svn update: 48945 (latest:48959)
authorYoumin Ha <youmin.ha@samsung.com>
Tue, 18 May 2010 07:21:43 +0000 (16:21 +0900)
committerYoumin Ha <youmin.ha@samsung.com>
Tue, 18 May 2010 07:21:43 +0000 (16:21 +0900)
460 files changed:
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
INSTALL [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
config/Makefile.am [new file with mode: 0644]
config/default/Makefile.am [new file with mode: 0644]
config/default/base.src [new file with mode: 0644]
config/default/icon.png [new file with mode: 0644]
config/default/profile.desktop [new file with mode: 0644]
config/illume/Makefile.am [new file with mode: 0644]
config/illume/base.src [new file with mode: 0644]
config/illume/icon.png [new file with mode: 0644]
config/illume/profile.desktop [new file with mode: 0644]
config/profile.src [new file with mode: 0644]
config/standard/Makefile.am [new file with mode: 0644]
config/standard/base.src [new file with mode: 0644]
config/standard/icon.png [new file with mode: 0644]
config/standard/profile.desktop [new file with mode: 0644]
configure.ac [new file with mode: 0644]
data/.cvsignore [new file with mode: 0644]
data/Makefile.am [new file with mode: 0644]
data/desktop/Makefile.am [new file with mode: 0644]
data/desktop/elementary.png [new file with mode: 0644]
data/desktop/elementary_config.desktop [new file with mode: 0644]
data/desktop/elementary_test.desktop [new file with mode: 0644]
data/edje_externals/Makefile.am [new file with mode: 0644]
data/edje_externals/ico_anchorblock.png [new file with mode: 0644]
data/edje_externals/ico_anchorview.png [new file with mode: 0644]
data/edje_externals/ico_bubble.png [new file with mode: 0644]
data/edje_externals/ico_button.png [new file with mode: 0644]
data/edje_externals/ico_check.png [new file with mode: 0644]
data/edje_externals/ico_clock.png [new file with mode: 0644]
data/edje_externals/ico_fileselector.png [new file with mode: 0644]
data/edje_externals/ico_fileselector_button.png [new file with mode: 0644]
data/edje_externals/ico_genlist.png [new file with mode: 0644]
data/edje_externals/ico_hoversel.png [new file with mode: 0644]
data/edje_externals/ico_list.png [new file with mode: 0755]
data/edje_externals/ico_map.png [new file with mode: 0644]
data/edje_externals/ico_notepad.png [new file with mode: 0644]
data/edje_externals/ico_photocam.png [new file with mode: 0644]
data/edje_externals/ico_progressbar.png [new file with mode: 0644]
data/edje_externals/ico_radio.png [new file with mode: 0644]
data/edje_externals/ico_scrolled_entry.png [new file with mode: 0644]
data/edje_externals/ico_slider.png [new file with mode: 0644]
data/edje_externals/ico_slideshow.png [new file with mode: 0644]
data/edje_externals/ico_spinner.png [new file with mode: 0644]
data/edje_externals/ico_thumb.png [new file with mode: 0644]
data/edje_externals/ico_toggle.png [new file with mode: 0644]
data/edje_externals/ico_toolbar.png [new file with mode: 0644]
data/edje_externals/icons.edc [new file with mode: 0644]
data/images/Makefile.am [new file with mode: 0644]
data/images/bubble.png [new file with mode: 0644]
data/images/bubble_sh.png [new file with mode: 0644]
data/images/icon_00.png [new file with mode: 0644]
data/images/icon_01.png [new file with mode: 0644]
data/images/icon_02.png [new file with mode: 0644]
data/images/icon_03.png [new file with mode: 0644]
data/images/icon_04.png [new file with mode: 0644]
data/images/icon_05.png [new file with mode: 0644]
data/images/icon_06.png [new file with mode: 0644]
data/images/icon_07.png [new file with mode: 0644]
data/images/icon_08.png [new file with mode: 0644]
data/images/icon_09.png [new file with mode: 0644]
data/images/icon_10.png [new file with mode: 0644]
data/images/icon_11.png [new file with mode: 0644]
data/images/icon_12.png [new file with mode: 0644]
data/images/icon_13.png [new file with mode: 0644]
data/images/icon_14.png [new file with mode: 0644]
data/images/icon_15.png [new file with mode: 0644]
data/images/icon_16.png [new file with mode: 0644]
data/images/icon_17.png [new file with mode: 0644]
data/images/icon_18.png [new file with mode: 0644]
data/images/icon_19.png [new file with mode: 0644]
data/images/icon_20.png [new file with mode: 0644]
data/images/icon_21.png [new file with mode: 0644]
data/images/icon_22.png [new file with mode: 0644]
data/images/icon_23.png [new file with mode: 0644]
data/images/logo.png [new file with mode: 0644]
data/images/logo_small.png [new file with mode: 0644]
data/images/panel_01.jpg [new file with mode: 0644]
data/images/parking.png [new file with mode: 0644]
data/images/plant_01.jpg [new file with mode: 0644]
data/images/rock_01.jpg [new file with mode: 0644]
data/images/rock_02.jpg [new file with mode: 0644]
data/images/sky_01.jpg [new file with mode: 0644]
data/images/sky_02.jpg [new file with mode: 0644]
data/images/sky_03.jpg [new file with mode: 0644]
data/images/sky_04.jpg [new file with mode: 0644]
data/images/wood_01.jpg [new file with mode: 0644]
data/objects/Makefile.am [new file with mode: 0644]
data/objects/clo.png [new file with mode: 0644]
data/objects/cross.png [new file with mode: 0644]
data/objects/multip.edc [new file with mode: 0644]
data/objects/over.png [new file with mode: 0644]
data/objects/sky.jpg [new file with mode: 0644]
data/objects/test.edc [new file with mode: 0644]
data/objects/under.png [new file with mode: 0644]
data/themes/Makefile.am [new file with mode: 0644]
data/themes/arrow_down.png [new file with mode: 0644]
data/themes/arrow_down.xcf.gz [new file with mode: 0644]
data/themes/arrow_right.png [new file with mode: 0644]
data/themes/arrow_up.png [new file with mode: 0644]
data/themes/arrow_up.xcf.gz [new file with mode: 0644]
data/themes/bt_base1.png [new file with mode: 0644]
data/themes/bt_base2.png [new file with mode: 0644]
data/themes/bt_bases.png [new file with mode: 0644]
data/themes/bt_basew.png [new file with mode: 0644]
data/themes/bt_dis_base.png [new file with mode: 0644]
data/themes/bt_dis_hilight.png [new file with mode: 0644]
data/themes/bt_dis_shine.png [new file with mode: 0644]
data/themes/bt_glow.png [new file with mode: 0644]
data/themes/bt_hilight.png [new file with mode: 0644]
data/themes/bt_hilightw.png [new file with mode: 0644]
data/themes/bt_shine.png [new file with mode: 0644]
data/themes/bt_sm_base1.png [new file with mode: 0644]
data/themes/bt_sm_base2.png [new file with mode: 0644]
data/themes/bt_sm_hilight.png [new file with mode: 0644]
data/themes/bt_sm_shine.png [new file with mode: 0644]
data/themes/bt_spinner_down.png [new file with mode: 0644]
data/themes/bt_spinner_hilight.png [new file with mode: 0644]
data/themes/bt_spinner_up.png [new file with mode: 0644]
data/themes/bubble.png [new file with mode: 0644]
data/themes/bubble_1.png [new file with mode: 0644]
data/themes/bubble_2.png [new file with mode: 0644]
data/themes/bubble_3.png [new file with mode: 0644]
data/themes/bubble_4.png [new file with mode: 0644]
data/themes/bubble_shine.png [new file with mode: 0644]
data/themes/bubble_shine3.png [new file with mode: 0644]
data/themes/bubble_shine4.png [new file with mode: 0644]
data/themes/busy-1.png [new file with mode: 0644]
data/themes/busy-2.png [new file with mode: 0644]
data/themes/busy-3.png [new file with mode: 0644]
data/themes/busy-4.png [new file with mode: 0644]
data/themes/busy-5.png [new file with mode: 0644]
data/themes/busy-6.png [new file with mode: 0644]
data/themes/busy-7.png [new file with mode: 0644]
data/themes/busy-8.png [new file with mode: 0644]
data/themes/busy-9.png [new file with mode: 0644]
data/themes/check.png [new file with mode: 0644]
data/themes/check2.png [new file with mode: 0644]
data/themes/check_base.png [new file with mode: 0644]
data/themes/cur_box.png [new file with mode: 0644]
data/themes/cur_glow.png [new file with mode: 0644]
data/themes/cur_hi.png [new file with mode: 0644]
data/themes/cur_shad.png [new file with mode: 0644]
data/themes/cur_shine.png [new file with mode: 0644]
data/themes/default.edc [new file with mode: 0644]
data/themes/dia_botshad.png [new file with mode: 0644]
data/themes/dia_grad.png [new file with mode: 0644]
data/themes/dia_topshad.png [new file with mode: 0644]
data/themes/down.png [new file with mode: 0644]
data/themes/emo-angry-shout.png [new file with mode: 0644]
data/themes/emo-angry.png [new file with mode: 0644]
data/themes/emo-crazy-laugh.png [new file with mode: 0644]
data/themes/emo-evil-laugh.png [new file with mode: 0644]
data/themes/emo-evil.png [new file with mode: 0644]
data/themes/emo-goggle-smile.png [new file with mode: 0644]
data/themes/emo-grumpy-smile.png [new file with mode: 0644]
data/themes/emo-grumpy.png [new file with mode: 0644]
data/themes/emo-guilty-smile.png [new file with mode: 0644]
data/themes/emo-guilty.png [new file with mode: 0644]
data/themes/emo-haha.png [new file with mode: 0644]
data/themes/emo-half-smile.png [new file with mode: 0644]
data/themes/emo-happy-panting.png [new file with mode: 0644]
data/themes/emo-happy.png [new file with mode: 0644]
data/themes/emo-indifferent.png [new file with mode: 0644]
data/themes/emo-kiss.png [new file with mode: 0644]
data/themes/emo-knowing-grin.png [new file with mode: 0644]
data/themes/emo-laugh.png [new file with mode: 0644]
data/themes/emo-little-bit-sorry.png [new file with mode: 0644]
data/themes/emo-love-lots.png [new file with mode: 0644]
data/themes/emo-love.png [new file with mode: 0644]
data/themes/emo-minimal-smile.png [new file with mode: 0644]
data/themes/emo-not-happy.png [new file with mode: 0644]
data/themes/emo-not-impressed.png [new file with mode: 0644]
data/themes/emo-omg.png [new file with mode: 0644]
data/themes/emo-opensmile.png [new file with mode: 0644]
data/themes/emo-smile.png [new file with mode: 0644]
data/themes/emo-sorry.png [new file with mode: 0644]
data/themes/emo-squint-laugh.png [new file with mode: 0644]
data/themes/emo-surprised.png [new file with mode: 0644]
data/themes/emo-suspicious.png [new file with mode: 0644]
data/themes/emo-tongue-dangling.png [new file with mode: 0644]
data/themes/emo-tongue-poke.png [new file with mode: 0644]
data/themes/emo-uh.png [new file with mode: 0644]
data/themes/emo-unhappy.png [new file with mode: 0644]
data/themes/emo-very-sorry.png [new file with mode: 0644]
data/themes/emo-what.png [new file with mode: 0644]
data/themes/emo-wink.png [new file with mode: 0644]
data/themes/emo-worried.png [new file with mode: 0644]
data/themes/emo-wtf.png [new file with mode: 0644]
data/themes/flip.xcf.gz [new file with mode: 0644]
data/themes/flip_0b.png [new file with mode: 0644]
data/themes/flip_0t.png [new file with mode: 0644]
data/themes/flip_1b.png [new file with mode: 0644]
data/themes/flip_1t.png [new file with mode: 0644]
data/themes/flip_2b.png [new file with mode: 0644]
data/themes/flip_2t.png [new file with mode: 0644]
data/themes/flip_3b.png [new file with mode: 0644]
data/themes/flip_3t.png [new file with mode: 0644]
data/themes/flip_4b.png [new file with mode: 0644]
data/themes/flip_4t.png [new file with mode: 0644]
data/themes/flip_5b.png [new file with mode: 0644]
data/themes/flip_5t.png [new file with mode: 0644]
data/themes/flip_6b.png [new file with mode: 0644]
data/themes/flip_6t.png [new file with mode: 0644]
data/themes/flip_7b.png [new file with mode: 0644]
data/themes/flip_7t.png [new file with mode: 0644]
data/themes/flip_8b.png [new file with mode: 0644]
data/themes/flip_8t.png [new file with mode: 0644]
data/themes/flip_9b.png [new file with mode: 0644]
data/themes/flip_9t.png [new file with mode: 0644]
data/themes/flip_amb.png [new file with mode: 0644]
data/themes/flip_amt.png [new file with mode: 0644]
data/themes/flip_base.png [new file with mode: 0644]
data/themes/flip_base_shad.png [new file with mode: 0644]
data/themes/flip_pmb.png [new file with mode: 0644]
data/themes/flip_pmt.png [new file with mode: 0644]
data/themes/flip_shad.png [new file with mode: 0644]
data/themes/frame_1.png [new file with mode: 0644]
data/themes/frame_2.png [new file with mode: 0644]
data/themes/head.png [new file with mode: 0644]
data/themes/hoversel_entry_bg.png [new file with mode: 0644]
data/themes/icon_apps.png [new file with mode: 0644]
data/themes/icon_arrow_down.png [new file with mode: 0644]
data/themes/icon_arrow_left.png [new file with mode: 0644]
data/themes/icon_arrow_right.png [new file with mode: 0644]
data/themes/icon_arrow_up.png [new file with mode: 0644]
data/themes/icon_chat.png [new file with mode: 0644]
data/themes/icon_clock.png [new file with mode: 0644]
data/themes/icon_close.png [new file with mode: 0644]
data/themes/icon_delete.png [new file with mode: 0644]
data/themes/icon_edit.png [new file with mode: 0644]
data/themes/icon_file.png [new file with mode: 0644]
data/themes/icon_folder.png [new file with mode: 0644]
data/themes/icon_home.png [new file with mode: 0644]
data/themes/icon_left_arrow.png [new file with mode: 0644]
data/themes/icon_refresh.png [new file with mode: 0644]
data/themes/icon_right_arrow.png [new file with mode: 0644]
data/themes/ilist_1.png [new file with mode: 0644]
data/themes/ilist_2.png [new file with mode: 0644]
data/themes/ilist_item_shadow.png [new file with mode: 0644]
data/themes/leftright.png [new file with mode: 0644]
data/themes/outdent-bottom.png [new file with mode: 0644]
data/themes/outdent-top.png [new file with mode: 0644]
data/themes/radio.png [new file with mode: 0644]
data/themes/radio2.png [new file with mode: 0644]
data/themes/radio_base.png [new file with mode: 0644]
data/themes/sb_runnerh.png [new file with mode: 0644]
data/themes/sb_runnerv.png [new file with mode: 0644]
data/themes/separator_h.png [new file with mode: 0644]
data/themes/separator_v.png [new file with mode: 0644]
data/themes/shad_circ.png [new file with mode: 0644]
data/themes/shelf_inset.png [new file with mode: 0644]
data/themes/sl_bg.png [new file with mode: 0644]
data/themes/sl_bg_over.png [new file with mode: 0644]
data/themes/sl_bt2_0_0.png [new file with mode: 0644]
data/themes/sl_bt2_0_1.png [new file with mode: 0644]
data/themes/sl_bt2_0_2.png [new file with mode: 0644]
data/themes/sl_bt2_1.png [new file with mode: 0644]
data/themes/sl_bt2_2.png [new file with mode: 0644]
data/themes/sl_bt_0.png [new file with mode: 0644]
data/themes/sl_bt_1.png [new file with mode: 0644]
data/themes/sl_bt_2.png [new file with mode: 0644]
data/themes/sl_units.png [new file with mode: 0644]
data/themes/slv_bg.png [new file with mode: 0644]
data/themes/slv_bg_over.png [new file with mode: 0644]
data/themes/slv_units.png [new file with mode: 0644]
data/themes/sp_bt_l.png [new file with mode: 0644]
data/themes/sp_bt_r.png [new file with mode: 0644]
data/themes/tog_base.png [new file with mode: 0644]
data/themes/tog_dis_base.png [new file with mode: 0644]
data/themes/toolbar_sel.png [new file with mode: 0644]
data/themes/toolbar_separator_v.png [new file with mode: 0644]
data/themes/up.png [new file with mode: 0644]
data/themes/updown.png [new file with mode: 0644]
debian/SVN_REV [new file with mode: 0644]
debian/_original/changelog [new file with mode: 0644]
debian/_original/compat [new file with mode: 0644]
debian/_original/control [new file with mode: 0644]
debian/_original/copyright [new file with mode: 0644]
debian/_original/libelm-bin.install [new file with mode: 0644]
debian/_original/libelm-dev.install [new file with mode: 0644]
debian/_original/libelm-svn-01.install [new file with mode: 0644]
debian/_original/rules [new file with mode: 0755]
doc/.cvsignore [new file with mode: 0644]
doc/Doxyfile [new file with mode: 0644]
doc/Makefile.am [new file with mode: 0644]
doc/e.css [new file with mode: 0644]
doc/elementary.dox.in [new file with mode: 0644]
doc/foot.html [new file with mode: 0644]
doc/head.html [new file with mode: 0644]
doc/img/edoxy.css [new file with mode: 0644]
doc/img/elementary.png [new file with mode: 0644]
doc/img/foot_bg.png [new file with mode: 0644]
doc/img/head_bg.png [new file with mode: 0644]
doc/img/header_menu_background.png [new file with mode: 0644]
doc/img/header_menu_background_last.png [new file with mode: 0644]
doc/img/header_menu_current_background.png [new file with mode: 0644]
doc/img/header_menu_unselected_background.png [new file with mode: 0644]
doc/img/logo.png [new file with mode: 0644]
elementary.pc.in [new file with mode: 0644]
elementary.spec.in [new file with mode: 0644]
m4/ac_attribute.m4 [new file with mode: 0644]
m4/efl_doxygen.m4 [new file with mode: 0644]
src/.cvsignore [new file with mode: 0644]
src/Makefile.am [new file with mode: 0644]
src/bin/.cvsignore [new file with mode: 0644]
src/bin/Makefile.am [new file with mode: 0644]
src/bin/config.c [new file with mode: 0644]
src/bin/quicklaunch.c [new file with mode: 0644]
src/bin/run.c [new file with mode: 0644]
src/bin/test.c [new file with mode: 0644]
src/bin/test_anchorblock.c [new file with mode: 0644]
src/bin/test_anchorview.c [new file with mode: 0644]
src/bin/test_anim.c [new file with mode: 0644]
src/bin/test_bg.c [new file with mode: 0644]
src/bin/test_box.c [new file with mode: 0644]
src/bin/test_button.c [new file with mode: 0644]
src/bin/test_carousel.c [new file with mode: 0644]
src/bin/test_check.c [new file with mode: 0644]
src/bin/test_clock.c [new file with mode: 0644]
src/bin/test_conform.c [new file with mode: 0644]
src/bin/test_entry.c [new file with mode: 0644]
src/bin/test_fileselector.c [new file with mode: 0644]
src/bin/test_fileselector_button.c [new file with mode: 0644]
src/bin/test_flip.c [new file with mode: 0644]
src/bin/test_floating.c [new file with mode: 0644]
src/bin/test_genlist.c [new file with mode: 0644]
src/bin/test_grid.c [new file with mode: 0644]
src/bin/test_hover.c [new file with mode: 0644]
src/bin/test_hoversel.c [new file with mode: 0644]
src/bin/test_icon.c [new file with mode: 0644]
src/bin/test_icon_desktops.c [new file with mode: 0644]
src/bin/test_index.c [new file with mode: 0644]
src/bin/test_inwin.c [new file with mode: 0644]
src/bin/test_label.c [new file with mode: 0644]
src/bin/test_launcher.c [new file with mode: 0644]
src/bin/test_layout.c [new file with mode: 0644]
src/bin/test_list.c [new file with mode: 0644]
src/bin/test_map.c [new file with mode: 0644]
src/bin/test_menu.c [new file with mode: 0644]
src/bin/test_multi.c [new file with mode: 0644]
src/bin/test_notepad.c [new file with mode: 0644]
src/bin/test_notify.c [new file with mode: 0644]
src/bin/test_pager.c [new file with mode: 0644]
src/bin/test_panel.c [new file with mode: 0644]
src/bin/test_photo.c [new file with mode: 0644]
src/bin/test_photocam.c [new file with mode: 0644]
src/bin/test_progressbar.c [new file with mode: 0644]
src/bin/test_radio.c [new file with mode: 0644]
src/bin/test_scaling.c [new file with mode: 0644]
src/bin/test_scroller.c [new file with mode: 0644]
src/bin/test_separator.c [new file with mode: 0644]
src/bin/test_slider.c [new file with mode: 0644]
src/bin/test_slideshow.c [new file with mode: 0644]
src/bin/test_spinner.c [new file with mode: 0644]
src/bin/test_table.c [new file with mode: 0644]
src/bin/test_thumb.c [new file with mode: 0644]
src/bin/test_toggle.c [new file with mode: 0644]
src/bin/test_toolbar.c [new file with mode: 0644]
src/bin/test_weather.c [new file with mode: 0644]
src/bin/test_win_state.c [new file with mode: 0644]
src/edje_externals/Makefile.am [new file with mode: 0644]
src/edje_externals/elm.c [new file with mode: 0644]
src/edje_externals/elm_anchorblock.c [new file with mode: 0644]
src/edje_externals/elm_anchorview.c [new file with mode: 0644]
src/edje_externals/elm_bubble.c [new file with mode: 0644]
src/edje_externals/elm_button.c [new file with mode: 0644]
src/edje_externals/elm_check.c [new file with mode: 0644]
src/edje_externals/elm_clock.c [new file with mode: 0644]
src/edje_externals/elm_fileselector.c [new file with mode: 0644]
src/edje_externals/elm_fileselector_button.c [new file with mode: 0644]
src/edje_externals/elm_genlist.c [new file with mode: 0644]
src/edje_externals/elm_hoversel.c [new file with mode: 0644]
src/edje_externals/elm_list.c [new file with mode: 0644]
src/edje_externals/elm_map.c [new file with mode: 0644]
src/edje_externals/elm_notepad.c [new file with mode: 0644]
src/edje_externals/elm_photocam.c [new file with mode: 0644]
src/edje_externals/elm_progressbar.c [new file with mode: 0644]
src/edje_externals/elm_radio.c [new file with mode: 0644]
src/edje_externals/elm_scrolled_entry.c [new file with mode: 0644]
src/edje_externals/elm_slider.c [new file with mode: 0644]
src/edje_externals/elm_slideshow.c [new file with mode: 0644]
src/edje_externals/elm_spinner.c [new file with mode: 0644]
src/edje_externals/elm_thumb.c [new file with mode: 0644]
src/edje_externals/elm_toggle.c [new file with mode: 0644]
src/edje_externals/elm_toolbar.c [new file with mode: 0644]
src/edje_externals/modules.inc [new file with mode: 0644]
src/edje_externals/private.h [new file with mode: 0644]
src/lib/Elementary.h.in [new file with mode: 0644]
src/lib/Makefile.am [new file with mode: 0644]
src/lib/elc_anchorblock.c [new file with mode: 0644]
src/lib/elc_anchorview.c [new file with mode: 0644]
src/lib/elc_fileselector.c [new file with mode: 0644]
src/lib/elc_fileselector_button.c [new file with mode: 0644]
src/lib/elc_hoversel.c [new file with mode: 0644]
src/lib/elc_notepad.c [new file with mode: 0644]
src/lib/elc_scrolled_entry.c [new file with mode: 0644]
src/lib/elm_bg.c [new file with mode: 0644]
src/lib/elm_box.c [new file with mode: 0644]
src/lib/elm_bubble.c [new file with mode: 0644]
src/lib/elm_button.c [new file with mode: 0644]
src/lib/elm_carousel.c [new file with mode: 0644]
src/lib/elm_check.c [new file with mode: 0644]
src/lib/elm_clock.c [new file with mode: 0644]
src/lib/elm_config.c [new file with mode: 0644]
src/lib/elm_conform.c [new file with mode: 0644]
src/lib/elm_entry.c [new file with mode: 0644]
src/lib/elm_flip.c [new file with mode: 0644]
src/lib/elm_frame.c [new file with mode: 0644]
src/lib/elm_genlist.c [new file with mode: 0644]
src/lib/elm_hover.c [new file with mode: 0644]
src/lib/elm_icon.c [new file with mode: 0644]
src/lib/elm_image.c [new file with mode: 0644]
src/lib/elm_index.c [new file with mode: 0644]
src/lib/elm_label.c [new file with mode: 0644]
src/lib/elm_layout.c [new file with mode: 0644]
src/lib/elm_list.c [new file with mode: 0644]
src/lib/elm_main.c [new file with mode: 0644]
src/lib/elm_map.c [new file with mode: 0644]
src/lib/elm_mapbuf.c [new file with mode: 0644]
src/lib/elm_menu.c [new file with mode: 0644]
src/lib/elm_module.c [new file with mode: 0644]
src/lib/elm_notify.c [new file with mode: 0644]
src/lib/elm_pager.c [new file with mode: 0644]
src/lib/elm_panel.c [new file with mode: 0644]
src/lib/elm_photo.c [new file with mode: 0644]
src/lib/elm_photocam.c [new file with mode: 0644]
src/lib/elm_priv.h [new file with mode: 0644]
src/lib/elm_progressbar.c [new file with mode: 0644]
src/lib/elm_radio.c [new file with mode: 0644]
src/lib/elm_scrolled_grid.c [new file with mode: 0644]
src/lib/elm_scroller.c [new file with mode: 0644]
src/lib/elm_separator.c [new file with mode: 0644]
src/lib/elm_slider.c [new file with mode: 0644]
src/lib/elm_slideshow.c [new file with mode: 0644]
src/lib/elm_spinner.c [new file with mode: 0644]
src/lib/elm_table.c [new file with mode: 0644]
src/lib/elm_theme.c [new file with mode: 0644]
src/lib/elm_thumb.c [new file with mode: 0644]
src/lib/elm_toggle.c [new file with mode: 0644]
src/lib/elm_toolbar.c [new file with mode: 0644]
src/lib/elm_widget.c [new file with mode: 0644]
src/lib/elm_win.c [new file with mode: 0644]
src/lib/els_box.c [new file with mode: 0644]
src/lib/els_box.h [new file with mode: 0644]
src/lib/els_icon.c [new file with mode: 0644]
src/lib/els_icon.h [new file with mode: 0644]
src/lib/els_pan.c [new file with mode: 0644]
src/lib/els_pan.h [new file with mode: 0644]
src/lib/els_scroller.c [new file with mode: 0644]
src/lib/els_scroller.h [new file with mode: 0644]
src/modules/Makefile.am [new file with mode: 0644]
src/modules/test_entry/Makefile.am [new file with mode: 0644]
src/modules/test_entry/mod.c [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..c99bb2b
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,13 @@
+The Rasterman (Carsten Haitzler) <raster@rasterman.com>
+Gustavo Sverzut Barbieri <barbieri@profusion.mobi>
+Cedric Bail <cedric.bail@free.fr>
+Vincent Torri <vtorri@univ-evry.fr>
+Daniel Kolesa <quaker66@gmail.com>
+Jaime Thomas <avi.thomas@gmail.com>
+Swisscom - http://www.swisscom.ch/
+Christopher Michael <devilhorns@devilhorns.us>
+Marco Trevisan (Treviño) <mail@3v1n0.net>
+Michael Bouchaud <michael.bouchaud@gmail.com>
+Jonathan Atton (Watchwolf) <jonathan.atton@gmail.com>
+Brian Wang <brian.wang.0721@gmail.com>
+Mike Blumenkrantz (zmike) <mike@zentific.com>
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..cf546d2
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,519 @@
+                 GNU LESSER GENERAL PUBLIC LICENSE
+                      Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+                 GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent modules,
+and to copy and distribute the resulting executable under terms of your
+choice, provided that you also meet, for each linked independent module,
+the terms and conditions of the license of that module. An independent
+module is a module which is not derived from or based on this library.
+If you modify this library, you may extend this exception to your version
+of the library, but you are not obliged to do so. If you do not wish to
+do so, delete this exception statement from your version.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                           NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..7c9d317
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,14 @@
+COMPILING and INSTALLING:
+
+If you got a official release tar archive do:
+    ./configure
+    
+( otherwise if you got this from enlightenment cvs do: ./autogen.sh )
+    
+Then to compile:
+    make
+
+To install (run this as root, or the user who handles installs):
+    make install
+
+NOTE: You MUST make install Elementary for it to run properly.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..d7a58bd
--- /dev/null
@@ -0,0 +1,22 @@
+SUBDIRS = src data config doc
+
+ACLOCAL_AMFLAGS = -I m4
+
+MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess \
+                       config.h.in config.sub configure install-sh \
+                      ltconfig ltmain.sh missing mkinstalldirs \
+                      stamp-h.in acconfig.h depcomp
+
+EXTRA_DIST = README AUTHORS COPYING autogen.sh elementary.pc.in elementary.spec elementary.spec.in
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = elementary.pc
+
+installed_headersdir = $(prefix)/include/elementary
+installed_headers_DATA = elementary_config.h
+
+.PHONY: doc
+
+doc:
+       @echo "entering doc/"
+       $(MAKE) -C doc doc
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..3de8538
--- /dev/null
+++ b/README
@@ -0,0 +1,3 @@
+Elementary - a basic widget set that is easy to use based on EFL for mobile
+touch-screen devices.
+
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..995ff2f
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+rm -rf autom4te.cache
+rm -f aclocal.m4 ltmain.sh
+
+touch README
+
+echo "Running aclocal..." ; aclocal $ACLOCAL_FLAGS -I m4 || 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/config/Makefile.am b/config/Makefile.am
new file mode 100644 (file)
index 0000000..cf52133
--- /dev/null
@@ -0,0 +1,19 @@
+MAINTAINERCLEANFILES = Makefile.in
+SUBDIRS = default standard illume
+
+EET_EET = @eet_eet@
+
+EXTRA_DIST = profile.src
+
+filesdir = $(datadir)/elementary/config
+
+files_DATA = profile.cfg
+
+%.cfg: %.src
+       $(EET_EET) -i \
+       $(top_builddir)/config/$@ config \
+       $< 0
+
+clean-local:
+       rm -rf *.cfg *~
+                                
diff --git a/config/default/Makefile.am b/config/default/Makefile.am
new file mode 100644 (file)
index 0000000..ba2bc96
--- /dev/null
@@ -0,0 +1,23 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+EET_EET = @eet_eet@
+
+EXTRA_DIST = \
+        profile.desktop \
+        icon.png \
+       base.src
+
+filesdir = $(datadir)/elementary/config/default
+files_DATA = \
+        profile.desktop \
+        icon.png \
+       base.cfg
+
+%.cfg: %.src
+       $(EET_EET) -e \
+       $(top_builddir)/config/default/$@ config \
+       $< 1
+
+clean-local:
+       rm -rf *.cfg *~
+       
diff --git a/config/default/base.src b/config/default/base.src
new file mode 100644 (file)
index 0000000..9cd5c20
--- /dev/null
@@ -0,0 +1,22 @@
+group "Elm_Config" struct {
+  value "engine" int: 0;
+  value "thumbscroll_enable" int: 1;
+  value "thumbscroll_threshhold" int: 24;
+  value "thumbscroll_momentum_threshhold" double: 100.0;
+  value "thumbscroll_friction" double: 1.0;
+  value "thumbscroll_bounce_friction" double: 0.5;
+  value "page_scroll_friction" double: 0.5;
+  value "bring_in_scroll_friction" double: 0.5;
+  value "zoom_friction" double: 0.5;
+  value "thumbscroll_bounce_enable" int: 1;
+  value "scale" double: 1.0;
+  value "bgpixmap" int: 0;
+  value "compositing" int: 1;
+  value "font_hinting" int: 2;
+  value "image_cache" int: 4096;
+  value "font_cache" int: 512;
+  value "finger_size" int: 40;
+  value "fps" double: 60.0;
+  value "theme" string: "default";
+  value "modules" string: "";
+}
diff --git a/config/default/icon.png b/config/default/icon.png
new file mode 100644 (file)
index 0000000..9c08ee2
Binary files /dev/null and b/config/default/icon.png differ
diff --git a/config/default/profile.desktop b/config/default/profile.desktop
new file mode 100644 (file)
index 0000000..e02dc43
--- /dev/null
@@ -0,0 +1,19 @@
+[Desktop Entry]
+Type=Link
+Name=Default
+Name[cs]=Výchozí
+Name[it]=Predefinito
+Name[hu]=Alapértelmezett
+Name[fr]=Prédéfini
+Name[el]=Προκαθορισμένο
+Name[eo]=Pravaloroj
+Name[zh_CN]=默认
+Icon=icon.png
+Comment=Select this to begin<br>the initial setup again.
+Comment[cs]=Vyberte pro znovuspuštění<br>tohoto průvodce.
+Comment[it]=Selezionare questo per<br>riprendere la<br>configurazione iniziale.
+Comment[hu]=Válaszd ezt az alap<br>beállítáok megismétléséhez.
+Comment[fr]=Sélectionnez ceci pour recommencer<br>la configuration initiale.
+Comment[el]=Επέλεξε αυτό για να <br>ξεκινήσεις την αρχική ρύθμιση ξανά.
+Comment[eo]=Elektu tion por restartigi<br>la pravalorizan agordon.
+Comment[zh_CN]=点击这里重新进行初始化设置主题。
diff --git a/config/illume/Makefile.am b/config/illume/Makefile.am
new file mode 100644 (file)
index 0000000..fa13056
--- /dev/null
@@ -0,0 +1,23 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+EET_EET = @eet_eet@
+
+EXTRA_DIST = \
+        profile.desktop \
+        icon.png \
+       base.src
+
+filesdir = $(datadir)/elementary/config/illume
+files_DATA = \
+        profile.desktop \
+        icon.png \
+       base.cfg
+
+%.cfg: %.src
+       $(EET_EET) -e \
+       $(top_builddir)/config/illume/$@ config \
+       $< 1
+
+clean-local:
+       rm -rf *.cfg *~
+       
diff --git a/config/illume/base.src b/config/illume/base.src
new file mode 100644 (file)
index 0000000..9cd5c20
--- /dev/null
@@ -0,0 +1,22 @@
+group "Elm_Config" struct {
+  value "engine" int: 0;
+  value "thumbscroll_enable" int: 1;
+  value "thumbscroll_threshhold" int: 24;
+  value "thumbscroll_momentum_threshhold" double: 100.0;
+  value "thumbscroll_friction" double: 1.0;
+  value "thumbscroll_bounce_friction" double: 0.5;
+  value "page_scroll_friction" double: 0.5;
+  value "bring_in_scroll_friction" double: 0.5;
+  value "zoom_friction" double: 0.5;
+  value "thumbscroll_bounce_enable" int: 1;
+  value "scale" double: 1.0;
+  value "bgpixmap" int: 0;
+  value "compositing" int: 1;
+  value "font_hinting" int: 2;
+  value "image_cache" int: 4096;
+  value "font_cache" int: 512;
+  value "finger_size" int: 40;
+  value "fps" double: 60.0;
+  value "theme" string: "default";
+  value "modules" string: "";
+}
diff --git a/config/illume/icon.png b/config/illume/icon.png
new file mode 100644 (file)
index 0000000..9e0ed3d
Binary files /dev/null and b/config/illume/icon.png differ
diff --git a/config/illume/profile.desktop b/config/illume/profile.desktop
new file mode 100644 (file)
index 0000000..34308f6
--- /dev/null
@@ -0,0 +1,16 @@
+[Desktop Entry]
+Type=Link
+Name=Illume
+Name[fr]=Illume
+Name[el]=Illume
+Name[eo]=Illume
+Name[zh_CN]=Illume
+Icon=icon.png
+Comment=Illume profile for<br>embedded systems like<br>phones and web<br>tablets with tiny<br>touchscreen displays.<br>Only use this if<br>you really have<br>such a device.
+Comment[cs]=Illume profil pro<br>přenosná zařízení<br>jako telefony<br>a webové tablety<br>s malými dotykovými displeji.<br>Použijte jen pokud<br>opravdu máte<br>takové zařízení.
+Comment[it]=Profilo Illume per<br>sistemi embedded come<br>cellulari e webpad<br>con piccoli display<br>touchscreen.<br>Usatelo solo se<br>avete realmente un<br>dispositivo simile.
+Comment[hu]=Illume profil <br>telefonokhoz, érintőképernyőkhöz.<br>Csak akkor használd ezt,<br>ha valóban ilyen eszközöd van.
+Comment[fr]=Profil Illume pour les systèmes<br>embarqués comme les téléphones<br>et tablettes internet pourvus<br>d'un petit écran tactile.<br>À n'utiliser que si<br>vous disposez réellement<br>d'un tel matériel.
+Comment[el]=Το προφίλ Illume είναι<br>για μικροσυσκευές όπως <br>κινητά τηλέφωνα ή internet<br>tablets με μικρές οθόνες αφής.<br>Επιλέξτε μόνο αν έχετε τέτοια<br>συσκευή.
+Comment[eo]=Profilo Illume por la<br>enkorpigitaj sistemoj<br>kiel la telefonoj kaj<br>ttt-tabletoj kun etaj<br>tuŝekranoj. Nur uzu<br>tiun se vi vere havas<br>tian aparaton.
+Comment[zh_CN]=为带有小型触屏的嵌入式系统如手机和上网本设计的 Illume 设置主题。
diff --git a/config/profile.src b/config/profile.src
new file mode 100644 (file)
index 0000000..331d858
--- /dev/null
@@ -0,0 +1 @@
+default
\ No newline at end of file
diff --git a/config/standard/Makefile.am b/config/standard/Makefile.am
new file mode 100644 (file)
index 0000000..88cae80
--- /dev/null
@@ -0,0 +1,23 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+EET_EET = @eet_eet@
+
+EXTRA_DIST = \
+        profile.desktop \
+        icon.png \
+       base.src
+
+filesdir = $(datadir)/elementary/config/standard
+files_DATA = \
+        profile.desktop \
+        icon.png \
+       base.cfg
+
+%.cfg: %.src
+       $(EET_EET) -e \
+       $(top_builddir)/config/standard/$@ config \
+       $< 1
+
+clean-local:
+       rm -rf *.cfg *~
+       
diff --git a/config/standard/base.src b/config/standard/base.src
new file mode 100644 (file)
index 0000000..4df5eda
--- /dev/null
@@ -0,0 +1,22 @@
+group "Elm_Config" struct {
+  value "engine" int: 0;
+  value "thumbscroll_enable" int: 1;
+  value "thumbscroll_threshhold" int: 4;
+  value "thumbscroll_momentum_threshhold" double: 100.0;
+  value "thumbscroll_friction" double: 1.0;
+  value "thumbscroll_bounce_friction" double: 0.5;
+  value "page_scroll_friction" double: 0.5;
+  value "bring_in_scroll_friction" double: 0.5;
+  value "zoom_friction" double: 0.5;
+  value "thumbscroll_bounce_enable" int: 1;
+  value "scale" double: 1.0;
+  value "bgpixmap" int: 0;
+  value "compositing" int: 1;
+  value "font_hinting" int: 2;
+  value "image_cache" int: 4096;
+  value "font_cache" int: 512;
+  value "finger_size" int: 5;
+  value "fps" double: 60.0;
+  value "theme" string: "default";
+  value "modules" string: "";
+}
diff --git a/config/standard/icon.png b/config/standard/icon.png
new file mode 100644 (file)
index 0000000..90b57af
Binary files /dev/null and b/config/standard/icon.png differ
diff --git a/config/standard/profile.desktop b/config/standard/profile.desktop
new file mode 100644 (file)
index 0000000..7c9ed30
--- /dev/null
@@ -0,0 +1,18 @@
+[Desktop Entry]
+Type=Link
+Name=Standard
+Name[cs]=Standartní
+Name[hu]=Általános
+Name[fr]=Standard
+Name[el]=Κανονικό
+Name[eo]=Kutima
+Name[zh_CN]=标准
+Icon=icon.png
+Comment=This is the standard<br>profile that is<br>universal for most<br>desktop and laptop<br>systems. Choose this<br>if you are not<br>sure what to choose.
+Comment[cs]=Toto je standartní<br>univerzální<br>profil pro většinu<br>stolních a přenosných<br>počítačů. Vyberte pokud<br>si nejste jisti<br>co vybrat.
+Comment[it]=Questo è il profilo<br>standard, universale<br>per la maggior<br>parte dei sistemi<br>desktop e portatili.<br>Scegliete questo se<br>non siete sicuri di<br>cosa scegliere.
+Comment[hu]=Ez az általános,<br>alap beállítás,<br>amely megfelelő a<br>legtöbb laptop és<br>asztali gép számára.
+Comment[fr]=C'est le profil standard<br>adapté à la quasi totalité<br>des systèmes de bureau<br>et ordinateurs portables.<br>Choisissez ce profil si<br>vous n'êtes pas sûr.
+Comment[el]=Αυτό είναι το κανονικό <br>προφίλ που είναι κοινό<br>για τα περισσότερα συστήματα. Επιλέξτε αυτό<br>αν δεν είστε σίγουροι για <br>την επιλογή σας.
+Comment[eo]=Tio estas la kutima profilo<br>taŭga por preskaŭ ĉiuj<br>oficejaj sistemoj kaj<br>porteblaj sistemoj.<br>Elektu ĝin se vi ne certas.
+Comment[zh_CN]=适用于大多数台式机和笔记本的设置主题,如果您不清楚如何选择则请使用这个。
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..26748a7
--- /dev/null
@@ -0,0 +1,478 @@
+# get rid of that stupid cache mechanism
+rm -f config.cache
+
+AC_INIT([elementary], [0.6.0.063], [enlightenment-devel@lists.sourceforge.net])
+release="ver-pre-svn-05"
+AC_PREREQ(2.52)
+AC_CONFIG_SRCDIR([configure.ac])
+AC_CONFIG_MACRO_DIR([m4])
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+
+AM_INIT_AUTOMAKE([1.6 dist-bzip2])
+AM_CONFIG_HEADER([elementary_config.h])
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+AC_C_BIGENDIAN
+AC_ISC_POSIX
+AC_PROG_CC
+AM_PROG_CC_STDC
+AC_HEADER_STDC
+AC_C_CONST
+AC_C___ATTRIBUTE__
+AC_FUNC_ALLOCA
+
+AC_LIBTOOL_WIN32_DLL
+define([AC_LIBTOOL_LANG_CXX_CONFIG], [:])dnl
+define([AC_LIBTOOL_LANG_F77_CONFIG], [:])dnl
+AC_PROG_LIBTOOL
+
+VMAJ=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $1);}'`
+VMIN=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $2);}'`
+VMIC=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $3);}'`
+SNAP=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $4);}'`
+version_info=`expr $VMAJ + $VMIN`":$VMIC:$VMIN"
+AC_SUBST(version_info)
+
+case "$host_os" in
+  mingw32ce* | cegcc*)
+    MODULE_ARCH="$host_os-$host_cpu"
+    ;;
+  *)
+    release_info="-release $release"
+    MODULE_ARCH="$host_os-$host_cpu-$release"
+    ;;
+esac
+AC_SUBST(release_info)
+AC_SUBST(MODULE_ARCH)
+AC_DEFINE_UNQUOTED(MODULE_ARCH, "$MODULE_ARCH", "Module architecture")
+
+EFL_SHARED_EXTENSION="${shrext_cmds}"
+AC_DEFINE_UNQUOTED(EFL_SHARED_EXTENSION, "${EFL_SHARED_EXTENSION}", "Shared extension")
+
+requirement_elm=""
+
+PKG_PROG_PKG_CONFIG
+
+# Check whether pkg-config supports Requires.private
+if $PKG_CONFIG --atleast-pkgconfig-version 0.22; then
+   pkgconfig_requires_private="Requires.private"
+else
+   pkgconfig_requires_private="Requires"
+fi
+AC_SUBST(pkgconfig_requires_private)
+
+lt_enable_auto_import=""
+ELM_UNIX_DEF="#undef"
+ELM_WIN32_DEF="#undef"
+ELM_WINCE_DEF="#undef"
+have_windows="no"
+case "$host_os" in
+   mingw32ce* | cegcc*)
+      PKG_CHECK_MODULES([EVIL], [evil])
+      AC_DEFINE(HAVE_EVIL, 1, [Set to 1 if evil package is installed.])
+      lt_enable_auto_import="-Wl,--enable-auto-import"
+      ELM_WINCE_DEF="#define"
+      have_windows="yes"
+dnl managed by evil
+      AC_DEFINE(HAVE_DLADDR)
+      requirement_elm="evil"
+      have_socket="no"
+    ;;
+   mingw*)
+      PKG_CHECK_MODULES([EVIL], [evil])
+      AC_DEFINE(HAVE_EVIL, 1, [Set to 1 if evil package is installed.])
+      lt_enable_auto_import="-Wl,--enable-auto-import"
+      ELM_WIN32_DEF="#define"
+      have_windows="yes"
+      requirement_elm="evil"
+      have_socket="no"
+      ;;
+   *solaris*)
+      ELM_UNIX_DEF="#define"
+      have_socket="yes"
+      AC_CHECK_LIB([socket], [connect], [], [have_socket="no"])
+      ;;
+   darwin*)
+      ELM_UNIX_DEF="#define"
+      have_socket="yes"
+      AC_CHECK_HEADERS([crt_externs.h])
+      AC_DEFINE([environ], [(*_NSGetEnviron())], [apple doesn't follow POSIX in this case.])
+      ;;
+   *)
+      ELM_UNIX_DEF="#define"
+      AC_CHECK_FUNCS(dlopen, res=yes, res=no)
+      if test "x$res" = "xyes"; then
+       AC_CHECK_FUNCS(dladdr, AC_DEFINE(HAVE_DLADDR))
+      else
+       AC_CHECK_LIB(dl, dlopen, res=yes, res=no)
+       if test "x$res" = "xyes"; then
+         AC_CHECK_LIB(dl, dladdr, AC_DEFINE(HAVE_DLADDR))
+         dlopen_libs=-ldl
+       else
+         AC_MSG_ERROR(Cannot find dlopen)
+       fi
+      fi
+      have_socket="yes"
+      ;;
+esac
+AM_CONDITIONAL([BUILD_RUN], [test "x$have_socket" = "xyes"])
+
+have_fork="no"
+AC_CHECK_FUNCS(fork, [
+  have_fork="yes"
+  AC_DEFINE(HAVE_FORK)
+])
+AM_CONDITIONAL([BUILD_QUICKLAUNCH], [test "x$have_fork" = "xyes"])
+
+AC_SUBST(dlopen_libs)
+AC_SUBST(lt_enable_auto_import)
+AC_SUBST(ELM_UNIX_DEF)
+AC_SUBST(ELM_WIN32_DEF)
+AC_SUBST(ELM_WINCE_DEF)
+
+AM_CONDITIONAL([ELEMENTARY_WINDOWS_BUILD], [test "x${have_windows}" = "xyes"])
+
+PKG_CHECK_MODULES([ELEMENTARY],
+   [
+    eina-0 >= 0.0.1
+    eet >= 1.2.3
+    evas >= 0.9.9
+    ecore >= 0.9.9
+    ecore-evas >= 0.9.9
+    ecore-file >= 0.9.9
+    edje >= 0.9.91
+   ]
+)
+
+AC_ARG_WITH(eet-eet,
+[  --with-eet-eet=PATH              specify a specific path to eet utility],
+[
+  v=$withval;
+  eet_eet=$v
+  echo "  Elementary eet explicitly set to "$eet_eet;
+],[
+  eet_eet=$(pkg-config --variable=prefix eet)/bin/eet
+])
+AC_SUBST(eet_eet)
+        
+requirement_elm="edje ecore-file ecore-evas ecore evas eet eina-0 ${requirement_elm}"
+
+have_elementary_x="no"
+want_elementary_x="auto"
+AC_ARG_ENABLE([ecore-x],
+   [AC_HELP_STRING([--disable-ecore-x], [disable ecore-x support. @<:@default=detect@:>@])],
+   [want_elementary_x=$enableval], [])
+
+if test "x$want_elementary_x" != "xno"; then
+   PKG_CHECK_MODULES([ELEMENTARY_X],
+      [ecore-x],
+      [
+       AC_DEFINE(HAVE_ELEMENTARY_X, 1, [X11 support for Elementary])
+       have_elementary_x="yes"
+       requirement_elm="ecore-x ${requirement_elm}"
+      ],
+      [have_elementary_x="no"]
+   )
+else
+    have_elementary_x="no"
+fi
+if test "x$want_elementary_x" = "xyes" -a "x$have_elementary_x" = "xno"; then
+    AC_MSG_ERROR([ecore-x support requested, but not found by pkg-config.])
+fi
+
+
+have_elementary_fb="no"
+want_elementary_fb="auto"
+AC_ARG_ENABLE([ecore-fb],
+   [AC_HELP_STRING([--disable-ecore-fb], [disable ecore-fb support. @<:@default=detect@:>@])],
+   [want_elementary_fb=$enableval], [])
+
+if test "x$want_elementary_fb" != "xno"; then
+   PKG_CHECK_MODULES([ELEMENTARY_FB],
+      [ecore-fb],
+      [
+       AC_DEFINE(HAVE_ELEMENTARY_FB, 1, [FB support for Elementary])
+       have_elementary_fb="yes"
+       requirement_elm="ecore-fb ${requirement_elm}"
+      ],
+      [have_elementary_fb="no"]
+   )
+else
+    have_elementary_fb="no"
+fi
+if test "x$want_elementary_fb" = "xyes" -a "x$have_elementary_fb" = "xno"; then
+    AC_MSG_ERROR([ecore-fb support requested, but not found by pkg-config.])
+fi
+
+have_elementary_sdl="no"
+want_elementary_sdl="auto"
+AC_ARG_ENABLE([ecore-sdl],
+   [AC_HELP_STRING([--disable-ecore-sdl], [disable ecore-sdl support. @<:@default=detect@:>@])],
+   [want_elementary_sdl=$enableval], [])
+
+if test "x$want_elementary_sdl" != "xno"; then
+   PKG_CHECK_MODULES([ELEMENTARY_SDL],
+      [ecore-sdl],
+      [
+       AC_DEFINE(HAVE_ELEMENTARY_SDL, 1, [SDL support for Elementary])
+       have_elementary_sdl="yes"
+       requirement_elm="ecore-sdl ${requirement_elm}"
+      ],
+      [have_elementary_sdl="no"]
+   )
+else
+    have_elementary_sdl="no"
+fi
+if test "x$want_elementary_sdl" = "xyes" -a "x$have_elementary_sdl" = "xno"; then
+    AC_MSG_ERROR([ecore-sdl support requested, but not found by pkg-config.])
+fi
+
+have_elementary_win32="no"
+want_elementary_win32="auto"
+AC_ARG_ENABLE([ecore-win32],
+   [AC_HELP_STRING([--disable-ecore-win32], [disable ecore-win32 support. @<:@default=detect@:>@])],
+   [want_elementary_win32=$enableval], [])
+
+if test "x$want_elementary_win32" != "xno"; then
+   PKG_CHECK_MODULES([ELEMENTARY_WIN32],
+      [ecore-win32],
+      [
+       AC_DEFINE(HAVE_ELEMENTARY_WIN32, 1, [Windows XP support for Elementary])
+       have_elementary_win32="yes"
+       requirement_elm="ecore-win32 ${requirement_elm}"
+      ],
+      [have_elementary_win32="no"]
+   )
+else
+    have_elementary_win32="no"
+fi
+if test "x$want_elementary_win32" = "xyes" -a "x$have_elementary_win32" = "xno"; then
+    AC_MSG_ERROR([ecore-win32 support requested, but not found by pkg-config.])
+fi
+
+have_elementary_wince="no"
+want_elementary_wince="auto"
+AC_ARG_ENABLE([ecore-wince],
+   [AC_HELP_STRING([--disable-ecore-wince], [disable ecore-wince support. @<:@default=detect@:>@])],
+   [want_elementary_wince=$enableval], [])
+
+if test "x$want_elementary_wince" != "xno"; then
+   PKG_CHECK_MODULES([ELEMENTARY_WINCE],
+      [ecore-wince],
+      [
+       AC_DEFINE(HAVE_ELEMENTARY_WINCE, 1, [Windows CE support for Elementary])
+       have_elementary_wince="yes"
+       requirement_elm="ecore-wince ${requirement_elm}"
+      ],
+      [have_elementary_wince="no"]
+   )
+else
+    have_elementary_wince="no"
+fi
+if test "x$want_elementary_wince" = "xyes" -a "x$have_elementary_wince" = "xno"; then
+    AC_MSG_ERROR([ecore-wince support requested, but not found by pkg-config.])
+fi
+
+ELM_EDBUS_DEF="#undef"
+have_elementary_edbus="no"
+want_elementary_edbus="auto"
+AC_ARG_ENABLE([edbus],
+   [AC_HELP_STRING([--disable-edbus], [disable edbus support. @<:@default=detect@:>@])],
+   [want_elementary_edbus=$enableval], [])
+
+if test "x$want_elementary_edbus" != "xno"; then
+    PKG_CHECK_MODULES([ELEMENTARY_EDBUS],
+       [
+        edbus
+        ehal
+       ],
+       [
+        AC_DEFINE(HAVE_ELEMENTARY_EDBUS, 1, [EDBus support for Elementary])
+        have_elementary_edbus="yes"
+        ELM_EDBUS_DEF="#define"
+        requirement_elm="ehal edbus ${requirement_elm}"
+       ],
+       [have_elementary_edbus="no"]
+    )
+else
+    have_elementary_edbus="no"
+fi
+if test "x$want_elementary_edbus" = "xyes" -a "x$have_elementary_edbus" = "xno"; then
+    AC_MSG_ERROR([E_DBus support requested, but no edbus/ehal found by pkg-config.])
+fi
+AC_SUBST(ELM_EDBUS_DEF)
+
+ELM_EFREET_DEF="#undef"
+have_elementary_efreet="no"
+want_elementary_efreet="auto"
+AC_ARG_ENABLE([efreet],
+   [AC_HELP_STRING([--disable-efreet], [disable efreet support. @<:@default=detect@:>@])],
+   [want_elementary_efreet=$enableval], [])
+
+if test "x$want_elementary_efreet" != "xno"; then
+    PKG_CHECK_MODULES([ELEMENTARY_EFREET],
+       [
+        efreet
+        efreet-mime
+        efreet-trash
+       ],
+       [
+        AC_DEFINE(HAVE_ELEMENTARY_EFREET, 1, [Efreet support for Elementary])
+        have_elementary_efreet="yes"
+        ELM_EFREET_DEF="#define"
+        requirement_elm="efreet efreet-mime efreet-trash ${requirement_elm}"
+       ],
+       [have_elementary_efreet="no"]
+    )
+else
+    have_elementary_efreet="no"
+fi
+if test "x$want_elementary_efreet" = "xyes" -a "x$have_elementary_efreet" = "xno"; then
+    AC_MSG_ERROR([Efreet support requested, but no efreet/efreet-mime/efreet-trash found by pkg-config.])
+fi
+AC_SUBST(ELM_EFREET_DEF)
+
+ELM_EWEATHER_DEF="#undef"
+have_elementary_eweather="no"
+want_elementary_eweather="auto"
+AC_ARG_ENABLE([eweather],
+   [AC_HELP_STRING([--disable-eweather], [disable eweather support. @<:@default=detect@:>@])],
+   [want_elementary_eweather=$enableval], [])
+
+if test "x$want_elementary_eweather" != "xno"; then
+    PKG_CHECK_MODULES([ELEMENTARY_EWEATHER],
+       [
+        eweather
+       ],
+       [
+        AC_DEFINE(HAVE_ELEMENTARY_EWEATHER, 1, [EWeather support for Elementary])
+        have_elementary_eweather="yes"
+        ELM_EWEATHER_DEF="#define"
+        requirement_elm="eweather ${requirement_elm}"
+       ],
+       [have_elementary_eweather="no"]
+    )
+else
+    have_elementary_eweather="no"
+fi
+if test "x$want_elementary_eweather" = "xyes" -a "x$have_elementary_eweather" = "xno"; then
+    AC_MSG_ERROR([Eweather support requested, but no eweather found by pkg-config.])
+fi
+AC_SUBST(ELM_EWEATHER_DEF)
+
+ELM_ETHUMB_DEF="#undef"
+have_elementary_ethumb="no"
+want_elementary_ethumb="auto"
+AC_ARG_ENABLE([ethumb],
+   [AC_HELP_STRING([--disable-ethumb], [disable ethumb support. @<:@default=detect@:>@])],
+   [want_elementary_ethumb=$enableval], [])
+
+if test "x$want_elementary_ethumb" != "xno"; then
+    PKG_CHECK_MODULES([ELEMENTARY_ETHUMB],
+       [
+        ethumb_client
+       ],
+       [
+        AC_DEFINE(HAVE_ELEMENTARY_ETHUMB, 1, [Ethumb support for Elementary])
+        have_elementary_ethumb="yes"
+        ELM_ETHUMB_DEF="#define"
+        requirement_elm="ethumb ${requirement_elm}"
+       ],
+       [have_elementary_ethumb="no"]
+    )
+else
+    have_elementary_ethumb="no"
+fi
+if test "x$want_elementary_ethumb" = "xyes" -a "x$have_elementary_ethumb" = "xno"; then
+    AC_MSG_ERROR([Ethumb support requested, but no ethumb found by pkg-config.])
+fi
+AC_SUBST(ELM_ETHUMB_DEF)
+
+ELM_ALLOCA_H_DEF="#undef"
+AC_CHECK_HEADER(alloca.h, [ELM_ALLOCA_H_DEF="#define"])
+AC_SUBST(ELM_ALLOCA_H_DEF)
+
+ELM_LIBINTL_H_DEF="#undef"
+AC_CHECK_HEADER(libintl.h, [ELM_LIBINTL_H_DEF="#define"])
+AC_SUBST(ELM_LIBINTL_H_DEF)
+
+AC_ARG_WITH(edje-cc,
+[  --with-edje-cc=PATH              specify a specific path to edje_cc],
+[
+  v=$withval;
+  edje_cc=$v
+  echo "  Elementary edje_cc explicitly set to "$edje_cc;
+],[
+  edje_cc=$(pkg-config --variable=prefix edje)/bin/edje_cc
+])
+AC_SUBST(edje_cc)
+
+my_libs="-lm"
+AC_SUBST(my_libs)
+AC_SUBST(requirement_elm)
+
+EFL_CHECK_DOXYGEN([build_doc="yes"], [build_doc="no"])
+
+AC_OUTPUT([
+Makefile
+elementary.spec
+elementary.pc
+doc/elementary.dox
+doc/Makefile
+src/Makefile
+src/lib/Makefile
+src/lib/Elementary.h
+src/bin/Makefile
+src/modules/Makefile
+src/modules/test_entry/Makefile
+src/edje_externals/Makefile
+data/Makefile
+data/themes/Makefile
+data/images/Makefile
+data/objects/Makefile
+data/desktop/Makefile
+data/edje_externals/Makefile
+config/Makefile
+config/default/Makefile
+config/standard/Makefile
+config/illume/Makefile
+])
+
+#####################################################################
+## Info
+
+echo
+echo
+echo
+echo "------------------------------------------------------------------------"
+echo "$PACKAGE $VERSION"
+echo "------------------------------------------------------------------------"
+echo
+echo "Configuration Options Summary:"
+echo
+echo "  Engines:"
+echo "    X11................: ${have_elementary_x}"
+echo "    Framebuffer........: ${have_elementary_fb}"
+echo "    SDL................: ${have_elementary_sdl}"
+echo "    Windows XP.........: ${have_elementary_win32}"
+echo "    Windows CE.........: ${have_elementary_wince}"
+echo
+echo "  Features:"
+echo "    EDBus..............: ${have_elementary_edbus}"
+echo "    EFreet.............: ${have_elementary_efreet}"
+echo "    EWeather...........: ${have_elementary_eweather}"
+echo "    Ethumb.............: ${have_elementary_ethumb}"
+echo
+echo "  edje_cc..............: ${edje_cc}"
+echo
+echo "Compilation............: make (or gmake)"
+echo "  CPPFLAGS.............: $CPPFLAGS"
+echo "  CFLAGS...............: $CFLAGS"
+echo "  LDFLAGS..............: $LDFLAGS"
+echo
+echo "Installation...........: make install (as root if needed, with 'su' or 'sudo')"
+echo "  prefix...............: $prefix"
+echo
diff --git a/data/.cvsignore b/data/.cvsignore
new file mode 100644 (file)
index 0000000..d880450
--- /dev/null
@@ -0,0 +1,3 @@
+Makefile
+Makefile.in
+default.edj
diff --git a/data/Makefile.am b/data/Makefile.am
new file mode 100644 (file)
index 0000000..17807ed
--- /dev/null
@@ -0,0 +1,3 @@
+AUTOMAKE_OPTIONS     = 1.4 foreign
+MAINTAINERCLEANFILES = Makefile.in
+SUBDIRS              = themes images objects desktop edje_externals
diff --git a/data/desktop/Makefile.am b/data/desktop/Makefile.am
new file mode 100644 (file)
index 0000000..14e5d0f
--- /dev/null
@@ -0,0 +1,10 @@
+4AUTOMAKE_OPTIONS     = 1.4 foreign
+MAINTAINERCLEANFILES = Makefile.in
+
+desktopdir = $(datadir)/applications
+desktop_DATA = elementary_test.desktop elementary_config.desktop
+
+icondir = $(datadir)/icons
+icon_DATA = elementary.png
+
+EXTRA_DIST = $(desktop_DATA) $(icon_DATA)
diff --git a/data/desktop/elementary.png b/data/desktop/elementary.png
new file mode 100644 (file)
index 0000000..7975489
Binary files /dev/null and b/data/desktop/elementary.png differ
diff --git a/data/desktop/elementary_config.desktop b/data/desktop/elementary_config.desktop
new file mode 100644 (file)
index 0000000..4ba1e96
--- /dev/null
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Name=Elementary Configuration
+Comment=Elementary Configuration
+Comment[fr]=Configuration pour Elementary
+Comment[it]=Configurazione di Elementary
+Exec=elementary_config
+Icon=elementary
+Terminal=false
+Type=Application
+Categories=Application;Utility;
diff --git a/data/desktop/elementary_test.desktop b/data/desktop/elementary_test.desktop
new file mode 100644 (file)
index 0000000..ad32d37
--- /dev/null
@@ -0,0 +1,12 @@
+[Desktop Entry]
+Encoding=UTF-8
+Name=Elementary Test
+Comment=Elementary Test Application
+Comment[cs]=Testovací aplikace Elementary
+Comment[fr]=Programme de tests pour Elementary
+Comment[it]=Applicazione di test per Elementary
+Exec=elementary_test
+Icon=elementary
+Terminal=false
+Type=Application
+Categories=Application;Utility;
diff --git a/data/edje_externals/Makefile.am b/data/edje_externals/Makefile.am
new file mode 100644 (file)
index 0000000..d278cbf
--- /dev/null
@@ -0,0 +1,42 @@
+AUTOMAKE_OPTIONS     = 1.4 foreign
+MAINTAINERCLEANFILES = Makefile.in
+
+EDJE_CC = @edje_cc@
+EDJE_FLAGS = -v -id $(top_srcdir)/data/edje_externals -fd $(top_srcdir)/data/edje_externals
+
+filesdir = $(datadir)/elementary/edje_externals
+files_DATA = icons.edj
+
+EXTRA_DIST = \
+icons.edc \
+ico_anchorblock.png \
+ico_anchorview.png \
+ico_bubble.png \
+ico_button.png \
+ico_check.png \
+ico_clock.png \
+ico_fileselector.png \
+ico_fileselector_button.png \
+ico_genlist.png \
+ico_hoversel.png \
+ico_list.png \
+ico_map.png \
+ico_notepad.png \
+ico_photocam.png \
+ico_progressbar.png \
+ico_radio.png \
+ico_scrolled_entry.png \
+ico_slider.png \
+ico_slideshow.png \
+ico_spinner.png \
+ico_thumb.png \
+ico_toggle.png \
+ico_toolbar.png
+
+icons.edj: Makefile $(EXTRA_DIST)
+       $(EDJE_CC) $(EDJE_FLAGS) \
+       $(top_srcdir)/data/edje_externals/icons.edc \
+       $(top_builddir)/data/edje_externals/icons.edj
+
+clean-local:
+       rm -f *.edj
diff --git a/data/edje_externals/ico_anchorblock.png b/data/edje_externals/ico_anchorblock.png
new file mode 100644 (file)
index 0000000..a62138e
Binary files /dev/null and b/data/edje_externals/ico_anchorblock.png differ
diff --git a/data/edje_externals/ico_anchorview.png b/data/edje_externals/ico_anchorview.png
new file mode 100644 (file)
index 0000000..7615015
Binary files /dev/null and b/data/edje_externals/ico_anchorview.png differ
diff --git a/data/edje_externals/ico_bubble.png b/data/edje_externals/ico_bubble.png
new file mode 100644 (file)
index 0000000..e2df401
Binary files /dev/null and b/data/edje_externals/ico_bubble.png differ
diff --git a/data/edje_externals/ico_button.png b/data/edje_externals/ico_button.png
new file mode 100644 (file)
index 0000000..842a432
Binary files /dev/null and b/data/edje_externals/ico_button.png differ
diff --git a/data/edje_externals/ico_check.png b/data/edje_externals/ico_check.png
new file mode 100644 (file)
index 0000000..2d05343
Binary files /dev/null and b/data/edje_externals/ico_check.png differ
diff --git a/data/edje_externals/ico_clock.png b/data/edje_externals/ico_clock.png
new file mode 100644 (file)
index 0000000..1a7ed02
Binary files /dev/null and b/data/edje_externals/ico_clock.png differ
diff --git a/data/edje_externals/ico_fileselector.png b/data/edje_externals/ico_fileselector.png
new file mode 100644 (file)
index 0000000..fbf06dc
Binary files /dev/null and b/data/edje_externals/ico_fileselector.png differ
diff --git a/data/edje_externals/ico_fileselector_button.png b/data/edje_externals/ico_fileselector_button.png
new file mode 100644 (file)
index 0000000..6b5c773
Binary files /dev/null and b/data/edje_externals/ico_fileselector_button.png differ
diff --git a/data/edje_externals/ico_genlist.png b/data/edje_externals/ico_genlist.png
new file mode 100644 (file)
index 0000000..ab19494
Binary files /dev/null and b/data/edje_externals/ico_genlist.png differ
diff --git a/data/edje_externals/ico_hoversel.png b/data/edje_externals/ico_hoversel.png
new file mode 100644 (file)
index 0000000..134d12d
Binary files /dev/null and b/data/edje_externals/ico_hoversel.png differ
diff --git a/data/edje_externals/ico_list.png b/data/edje_externals/ico_list.png
new file mode 100755 (executable)
index 0000000..9a1dc64
Binary files /dev/null and b/data/edje_externals/ico_list.png differ
diff --git a/data/edje_externals/ico_map.png b/data/edje_externals/ico_map.png
new file mode 100644 (file)
index 0000000..1c8ca8b
Binary files /dev/null and b/data/edje_externals/ico_map.png differ
diff --git a/data/edje_externals/ico_notepad.png b/data/edje_externals/ico_notepad.png
new file mode 100644 (file)
index 0000000..b957492
Binary files /dev/null and b/data/edje_externals/ico_notepad.png differ
diff --git a/data/edje_externals/ico_photocam.png b/data/edje_externals/ico_photocam.png
new file mode 100644 (file)
index 0000000..c789dbb
Binary files /dev/null and b/data/edje_externals/ico_photocam.png differ
diff --git a/data/edje_externals/ico_progressbar.png b/data/edje_externals/ico_progressbar.png
new file mode 100644 (file)
index 0000000..202aead
Binary files /dev/null and b/data/edje_externals/ico_progressbar.png differ
diff --git a/data/edje_externals/ico_radio.png b/data/edje_externals/ico_radio.png
new file mode 100644 (file)
index 0000000..080f4b0
Binary files /dev/null and b/data/edje_externals/ico_radio.png differ
diff --git a/data/edje_externals/ico_scrolled_entry.png b/data/edje_externals/ico_scrolled_entry.png
new file mode 100644 (file)
index 0000000..443e4c2
Binary files /dev/null and b/data/edje_externals/ico_scrolled_entry.png differ
diff --git a/data/edje_externals/ico_slider.png b/data/edje_externals/ico_slider.png
new file mode 100644 (file)
index 0000000..307f45c
Binary files /dev/null and b/data/edje_externals/ico_slider.png differ
diff --git a/data/edje_externals/ico_slideshow.png b/data/edje_externals/ico_slideshow.png
new file mode 100644 (file)
index 0000000..2341b7a
Binary files /dev/null and b/data/edje_externals/ico_slideshow.png differ
diff --git a/data/edje_externals/ico_spinner.png b/data/edje_externals/ico_spinner.png
new file mode 100644 (file)
index 0000000..0ab2af6
Binary files /dev/null and b/data/edje_externals/ico_spinner.png differ
diff --git a/data/edje_externals/ico_thumb.png b/data/edje_externals/ico_thumb.png
new file mode 100644 (file)
index 0000000..e98ed3d
Binary files /dev/null and b/data/edje_externals/ico_thumb.png differ
diff --git a/data/edje_externals/ico_toggle.png b/data/edje_externals/ico_toggle.png
new file mode 100644 (file)
index 0000000..e22086a
Binary files /dev/null and b/data/edje_externals/ico_toggle.png differ
diff --git a/data/edje_externals/ico_toolbar.png b/data/edje_externals/ico_toolbar.png
new file mode 100644 (file)
index 0000000..c3799cb
Binary files /dev/null and b/data/edje_externals/ico_toolbar.png differ
diff --git a/data/edje_externals/icons.edc b/data/edje_externals/icons.edc
new file mode 100644 (file)
index 0000000..e36ccea
--- /dev/null
@@ -0,0 +1,37 @@
+#define ICON(_name)                                         \
+images { image: "ico_"_name".png" COMP; }                   \
+collections { group { name: "ico_"_name;                    \
+      parts { part { name: "icon";                          \
+            type: IMAGE; mouse_events: 0;                   \
+            description { state: "default" 0.0;             \
+               align: 0.5 0.5;                              \
+               aspect: 1.0 1.0;                             \
+               aspect_preference: VERTICAL;                 \
+               image.normal: "ico_"_name".png";             \
+}}}}}
+
+ICON("anchorblock")
+ICON("anchorview")
+ICON("bubble")
+ICON("button")
+ICON("check")
+ICON("clock")
+ICON("fileselector")
+ICON("fileselector_button")
+ICON("genlist")
+ICON("hoversel")
+ICON("list")
+ICON("map")
+ICON("notepad")
+ICON("photocam")
+ICON("progressbar")
+ICON("radio")
+ICON("scrolled_entry")
+ICON("slider")
+ICON("slideshow")
+ICON("spinner")
+ICON("thumb")
+ICON("toggle")
+ICON("toolbar")
+ICON("slideshow")
+
diff --git a/data/images/Makefile.am b/data/images/Makefile.am
new file mode 100644 (file)
index 0000000..5e361be
--- /dev/null
@@ -0,0 +1,45 @@
+AUTOMAKE_OPTIONS     = 1.4 foreign
+MAINTAINERCLEANFILES = Makefile.in
+
+filesdir = $(datadir)/elementary/images
+files_DATA = \
+panel_01.jpg \
+plant_01.jpg \
+rock_01.jpg \
+rock_02.jpg \
+sky_01.jpg \
+sky_02.jpg \
+sky_03.jpg \
+sky_04.jpg \
+wood_01.jpg \
+logo.png \
+logo_small.png \
+parking.png \
+icon_00.png \
+icon_01.png \
+icon_02.png \
+icon_03.png \
+icon_04.png \
+icon_05.png \
+icon_06.png \
+icon_07.png \
+icon_08.png \
+icon_09.png \
+icon_10.png \
+icon_11.png \
+icon_12.png \
+icon_13.png \
+icon_14.png \
+icon_15.png \
+icon_16.png \
+icon_17.png \
+icon_18.png \
+icon_19.png \
+icon_20.png \
+icon_21.png \
+icon_22.png \
+icon_23.png \
+bubble.png \
+bubble_sh.png
+
+EXTRA_DIST = $(files_DATA)
diff --git a/data/images/bubble.png b/data/images/bubble.png
new file mode 100644 (file)
index 0000000..dfb71b7
Binary files /dev/null and b/data/images/bubble.png differ
diff --git a/data/images/bubble_sh.png b/data/images/bubble_sh.png
new file mode 100644 (file)
index 0000000..b66c1e6
Binary files /dev/null and b/data/images/bubble_sh.png differ
diff --git a/data/images/icon_00.png b/data/images/icon_00.png
new file mode 100644 (file)
index 0000000..d026778
Binary files /dev/null and b/data/images/icon_00.png differ
diff --git a/data/images/icon_01.png b/data/images/icon_01.png
new file mode 100644 (file)
index 0000000..faf524c
Binary files /dev/null and b/data/images/icon_01.png differ
diff --git a/data/images/icon_02.png b/data/images/icon_02.png
new file mode 100644 (file)
index 0000000..592cb5a
Binary files /dev/null and b/data/images/icon_02.png differ
diff --git a/data/images/icon_03.png b/data/images/icon_03.png
new file mode 100644 (file)
index 0000000..3d3063b
Binary files /dev/null and b/data/images/icon_03.png differ
diff --git a/data/images/icon_04.png b/data/images/icon_04.png
new file mode 100644 (file)
index 0000000..454bd62
Binary files /dev/null and b/data/images/icon_04.png differ
diff --git a/data/images/icon_05.png b/data/images/icon_05.png
new file mode 100644 (file)
index 0000000..bb81792
Binary files /dev/null and b/data/images/icon_05.png differ
diff --git a/data/images/icon_06.png b/data/images/icon_06.png
new file mode 100644 (file)
index 0000000..7f72520
Binary files /dev/null and b/data/images/icon_06.png differ
diff --git a/data/images/icon_07.png b/data/images/icon_07.png
new file mode 100644 (file)
index 0000000..1c76beb
Binary files /dev/null and b/data/images/icon_07.png differ
diff --git a/data/images/icon_08.png b/data/images/icon_08.png
new file mode 100644 (file)
index 0000000..c8fc8d2
Binary files /dev/null and b/data/images/icon_08.png differ
diff --git a/data/images/icon_09.png b/data/images/icon_09.png
new file mode 100644 (file)
index 0000000..f321617
Binary files /dev/null and b/data/images/icon_09.png differ
diff --git a/data/images/icon_10.png b/data/images/icon_10.png
new file mode 100644 (file)
index 0000000..c72918b
Binary files /dev/null and b/data/images/icon_10.png differ
diff --git a/data/images/icon_11.png b/data/images/icon_11.png
new file mode 100644 (file)
index 0000000..cdb212e
Binary files /dev/null and b/data/images/icon_11.png differ
diff --git a/data/images/icon_12.png b/data/images/icon_12.png
new file mode 100644 (file)
index 0000000..1954b9b
Binary files /dev/null and b/data/images/icon_12.png differ
diff --git a/data/images/icon_13.png b/data/images/icon_13.png
new file mode 100644 (file)
index 0000000..27d964e
Binary files /dev/null and b/data/images/icon_13.png differ
diff --git a/data/images/icon_14.png b/data/images/icon_14.png
new file mode 100644 (file)
index 0000000..2434b05
Binary files /dev/null and b/data/images/icon_14.png differ
diff --git a/data/images/icon_15.png b/data/images/icon_15.png
new file mode 100644 (file)
index 0000000..8ab20ce
Binary files /dev/null and b/data/images/icon_15.png differ
diff --git a/data/images/icon_16.png b/data/images/icon_16.png
new file mode 100644 (file)
index 0000000..7f5ad1e
Binary files /dev/null and b/data/images/icon_16.png differ
diff --git a/data/images/icon_17.png b/data/images/icon_17.png
new file mode 100644 (file)
index 0000000..6afaf7a
Binary files /dev/null and b/data/images/icon_17.png differ
diff --git a/data/images/icon_18.png b/data/images/icon_18.png
new file mode 100644 (file)
index 0000000..74eb0d6
Binary files /dev/null and b/data/images/icon_18.png differ
diff --git a/data/images/icon_19.png b/data/images/icon_19.png
new file mode 100644 (file)
index 0000000..d8784e0
Binary files /dev/null and b/data/images/icon_19.png differ
diff --git a/data/images/icon_20.png b/data/images/icon_20.png
new file mode 100644 (file)
index 0000000..69a9dca
Binary files /dev/null and b/data/images/icon_20.png differ
diff --git a/data/images/icon_21.png b/data/images/icon_21.png
new file mode 100644 (file)
index 0000000..6561e5f
Binary files /dev/null and b/data/images/icon_21.png differ
diff --git a/data/images/icon_22.png b/data/images/icon_22.png
new file mode 100644 (file)
index 0000000..d6130e8
Binary files /dev/null and b/data/images/icon_22.png differ
diff --git a/data/images/icon_23.png b/data/images/icon_23.png
new file mode 100644 (file)
index 0000000..27f5457
Binary files /dev/null and b/data/images/icon_23.png differ
diff --git a/data/images/logo.png b/data/images/logo.png
new file mode 100644 (file)
index 0000000..7dbae67
Binary files /dev/null and b/data/images/logo.png differ
diff --git a/data/images/logo_small.png b/data/images/logo_small.png
new file mode 100644 (file)
index 0000000..c7dc665
Binary files /dev/null and b/data/images/logo_small.png differ
diff --git a/data/images/panel_01.jpg b/data/images/panel_01.jpg
new file mode 100644 (file)
index 0000000..46fbdb9
Binary files /dev/null and b/data/images/panel_01.jpg differ
diff --git a/data/images/parking.png b/data/images/parking.png
new file mode 100644 (file)
index 0000000..0a3d801
Binary files /dev/null and b/data/images/parking.png differ
diff --git a/data/images/plant_01.jpg b/data/images/plant_01.jpg
new file mode 100644 (file)
index 0000000..f1714dd
Binary files /dev/null and b/data/images/plant_01.jpg differ
diff --git a/data/images/rock_01.jpg b/data/images/rock_01.jpg
new file mode 100644 (file)
index 0000000..c50ccb3
Binary files /dev/null and b/data/images/rock_01.jpg differ
diff --git a/data/images/rock_02.jpg b/data/images/rock_02.jpg
new file mode 100644 (file)
index 0000000..04aea8a
Binary files /dev/null and b/data/images/rock_02.jpg differ
diff --git a/data/images/sky_01.jpg b/data/images/sky_01.jpg
new file mode 100644 (file)
index 0000000..22f3050
Binary files /dev/null and b/data/images/sky_01.jpg differ
diff --git a/data/images/sky_02.jpg b/data/images/sky_02.jpg
new file mode 100644 (file)
index 0000000..d0d7448
Binary files /dev/null and b/data/images/sky_02.jpg differ
diff --git a/data/images/sky_03.jpg b/data/images/sky_03.jpg
new file mode 100644 (file)
index 0000000..cbad02a
Binary files /dev/null and b/data/images/sky_03.jpg differ
diff --git a/data/images/sky_04.jpg b/data/images/sky_04.jpg
new file mode 100644 (file)
index 0000000..c5cbc18
Binary files /dev/null and b/data/images/sky_04.jpg differ
diff --git a/data/images/wood_01.jpg b/data/images/wood_01.jpg
new file mode 100644 (file)
index 0000000..89f1006
Binary files /dev/null and b/data/images/wood_01.jpg differ
diff --git a/data/objects/Makefile.am b/data/objects/Makefile.am
new file mode 100644 (file)
index 0000000..8d936c8
--- /dev/null
@@ -0,0 +1,31 @@
+AUTOMAKE_OPTIONS     = 1.4 foreign
+MAINTAINERCLEANFILES = Makefile.in
+
+EDJE_CC = @edje_cc@
+EDJE_FLAGS = -v -id $(top_srcdir)/data/objects -fd $(top_srcdir)/data/objects
+
+filesdir = $(datadir)/elementary/objects
+
+files_DATA = test.edj multip.edj
+
+EXTRA_DIST = \
+test.edc \
+multip.edc \
+over.png \
+under.png \
+sky.jpg \
+clo.png \
+cross.png
+
+test.edj: Makefile $(EXTRA_DIST)
+       $(EDJE_CC) $(EDJE_FLAGS) \
+       $(top_srcdir)/data/objects/test.edc \
+       $(top_builddir)/data/objects/test.edj
+                       
+multip.edj: Makefile $(EXTRA_DIST)
+       $(EDJE_CC) $(EDJE_FLAGS) \
+       $(top_srcdir)/data/objects/multip.edc \
+       $(top_builddir)/data/objects/multip.edj
+                       
+clean-local:
+       rm -f *.edj
diff --git a/data/objects/clo.png b/data/objects/clo.png
new file mode 100644 (file)
index 0000000..dedfc51
Binary files /dev/null and b/data/objects/clo.png differ
diff --git a/data/objects/cross.png b/data/objects/cross.png
new file mode 100644 (file)
index 0000000..9670d7f
Binary files /dev/null and b/data/objects/cross.png differ
diff --git a/data/objects/multip.edc b/data/objects/multip.edc
new file mode 100644 (file)
index 0000000..66be6bb
--- /dev/null
@@ -0,0 +1,17 @@
+collections {
+   group { name: "point";
+      images {
+        image: "cross.png" COMP;
+      }
+      parts {
+        part { name: "sky";
+            mouse_events: 0;
+           description { state: "default" 0.0;
+               min: 301 301;
+              image.normal: "cross.png";
+           }
+        }
+      }
+   }
+}
+        
diff --git a/data/objects/over.png b/data/objects/over.png
new file mode 100644 (file)
index 0000000..5303e2d
Binary files /dev/null and b/data/objects/over.png differ
diff --git a/data/objects/sky.jpg b/data/objects/sky.jpg
new file mode 100644 (file)
index 0000000..6132e7c
Binary files /dev/null and b/data/objects/sky.jpg differ
diff --git a/data/objects/test.edc b/data/objects/test.edc
new file mode 100644 (file)
index 0000000..5fb5459
--- /dev/null
@@ -0,0 +1,140 @@
+collections {
+   group { name: "layout";
+      images {
+        image: "over.png" COMP;
+        image: "under.png" COMP;
+        image: "sky.jpg" LOSSY 80;
+        image: "clo.png" LOSSY 60;
+      }
+      parts {
+        part { name: "sky";
+            mouse_events: 0;
+           description { state: "default" 0.0;
+              aspect: 2.6225 2.6225;
+              aspect_preference: NONE;
+              image.normal: "sky.jpg";
+           }
+           description { state: "drift" 0.0;
+               inherit: "default" 0.0;
+               fill {
+                  origin {
+                     relative: 1.0 0.0;
+                     offset: 0 0;
+                  }
+               }
+           }
+        }
+        part { name: "under";
+            mouse_events: 0;
+           description { state: "default" 0.0;
+              align: 0.5 0.0;
+              aspect: 1.486068111 1.486068111;
+              aspect_preference: HORIZONTAL;
+              image.normal: "under.png";
+           }
+        }
+        part { name: "element1";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1 {
+                 relative: 0.2 0.2;
+              }
+              rel2 {
+                 relative: 0.4 0.3;
+              }
+           }
+        }
+        part { name: "element2";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1 {
+                 relative: 0.6 0.3;
+              }
+              rel2 {
+                 relative: 0.9 0.5;
+              }
+           }
+        }
+        part { name: "element3";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1 {
+                 relative: 0.1 0.7;
+              }
+              rel2 {
+                 relative: 0.9 0.9;
+              }
+           }
+        }
+        part { name: "over";
+            mouse_events: 0;
+           description { state: "default" 0.0;
+              align: 0.0 1.0;
+              aspect: 2.238095238 2.238095238;
+              max: 329 147;
+              aspect_preference: HORIZONTAL;
+              image.normal: "over.png";
+           }
+        }
+         part { name: "clo";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               fill {
+                  smooth: 0;
+                  origin {
+                     relative: 0.0 0.0;
+                     offset: 0 0;
+                  }
+                  size {
+                     relative: 1.84722 1.0;
+                     offset: 0 0;
+                  }
+               }
+               image.normal: "clo.png";
+            }
+            description { state: "drift" 0.0;
+               inherit: "default" 0.0;
+               fill {
+                  origin {
+                     relative: 1.84722 0.0;
+                     offset: 0 0;
+                  }
+                  size {
+                     relative: 1.84722 1.0;
+                     offset: 0 0;
+                  }
+               }
+            }
+         }
+      }
+      programs {
+         program { name: "anim1";
+            signal: "load";
+            source: "";
+            action: STATE_SET "drift" 0.0;
+            transition: LINEAR 10.0;
+            target: "clo";
+            after: "anim2";
+         }
+         program { name: "anim2";
+            action: STATE_SET "default" 0.0;
+            target: "clo";
+            after: "anim1";
+         }
+         program { name: "anim3";
+            signal: "load";
+            source: "";
+            action: STATE_SET "drift" 0.0;
+            transition: LINEAR 40.0;
+            target: "sky";
+            after: "anim4";
+         }
+         program { name: "anim4";
+            action: STATE_SET "default" 0.0;
+            target: "sky";
+            after: "anim3";
+         }
+      }
+   }
+}
+        
diff --git a/data/objects/under.png b/data/objects/under.png
new file mode 100644 (file)
index 0000000..91cb3fb
Binary files /dev/null and b/data/objects/under.png differ
diff --git a/data/themes/Makefile.am b/data/themes/Makefile.am
new file mode 100644 (file)
index 0000000..7170801
--- /dev/null
@@ -0,0 +1,195 @@
+AUTOMAKE_OPTIONS     = 1.4 foreign
+MAINTAINERCLEANFILES = Makefile.in
+
+EDJE_CC = @edje_cc@
+EDJE_FLAGS = -v -id $(top_srcdir)/data/themes -fd $(top_srcdir)/data/themes
+
+filesdir = $(datadir)/elementary/themes
+files_DATA = default.edj
+
+EXTRA_DIST = \
+default.edc \
+arrow_down.png \
+arrow_up.png \
+bt_base1.png \
+bt_base2.png \
+bt_bases.png \
+bt_basew.png \
+bt_glow.png \
+bt_hilight.png \
+bt_hilightw.png \
+bt_shine.png \
+bt_sm_base1.png \
+bt_sm_base2.png \
+bt_sm_hilight.png \
+bt_sm_shine.png \
+bt_dis_base.png \
+bt_dis_hilight.png \
+dia_botshad.png \
+dia_grad.png \
+dia_topshad.png \
+frame_1.png \
+frame_2.png \
+flip_0b.png \
+flip_0t.png \
+flip_1b.png \
+flip_1t.png \
+flip_2b.png \
+flip_2t.png \
+flip_3b.png \
+flip_3t.png \
+flip_4b.png \
+flip_4t.png \
+flip_5b.png \
+flip_5t.png \
+flip_6b.png \
+flip_6t.png \
+flip_7b.png \
+flip_7t.png \
+flip_8b.png \
+flip_8t.png \
+flip_9b.png \
+flip_9t.png \
+flip_amb.png \
+flip_amt.png \
+flip_base.png \
+flip_base_shad.png \
+flip_pmb.png \
+flip_pmt.png \
+flip_shad.png \
+head.png \
+sb_runnerh.png \
+sb_runnerv.png \
+shelf_inset.png \
+tog_base.png \
+tog_dis_base.png \
+shad_circ.png \
+bt_dis_base.png \
+bt_dis_hilight.png \
+outdent-top.png \
+outdent-bottom.png \
+updown.png \
+leftright.png \
+hoversel_entry_bg.png \
+cur_box.png \
+cur_hi.png \
+cur_shad.png \
+cur_shine.png \
+cur_glow.png \
+bubble.png \
+bubble_3.png \
+bubble_shine3.png \
+bubble_4.png \
+bubble_shine4.png \
+bubble_1.png \
+bubble_shine.png \
+bubble_2.png \
+icon_home.png \
+icon_close.png \
+icon_apps.png \
+icon_arrow_up.png \
+icon_arrow_down.png \
+icon_arrow_left.png \
+icon_arrow_right.png \
+bt_dis_shine.png \
+icon_left_arrow.png \
+icon_right_arrow.png \
+toolbar_sel.png \
+icon_chat.png \
+icon_clock.png \
+icon_delete.png \
+icon_edit.png \
+icon_refresh.png \
+icon_folder.png \
+icon_file.png \
+ilist_1.png \
+ilist_2.png \
+ilist_item_shadow.png \
+sl_bg.png \
+sl_bg_over.png \
+sl_bt_0.png \
+sl_bt_1.png \
+sl_bt_2.png \
+sl_bt2_0_0.png \
+sl_bt2_0_1.png \
+sl_bt2_0_2.png \
+sl_bt2_1.png \
+sl_bt2_2.png \
+sl_units.png \
+slv_bg.png \
+slv_bg_over.png \
+slv_units.png \
+check_base.png \
+check.png \
+check2.png \
+radio_base.png \
+radio.png \
+radio2.png \
+separator_h.png \
+separator_v.png \
+toolbar_separator_v.png \
+sp_bt_l.png \
+sp_bt_r.png \
+busy-1.png \
+busy-2.png \
+busy-3.png \
+busy-4.png \
+busy-5.png \
+busy-6.png \
+busy-7.png \
+busy-8.png \
+busy-9.png \
+arrow_right.png \
+bt_spinner_up.png \
+bt_spinner_down.png \
+bt_spinner_hilight.png \
+up.png \
+down.png \
+emo-angry.png \
+emo-angry-shout.png \
+emo-crazy-laugh.png \
+emo-evil-laugh.png \
+emo-evil.png \
+emo-goggle-smile.png \
+emo-grumpy.png \
+emo-grumpy-smile.png \
+emo-guilty.png \
+emo-guilty-smile.png \
+emo-haha.png \
+emo-half-smile.png \
+emo-happy-panting.png \
+emo-happy.png \
+emo-indifferent.png \
+emo-kiss.png \
+emo-knowing-grin.png \
+emo-laugh.png \
+emo-little-bit-sorry.png \
+emo-love-lots.png \
+emo-love.png \
+emo-minimal-smile.png \
+emo-not-happy.png \
+emo-not-impressed.png \
+emo-omg.png \
+emo-opensmile.png \
+emo-smile.png \
+emo-sorry.png \
+emo-squint-laugh.png \
+emo-surprised.png \
+emo-suspicious.png \
+emo-tongue-dangling.png \
+emo-tongue-poke.png \
+emo-uh.png \
+emo-unhappy.png \
+emo-very-sorry.png \
+emo-what.png \
+emo-wink.png \
+emo-worried.png \
+emo-wtf.png
+
+default.edj: Makefile $(EXTRA_DIST)
+       $(EDJE_CC) $(EDJE_FLAGS) \
+       $(top_srcdir)/data/themes/default.edc \
+       $(top_builddir)/data/themes/default.edj
+
+clean-local:
+       rm -f *.edj
diff --git a/data/themes/arrow_down.png b/data/themes/arrow_down.png
new file mode 100644 (file)
index 0000000..db81aac
Binary files /dev/null and b/data/themes/arrow_down.png differ
diff --git a/data/themes/arrow_down.xcf.gz b/data/themes/arrow_down.xcf.gz
new file mode 100644 (file)
index 0000000..3d4e89c
Binary files /dev/null and b/data/themes/arrow_down.xcf.gz differ
diff --git a/data/themes/arrow_right.png b/data/themes/arrow_right.png
new file mode 100644 (file)
index 0000000..268d6d1
Binary files /dev/null and b/data/themes/arrow_right.png differ
diff --git a/data/themes/arrow_up.png b/data/themes/arrow_up.png
new file mode 100644 (file)
index 0000000..a90fe93
Binary files /dev/null and b/data/themes/arrow_up.png differ
diff --git a/data/themes/arrow_up.xcf.gz b/data/themes/arrow_up.xcf.gz
new file mode 100644 (file)
index 0000000..977e24c
Binary files /dev/null and b/data/themes/arrow_up.xcf.gz differ
diff --git a/data/themes/bt_base1.png b/data/themes/bt_base1.png
new file mode 100644 (file)
index 0000000..2d1f179
Binary files /dev/null and b/data/themes/bt_base1.png differ
diff --git a/data/themes/bt_base2.png b/data/themes/bt_base2.png
new file mode 100644 (file)
index 0000000..dd3e3ce
Binary files /dev/null and b/data/themes/bt_base2.png differ
diff --git a/data/themes/bt_bases.png b/data/themes/bt_bases.png
new file mode 100644 (file)
index 0000000..1b867fd
Binary files /dev/null and b/data/themes/bt_bases.png differ
diff --git a/data/themes/bt_basew.png b/data/themes/bt_basew.png
new file mode 100644 (file)
index 0000000..8d787dd
Binary files /dev/null and b/data/themes/bt_basew.png differ
diff --git a/data/themes/bt_dis_base.png b/data/themes/bt_dis_base.png
new file mode 100644 (file)
index 0000000..06f3dd5
Binary files /dev/null and b/data/themes/bt_dis_base.png differ
diff --git a/data/themes/bt_dis_hilight.png b/data/themes/bt_dis_hilight.png
new file mode 100644 (file)
index 0000000..e5cf7d3
Binary files /dev/null and b/data/themes/bt_dis_hilight.png differ
diff --git a/data/themes/bt_dis_shine.png b/data/themes/bt_dis_shine.png
new file mode 100644 (file)
index 0000000..20285be
Binary files /dev/null and b/data/themes/bt_dis_shine.png differ
diff --git a/data/themes/bt_glow.png b/data/themes/bt_glow.png
new file mode 100644 (file)
index 0000000..e995ff1
Binary files /dev/null and b/data/themes/bt_glow.png differ
diff --git a/data/themes/bt_hilight.png b/data/themes/bt_hilight.png
new file mode 100644 (file)
index 0000000..3b7fe5b
Binary files /dev/null and b/data/themes/bt_hilight.png differ
diff --git a/data/themes/bt_hilightw.png b/data/themes/bt_hilightw.png
new file mode 100644 (file)
index 0000000..b97a4f8
Binary files /dev/null and b/data/themes/bt_hilightw.png differ
diff --git a/data/themes/bt_shine.png b/data/themes/bt_shine.png
new file mode 100644 (file)
index 0000000..a58bdee
Binary files /dev/null and b/data/themes/bt_shine.png differ
diff --git a/data/themes/bt_sm_base1.png b/data/themes/bt_sm_base1.png
new file mode 100644 (file)
index 0000000..c37e182
Binary files /dev/null and b/data/themes/bt_sm_base1.png differ
diff --git a/data/themes/bt_sm_base2.png b/data/themes/bt_sm_base2.png
new file mode 100644 (file)
index 0000000..f159648
Binary files /dev/null and b/data/themes/bt_sm_base2.png differ
diff --git a/data/themes/bt_sm_hilight.png b/data/themes/bt_sm_hilight.png
new file mode 100644 (file)
index 0000000..63899ca
Binary files /dev/null and b/data/themes/bt_sm_hilight.png differ
diff --git a/data/themes/bt_sm_shine.png b/data/themes/bt_sm_shine.png
new file mode 100644 (file)
index 0000000..23bf311
Binary files /dev/null and b/data/themes/bt_sm_shine.png differ
diff --git a/data/themes/bt_spinner_down.png b/data/themes/bt_spinner_down.png
new file mode 100644 (file)
index 0000000..233f2a9
Binary files /dev/null and b/data/themes/bt_spinner_down.png differ
diff --git a/data/themes/bt_spinner_hilight.png b/data/themes/bt_spinner_hilight.png
new file mode 100644 (file)
index 0000000..55d50b8
Binary files /dev/null and b/data/themes/bt_spinner_hilight.png differ
diff --git a/data/themes/bt_spinner_up.png b/data/themes/bt_spinner_up.png
new file mode 100644 (file)
index 0000000..ea351be
Binary files /dev/null and b/data/themes/bt_spinner_up.png differ
diff --git a/data/themes/bubble.png b/data/themes/bubble.png
new file mode 100644 (file)
index 0000000..78b831b
Binary files /dev/null and b/data/themes/bubble.png differ
diff --git a/data/themes/bubble_1.png b/data/themes/bubble_1.png
new file mode 100644 (file)
index 0000000..fd6d00c
Binary files /dev/null and b/data/themes/bubble_1.png differ
diff --git a/data/themes/bubble_2.png b/data/themes/bubble_2.png
new file mode 100644 (file)
index 0000000..6e1e847
Binary files /dev/null and b/data/themes/bubble_2.png differ
diff --git a/data/themes/bubble_3.png b/data/themes/bubble_3.png
new file mode 100644 (file)
index 0000000..cbdcf9c
Binary files /dev/null and b/data/themes/bubble_3.png differ
diff --git a/data/themes/bubble_4.png b/data/themes/bubble_4.png
new file mode 100644 (file)
index 0000000..5eefbff
Binary files /dev/null and b/data/themes/bubble_4.png differ
diff --git a/data/themes/bubble_shine.png b/data/themes/bubble_shine.png
new file mode 100644 (file)
index 0000000..33fd1d8
Binary files /dev/null and b/data/themes/bubble_shine.png differ
diff --git a/data/themes/bubble_shine3.png b/data/themes/bubble_shine3.png
new file mode 100644 (file)
index 0000000..398062f
Binary files /dev/null and b/data/themes/bubble_shine3.png differ
diff --git a/data/themes/bubble_shine4.png b/data/themes/bubble_shine4.png
new file mode 100644 (file)
index 0000000..9ab6fd0
Binary files /dev/null and b/data/themes/bubble_shine4.png differ
diff --git a/data/themes/busy-1.png b/data/themes/busy-1.png
new file mode 100644 (file)
index 0000000..0997dee
Binary files /dev/null and b/data/themes/busy-1.png differ
diff --git a/data/themes/busy-2.png b/data/themes/busy-2.png
new file mode 100644 (file)
index 0000000..71c65a4
Binary files /dev/null and b/data/themes/busy-2.png differ
diff --git a/data/themes/busy-3.png b/data/themes/busy-3.png
new file mode 100644 (file)
index 0000000..96e63ab
Binary files /dev/null and b/data/themes/busy-3.png differ
diff --git a/data/themes/busy-4.png b/data/themes/busy-4.png
new file mode 100644 (file)
index 0000000..4ecb44c
Binary files /dev/null and b/data/themes/busy-4.png differ
diff --git a/data/themes/busy-5.png b/data/themes/busy-5.png
new file mode 100644 (file)
index 0000000..2978f49
Binary files /dev/null and b/data/themes/busy-5.png differ
diff --git a/data/themes/busy-6.png b/data/themes/busy-6.png
new file mode 100644 (file)
index 0000000..a73d583
Binary files /dev/null and b/data/themes/busy-6.png differ
diff --git a/data/themes/busy-7.png b/data/themes/busy-7.png
new file mode 100644 (file)
index 0000000..2cc0f80
Binary files /dev/null and b/data/themes/busy-7.png differ
diff --git a/data/themes/busy-8.png b/data/themes/busy-8.png
new file mode 100644 (file)
index 0000000..c07cddc
Binary files /dev/null and b/data/themes/busy-8.png differ
diff --git a/data/themes/busy-9.png b/data/themes/busy-9.png
new file mode 100644 (file)
index 0000000..9fdf098
Binary files /dev/null and b/data/themes/busy-9.png differ
diff --git a/data/themes/check.png b/data/themes/check.png
new file mode 100644 (file)
index 0000000..7d58e85
Binary files /dev/null and b/data/themes/check.png differ
diff --git a/data/themes/check2.png b/data/themes/check2.png
new file mode 100644 (file)
index 0000000..1748d5d
Binary files /dev/null and b/data/themes/check2.png differ
diff --git a/data/themes/check_base.png b/data/themes/check_base.png
new file mode 100644 (file)
index 0000000..96481c9
Binary files /dev/null and b/data/themes/check_base.png differ
diff --git a/data/themes/cur_box.png b/data/themes/cur_box.png
new file mode 100644 (file)
index 0000000..136b8c8
Binary files /dev/null and b/data/themes/cur_box.png differ
diff --git a/data/themes/cur_glow.png b/data/themes/cur_glow.png
new file mode 100644 (file)
index 0000000..fd922bd
Binary files /dev/null and b/data/themes/cur_glow.png differ
diff --git a/data/themes/cur_hi.png b/data/themes/cur_hi.png
new file mode 100644 (file)
index 0000000..cbafef8
Binary files /dev/null and b/data/themes/cur_hi.png differ
diff --git a/data/themes/cur_shad.png b/data/themes/cur_shad.png
new file mode 100644 (file)
index 0000000..3e899de
Binary files /dev/null and b/data/themes/cur_shad.png differ
diff --git a/data/themes/cur_shine.png b/data/themes/cur_shine.png
new file mode 100644 (file)
index 0000000..6df5a6d
Binary files /dev/null and b/data/themes/cur_shine.png differ
diff --git a/data/themes/default.edc b/data/themes/default.edc
new file mode 100644 (file)
index 0000000..535ddb8
--- /dev/null
@@ -0,0 +1,23235 @@
+// LICENSE NOTE:
+// This file (and only this one) is licenses under public-domain. The reason
+// is that this is meant to serve as a template for making your own themes and
+// Elementary's LGPL license is not intended to follow. The images used do come
+// under LGPL, but this file specifically for the structure of your theme is
+// public-domain. This means you can take, use, re-license and otherwise
+// have zero restrictions on using this file as a base for your theme.
+
+collections {
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/bg/base/default";
+      images {
+         image: "dia_grad.png" COMP;
+        image: "dia_topshad.png" COMP;
+        image: "dia_botshad.png" COMP;
+      }
+      parts {
+         part { name: "base";
+           mouse_events:  0;
+           description { state: "default" 0.0;
+              image.normal: "dia_grad.png";
+              fill {
+                 smooth: 0;
+                 size {
+                    relative: 0.0 1.0;
+                    offset: 64 0;
+                 }
+              }
+           }
+        }
+        part { name: "elm.swallow.background";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+           }
+        }
+        part { name: "shadow";
+           mouse_events:  0;
+           description { state: "default" 0.0;
+              rel2.relative: 1.0 0.0;
+              rel2.offset: -1 31;
+              image.normal: "dia_topshad.png";
+              fill {
+                 smooth: 0;
+                 size {
+                    relative: 0.0 1.0;
+                    offset: 64 0;
+                 }
+              }
+           }
+        }
+        part { name: "shadow2";
+           mouse_events:  0;
+           description { state: "default" 0.0;
+              rel1.relative: 0.0 1.0;
+              rel1.offset: 0 -4;
+              image.normal: "dia_botshad.png";
+              fill {
+                 smooth: 0;
+                 size {
+                    relative: 0.0 1.0;
+                    offset: 64 0;
+                 }
+              }
+           }
+        }
+        part { name: "elm.swallow.content";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.offset:  4 4;
+              rel2.offset: -5 -5;
+           }
+        }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/scroller/base/default";
+
+      alias: "elm/list/base/default";
+      alias: "elm/genlist/base/default";
+      alias: "elm/carousel/base/default";
+      alias: "elm/grid/base/default";
+
+      script {
+        public sbvis_v, sbvis_h, sbalways_v, sbalways_h, sbvis_timer;
+        public timer0(val) {
+           new v;
+           v = get_int(sbvis_v);
+           if (v) {
+               v = get_int(sbalways_v);
+               if (!v) {
+                  emit("do-hide-vbar", "");
+                  set_int(sbvis_v, 0);
+               }
+           }
+           v = get_int(sbvis_h);
+           if (v) {
+               v = get_int(sbalways_h);
+               if (!v) {
+                  emit("do-hide-hbar", "");
+                  set_int(sbvis_h, 0);
+               }
+           }
+           set_int(sbvis_timer, 0);
+           return 0;
+        }
+      }
+      images {
+        image: "shelf_inset.png" COMP;
+        image: "bt_sm_base2.png" COMP;
+        image: "bt_sm_shine.png" COMP;
+        image: "bt_sm_hilight.png" COMP;
+        image: "sb_runnerh.png" COMP;
+        image: "sb_runnerv.png" COMP;
+      }
+      parts {
+         part { name: "bg";
+           type: RECT;
+           description { state: "default" 0.0;
+              rel1.offset: 1 1;
+              rel2.offset: -2 -2;
+              color: 255 255 255 0;
+           }
+        }
+        part { name: "clipper";
+           type: RECT;
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "bg";
+              rel2.to: "bg";
+           }
+        }
+        part { name: "elm.swallow.content";
+           clip_to: "clipper";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.offset: 1 1;
+              rel2.offset: -2 -2;
+           }
+        }
+        part { name: "conf_over";
+           mouse_events:  0;
+           description { state: "default" 0.0;
+              rel1.offset: 0 0;
+              rel2.offset: -1 -1;
+              image {
+                 normal: "shelf_inset.png";
+                 border: 7 7 7 7;
+                 middle: 0;
+              }
+              fill.smooth : 0;
+           }
+        }
+        part { name: "sb_vbar_clip_master";
+           type: RECT;
+           mouse_events: 0;
+           description { state: "default" 0.0;
+           }
+           description { state: "hidden" 0.0;
+              visible: 0;
+              color: 255 255 255 0;
+           }
+        }
+        part { name: "sb_vbar_clip";
+            clip_to: "sb_vbar_clip_master";
+           type: RECT;
+           mouse_events: 0;
+           description { state: "default" 0.0;
+           }
+           description { state: "hidden" 0.0;
+              visible: 0;
+              color: 255 255 255 0;
+           }
+        }
+        part { name: "sb_vbar";
+           type: RECT;
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              fixed: 1 1;
+              visible: 0;
+              min: 17 17;
+              align: 1.0 0.0;
+              rel1 {
+                 relative: 1.0 0.0;
+                 offset:   -2 0;
+              }
+              rel2 {
+                 relative: 1.0 0.0;
+                 offset:   -2 -1;
+                 to_y:     "sb_hbar";
+              }
+           }
+        }
+        part { name: "sb_vbar_runner";
+           clip_to: "sb_vbar_clip";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              min: 3 3;
+              max: 3 99999;
+              rel1.to:       "sb_vbar";
+              rel2.to:       "sb_vbar";
+              image {
+                 normal: "sb_runnerv.png";
+                 border: 0 0 4 4;
+              }
+              fill.smooth: 0;
+           }
+        }
+        part { name: "elm.dragable.vbar";
+           clip_to: "sb_vbar_clip";
+           mouse_events: 0;
+           dragable {
+              x: 0 0 0;
+              y: 1 1 0;
+              confine: "sb_vbar";
+           }
+           description { state: "default" 0.0;
+              fixed: 1 1;
+              min: 17 17;
+              rel1 {
+                 relative: 0.5  0.5;
+                 offset:   0    0;
+                 to: "sb_vbar";
+              }
+              rel2 {
+                 relative: 0.5  0.5;
+                 offset:   0    0;
+                 to: "sb_vbar";
+              }
+              image {
+                 normal: "bt_sm_base2.png";
+                 border: 6 6 6 6;
+              }
+               image.middle: SOLID;
+           }
+        }
+        part { name: "sb_vbar_over1";
+           clip_to: "sb_vbar_clip";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "elm.dragable.vbar";
+              rel2.relative: 1.0 0.5;
+              rel2.to: "elm.dragable.vbar";
+              image {
+                 normal: "bt_sm_hilight.png";
+                 border: 6 6 6 0;
+              }
+           }
+        }
+        part { name: "sb_vbar_over2";
+           clip_to: "sb_vbar_clip";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "elm.dragable.vbar";
+              rel2.to: "elm.dragable.vbar";
+              image {
+                 normal: "bt_sm_shine.png";
+                 border: 6 6 6 0;
+              }
+           }
+        }
+
+        part { name: "sb_hbar_clip_master";
+           type: RECT;
+           mouse_events: 0;
+           description { state: "default" 0.0;
+           }
+           description { state: "hidden" 0.0;
+              visible: 0;
+              color: 255 255 255 0;
+           }
+        }
+        part { name: "sb_hbar_clip";
+            clip_to: "sb_hbar_clip_master";
+           type: RECT;
+           mouse_events: 0;
+           description { state: "default" 0.0;
+           }
+           description { state: "hidden" 0.0;
+              visible: 0;
+              color: 255 255 255 0;
+           }
+        }
+        part { name: "sb_hbar";
+           type: RECT;
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              fixed: 1 1;
+              visible: 0;
+              min: 17 17;
+              align: 0.0 1.0;
+              rel1 {
+                 relative: 0.0 1.0;
+                 offset:   0 -2;
+              }
+              rel2 {
+                 relative: 0.0 1.0;
+                 offset:   -1 -2;
+                 to_x:     "sb_vbar";
+              }
+           }
+        }
+        part { name: "sb_hbar_runner";
+           clip_to: "sb_hbar_clip";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              min: 3 3;
+              max: 99999 3;
+              rel1.to:       "sb_hbar";
+              rel2.to:       "sb_hbar";
+              image {
+                 normal: "sb_runnerh.png";
+                 border: 4 4 0 0;
+              }
+              fill.smooth: 0;
+           }
+        }
+        part { name: "elm.dragable.hbar";
+           clip_to: "sb_hbar_clip";
+           mouse_events: 0;
+           dragable {
+              x: 1 1 0;
+              y: 0 0 0;
+              confine: "sb_hbar";
+           }
+           description { state: "default" 0.0;
+              fixed: 1 1;
+              min: 17 17;
+              rel1 {
+                 relative: 0.5  0.5;
+                 offset:   0    0;
+                 to: "sb_hbar";
+              }
+              rel2 {
+                 relative: 0.5  0.5;
+                 offset:   0    0;
+                 to: "sb_hbar";
+              }
+              image {
+                 normal: "bt_sm_base2.png";
+                 border: 6 6 6 6;
+              }
+               image.middle: SOLID;
+           }
+        }
+        part { name: "sb_hbar_over1";
+           clip_to: "sb_hbar_clip";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "elm.dragable.hbar";
+              rel2.relative: 1.0 0.5;
+              rel2.to: "elm.dragable.hbar";
+              image {
+                 normal: "bt_sm_hilight.png";
+                 border: 6 6 6 0;
+              }
+           }
+        }
+        part { name: "sb_hbar_over2";
+           clip_to: "sb_hbar_clip";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "elm.dragable.hbar";
+              rel2.to: "elm.dragable.hbar";
+              image {
+                 normal: "bt_sm_shine.png";
+                 border: 6 6 6 0;
+              }
+           }
+        }
+      }
+      programs {
+        program { name: "load";
+           signal: "load";
+           source: "";
+           script {
+              set_state(PART:"sb_hbar_clip", "hidden", 0.0);
+              set_state(PART:"sb_vbar_clip", "hidden", 0.0);
+              set_int(sbvis_h, 0);
+              set_int(sbvis_v, 0);
+              set_int(sbalways_v, 0);
+              set_int(sbalways_h, 0);
+              set_int(sbvis_timer, 0);
+           }
+        }
+
+        program { name: "vbar_show";
+           signal: "elm,action,show,vbar";
+           source: "elm";
+            action:  STATE_SET "default" 0.0;
+            target: "sb_vbar_clip_master";
+        }
+        program { name: "vbar_hide";
+           signal: "elm,action,hide,vbar";
+           source: "elm";
+            action:  STATE_SET "hidden" 0.0;
+            target: "sb_vbar_clip_master";
+        }
+        program { name: "vbar_show_always";
+           signal: "elm,action,show_always,vbar";
+           source: "elm";
+            script {
+               new v;
+               v = get_int(sbvis_v);
+               v |= get_int(sbalways_v);
+               if (!v) {
+                  set_int(sbalways_v, 1);
+                  emit("do-show-vbar", "");
+                  set_int(sbvis_v, 1);
+               }
+            }
+        }
+        program { name: "vbar_show_notalways";
+           signal: "elm,action,show_notalways,vbar";
+           source: "elm";
+            script {
+               new v;
+               v = get_int(sbalways_v);
+               if (v) {
+                  set_int(sbalways_v, 0);
+                  v = get_int(sbvis_v);
+                  if (!v) {
+                     emit("do-hide-vbar", "");
+                     set_int(sbvis_v, 0);
+                  }
+               }
+            }
+        }
+        program { name: "sb_vbar_show";
+           signal: "do-show-vbar";
+           source: "";
+           action:  STATE_SET "default" 0.0;
+           transition: LINEAR 1.0;
+           target: "sb_vbar_clip";
+        }
+        program { name: "sb_vbar_hide";
+           signal: "do-hide-vbar";
+           source: "";
+           action:  STATE_SET "hidden" 0.0;
+           transition: LINEAR 1.0;
+           target: "sb_vbar_clip";
+        }
+
+        program { name: "hbar_show";
+           signal: "elm,action,show,hbar";
+           source: "elm";
+            action:  STATE_SET "default" 0.0;
+            target: "sb_hbar_clip_master";
+        }
+        program { name: "hbar_hide";
+           signal: "elm,action,hide,hbar";
+           source: "elm";
+            action:  STATE_SET "hidden" 0.0;
+            target: "sb_hbar_clip_master";
+        }
+        program { name: "hbar_show_always";
+           signal: "elm,action,show_always,hbar";
+           source: "elm";
+            script {
+               new v;
+               v = get_int(sbvis_h);
+               v |= get_int(sbalways_h);
+               if (!v) {
+                  set_int(sbalways_h, 1);
+                  emit("do-show-hbar", "");
+                  set_int(sbvis_h, 1);
+               }
+            }
+        }
+        program { name: "hbar_show_notalways";
+           signal: "elm,action,show_notalways,hbar";
+           source: "elm";
+            script {
+               new v;
+               v = get_int(sbalways_h);
+               if (v) {
+                  set_int(sbalways_h, 0);
+                  v = get_int(sbvis_h);
+                  if (!v) {
+                     emit("do-hide-hbar", "");
+                     set_int(sbvis_h, 0);
+                  }
+               }
+            }
+        }
+        program { name: "sb_hbar_show";
+           signal: "do-show-hbar";
+           source: "";
+           action:  STATE_SET "default" 0.0;
+           transition: LINEAR 1.0;
+           target: "sb_hbar_clip";
+        }
+        program { name: "sb_hbar_hide";
+           signal: "do-hide-hbar";
+           source: "";
+           action:  STATE_SET "hidden" 0.0;
+           transition: LINEAR 1.0;
+           target: "sb_hbar_clip";
+        }
+
+        program { name: "scroll";
+           signal: "elm,action,scroll";
+           source: "elm";
+           script {
+              new v;
+              v = get_int(sbvis_v);
+               v |= get_int(sbalways_v);
+              if (!v) {
+                  emit("do-show-vbar", "");
+                  set_int(sbvis_v, 1);
+              }
+              v = get_int(sbvis_h);
+               v |= get_int(sbalways_h);
+              if (!v) {
+                  emit("do-show-hbar", "");
+                  set_int(sbvis_h, 1);
+              }
+              v = get_int(sbvis_timer);
+              if (v > 0) cancel_timer(v);
+              v = timer(2.0, "timer0", 0);
+              set_int(sbvis_timer, v);
+           }
+        }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/label/base/default";
+      styles
+       {
+          style { name: "textblock_style";
+             base: "font=Sans font_size=10 align=left color=#000 wrap=word";
+
+             tag:  "br" "\n";
+             tag:  "hilight" "+ font=Sans:style=Bold";
+             tag:  "b" "+ font=Sans:style=Bold";
+             tag:  "tab" "\t";
+          }
+       }
+      parts {
+        part { name: "elm.text";
+           type: TEXTBLOCK;
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              text {
+                 style: "textblock_style";
+                 min: 1 1;
+              }
+           }
+        }
+      }
+   }
+
+   group { name: "elm/label/base_wrap/default";
+      parts {
+        part { name: "elm.text";
+           type: TEXTBLOCK;
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              text {
+                 style: "textblock_style";
+                 min: 0 1;
+              }
+           }
+        }
+      }
+   }
+
+   group { name: "elm/label/base/marker";
+      styles
+       {
+          style { name: "textblock_style2";
+             base: "font=Sans:style=Bold font_size=10 align=center color=#fff wrap=word";
+
+             tag:  "br" "\n";
+             tag:  "hilight" "+ color=#ffff";
+             tag:  "b" "+ color=#ffff";
+             tag:  "tab" "\t";
+          }
+       }
+      parts {
+        part { name: "elm.text";
+           type: TEXTBLOCK;
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              text {
+                 style: "textblock_style2";
+                 min: 1 1;
+              }
+           }
+        }
+      }
+   }
+
+   group { name: "elm/label/base_wrap/marker";
+      parts {
+        part { name: "elm.text";
+           type: TEXTBLOCK;
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              text {
+                 style: "textblock_style2";
+                 min: 0 1;
+              }
+           }
+        }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+
+   group { name: "elm/button/base/default";
+      images {
+        image: "bt_base1.png" COMP;
+        image: "bt_base2.png" COMP;
+        image: "bt_hilight.png" COMP;
+        image: "bt_shine.png" COMP;
+        image: "bt_glow.png" COMP;
+        image: "bt_dis_base.png" COMP;
+        image: "bt_dis_hilight.png" COMP;
+      }
+      parts {
+        part { name: "button_image";
+           mouse_events: 1;
+           description { state: "default" 0.0;
+              image {
+                 normal: "bt_base2.png";
+                 border: 7 7 7 7;
+              }
+               image.middle: SOLID;
+           }
+           description { state: "clicked" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "bt_base1.png";
+               image.middle: SOLID;
+           }
+           description { state: "disabled" 0.0;
+              inherit:  "default" 0.0;
+              image {
+                 normal: "bt_dis_base.png";
+                 border: 4 4 4 4;
+              }
+           }
+        }
+        part { name: "elm.swallow.content";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+               fixed: 1 0;
+              visible: 0;
+              align: 0.0 0.5;
+              rel1.offset: 4 4;
+              rel2.offset: 3 -5;
+              rel2.relative: 0.0 1.0;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+               fixed: 1 0;
+              visible: 1;
+              aspect: 1.0 1.0;
+              aspect_preference: VERTICAL;
+              rel2.offset: 4 -5;
+           }
+           description { state: "icononly" 0.0;
+              inherit: "default" 0.0;
+               fixed: 0 0;
+              visible: 1;
+              align: 0.5 0.5;
+              aspect: 1.0 1.0;
+              rel2.offset: -5 -5;
+              rel2.relative: 1.0 1.0;
+              aspect_preference: VERTICAL;
+           }
+        }
+         part {
+           name:          "elm.text";
+           type:          TEXT;
+           effect:        SOFT_SHADOW;
+           mouse_events:  0;
+           scale: 1;
+           description { state: "default" 0.0;
+              visible: 0;
+              rel1.to_x: "elm.swallow.content";
+              rel1.relative: 1.0 0.0;
+               rel1.offset: 0 4;
+              rel2.offset: -5 -5;
+              color: 224 224 224 255;
+              color3: 0 0 0 64;
+              text {
+                 font:     "Sans,Edje-Vera";
+                 size:     10;
+                 min:      0 0;
+                 align:    0.5 0.5;
+              }
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              text.min: 1 1;
+           }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+              color: 0 0 0 128;
+              color3: 0 0 0 0;
+           }
+           description { state: "disabled_visible" 0.0;
+              inherit: "default" 0.0;
+              color: 0 0 0 128;
+              color3: 0 0 0 0;
+              visible: 1;
+              text.min: 1 1;
+           }
+        }
+        part {   name: "over1";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel2.relative: 1.0 0.5;
+              image {
+                 normal: "bt_hilight.png";
+                 border: 7 7 7 0;
+              }
+           }
+           description { state: "disabled" 0.0;
+              inherit:  "default" 0.0;
+              image {
+                 normal: "bt_dis_hilight.png";
+                 border: 4 4 4 0;
+              }
+           }
+        }
+        part { name: "over2";
+           mouse_events: 1;
+           repeat_events: 1;
+            ignore_flags: ON_HOLD;
+           description { state: "default" 0.0;
+              image {
+                 normal: "bt_shine.png";
+                 border: 7 7 7 7;
+              }
+           }
+           description { state: "disabled" 0.0;
+              inherit:  "default" 0.0;
+              visible: 0;
+           }
+        }
+         part { name: "over3";
+            mouse_events: 1;
+            repeat_events: 1;
+            description { state: "default" 0.0;
+               color: 255 255 255 0;
+               image {
+                  normal: "bt_glow.png";
+                  border: 12 12 12 12;
+               }
+              fill.smooth : 0;
+            }
+            description { state: "clicked" 0.0;
+               inherit:  "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+        part { name: "disabler";
+           type: RECT;
+           description { state: "default" 0.0;
+              color: 0 0 0 0;
+              visible: 0;
+           }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+           }
+        }
+      }
+      programs {
+        program {
+           name:   "button_click";
+           signal: "mouse,down,1";
+           source: "over2";
+           action: SIGNAL_EMIT "elm,action,press" "";
+           after: "button_click_anim";
+        }
+        program {
+           name:   "button_click_anim";
+           action: STATE_SET "clicked" 0.0;
+           target: "button_image";
+        }
+        program {
+           name:   "button_unclick";
+           signal: "mouse,up,1";
+           source: "over2";
+           action: SIGNAL_EMIT "elm,action,unpress" "";
+           after: "button_unclick_anim";
+        }
+        program {
+           name:   "button_unclick_anim";
+           action: STATE_SET "default" 0.0;
+           target: "button_image";
+        }
+        program {
+           name:   "button_click2";
+           signal: "mouse,down,1";
+           source: "over3";
+           action: STATE_SET "clicked" 0.0;
+           target: "over3";
+        }
+        program {
+           name:   "button_unclick2";
+           signal: "mouse,up,1";
+           source: "over3";
+           action: STATE_SET "default" 0.0;
+            transition: DECELERATE 0.5;
+           target: "over3";
+        }
+        program {
+           name:   "button_unclick3";
+           signal: "mouse,up,1";
+           source: "over2";
+           action: SIGNAL_EMIT "elm,action,click" "";
+        }
+        program { name: "text_show";
+           signal: "elm,state,text,visible";
+           source: "elm";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.swallow.content", st, 30, vl);
+              if (!strcmp(st, "icononly"))
+                set_state(PART:"elm.swallow.content", "visible", 0.0);
+              set_state(PART:"elm.text", "visible", 0.0);
+           }
+        }
+        program { name: "text_hide";
+           signal: "elm,state,text,hidden";
+           source: "elm";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.swallow.content", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.swallow.content", "icononly", 0.0);
+              set_state(PART:"elm.text", "default", 0.0);
+           }
+        }
+        program { name: "icon_show";
+           signal: "elm,state,icon,visible";
+           source: "elm";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.text", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.swallow.content", "visible", 0.0);
+              else
+                set_state(PART:"elm.swallow.content", "icononly", 0.0);
+           }
+        }
+        program { name: "icon_hide";
+           signal: "elm,state,icon,hidden";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "elm.swallow.content";
+        }
+        program { name: "disable";
+           signal: "elm,state,disabled";
+           source: "elm";
+           action: STATE_SET "disabled" 0.0;
+           target: "button_image";
+           target: "over1";
+           target: "over2";
+           target: "disabler";
+            after: "disable_text";
+        }
+         program { name: "disable_text";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.text", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.text", "disabled_visible", 0.0);
+              else
+                set_state(PART:"elm.text", "disabled", 0.0);
+           }
+         }
+        program { name: "enable";
+           signal: "elm,state,enabled";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "button_image";
+           target: "over1";
+           target: "over2";
+           target: "disabler";
+            after: "enable_text";
+        }
+         program { name: "enable_text";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.text", st, 30, vl);
+              if (!strcmp(st, "disabled_visible"))
+                set_state(PART:"elm.text", "visible", 0.0);
+              else
+                set_state(PART:"elm.text", "default", 0.0);
+           }
+         }
+      }
+   }
+
+   group { name: "elm/button/base/hoversel_vertical/default";
+      alias: "elm/button/base/hoversel_vertical/entry";
+      alias: "elm/button/base/hoversel_horizontal/default";
+      alias: "elm/button/base/hoversel_horizontal/entry";
+      images {
+        image: "bt_base1.png" COMP;
+        image: "bt_base2.png" COMP;
+        image: "bt_hilight.png" COMP;
+        image: "bt_shine.png" COMP;
+        image: "bt_glow.png" COMP;
+        image: "updown.png" COMP;
+        image: "bt_dis_base.png" COMP;
+        image: "bt_dis_hilight.png" COMP;
+      }
+      parts {
+        part { name: "button_image";
+           mouse_events: 1;
+           description { state: "default" 0.0;
+              image {
+                 normal: "bt_base2.png";
+                 border: 7 7 7 7;
+              }
+               image.middle: SOLID;
+           }
+           description { state: "clicked" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "bt_base1.png";
+               image.middle: SOLID;
+           }
+           description { state: "disabled" 0.0;
+              inherit:  "default" 0.0;
+              image {
+                 normal: "bt_dis_base.png";
+                 border: 4 4 4 4;
+              }
+           }
+        }
+        part { name: "arrow";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              image.normal: "updown.png";
+               aspect: 0.6666666666 0.6666666666;
+               aspect_preference: VERTICAL;
+               rel1.offset: 6 7;
+               rel2.offset: 6 -7;
+               rel2.relative: 0.0 1.0;
+               align: 0.0 0.5;
+           }
+        }
+        part { name: "elm.swallow.content";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+               fixed: 1 0;
+              visible: 0;
+              align: 0.0 0.5;
+              rel1 {
+                  to_x: "arrow";
+                  offset: 2 4;
+                  relative: 1.0 0.0;
+               }
+              rel2 {
+                  to_x: "arrow";
+                  offset: 1 -5;
+                  relative: 1.0 1.0;
+               }
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+               fixed: 0 0;
+              visible: 1;
+              aspect: 1.0 1.0;
+              aspect_preference: VERTICAL;
+              rel2.offset: 2 -5;
+           }
+           description { state: "icononly" 0.0;
+              inherit: "default" 0.0;
+               fixed: 0 0;
+              visible: 1;
+              align: 0.5 0.5;
+              aspect: 1.0 1.0;
+               rel1 {
+                  to_x: "button_image";
+                  offset: -5 -5;
+                  relative: 1.0 1.0;
+               }
+              aspect_preference: VERTICAL;
+           }
+        }
+         part {
+           name:          "elm.text";
+           type:          TEXT;
+           effect:        SOFT_SHADOW;
+           mouse_events:  0;
+           scale: 1;
+           description { state: "default" 0.0;
+              visible: 0;
+              rel1.to_x: "elm.swallow.content";
+              rel1.relative: 1.0 0.0;
+               rel1.offset: 0 4;
+              rel2.offset: -5 -5;
+              color: 224 224 224 255;
+              color3: 0 0 0 64;
+              text {
+                 font:     "Sans,Edje-Vera";
+                 size:     10;
+                 min:      0 0;
+                 align:    0.5 0.5;
+              }
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              text.min: 1 1;
+           }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+              color: 0 0 0 128;
+              color3: 0 0 0 0;
+           }
+           description { state: "disabled_visible" 0.0;
+              inherit: "default" 0.0;
+              color: 0 0 0 128;
+              color3: 0 0 0 0;
+              visible: 1;
+              text.min: 1 1;
+           }
+        }
+        part {   name: "over1";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel2.relative: 1.0 0.5;
+              image {
+                 normal: "bt_hilight.png";
+                 border: 7 7 7 0;
+              }
+           }
+           description { state: "disabled" 0.0;
+              inherit:  "default" 0.0;
+              image {
+                 normal: "bt_dis_hilight.png";
+                 border: 4 4 4 0;
+              }
+           }
+        }
+        part { name: "over2";
+           mouse_events: 1;
+           repeat_events: 1;
+            ignore_flags: ON_HOLD;
+           description { state: "default" 0.0;
+              image {
+                 normal: "bt_shine.png";
+                 border: 7 7 7 7;
+              }
+           }
+           description { state: "disabled" 0.0;
+              inherit:  "default" 0.0;
+              visible: 0;
+           }
+        }
+         part { name: "over3";
+            mouse_events: 1;
+            repeat_events: 1;
+            description { state: "default" 0.0;
+               color: 255 255 255 0;
+               image {
+                  normal: "bt_glow.png";
+                  border: 12 12 12 12;
+               }
+              fill.smooth : 0;
+            }
+            description { state: "clicked" 0.0;
+               inherit:  "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+        part { name: "disabler";
+           type: RECT;
+           description { state: "default" 0.0;
+              color: 0 0 0 0;
+              visible: 0;
+           }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+           }
+        }
+      }
+      programs {
+        program {
+           name:   "button_click";
+           signal: "mouse,down,1";
+           source: "over2";
+           action: STATE_SET "clicked" 0.0;
+           target: "button_image";
+        }
+        program {
+           name:   "button_unclick";
+           signal: "mouse,up,1";
+           source: "over2";
+           action: STATE_SET "default" 0.0;
+           target: "button_image";
+        }
+        program {
+           name:   "button_click2";
+           signal: "mouse,down,1";
+           source: "over3";
+           action: STATE_SET "clicked" 0.0;
+           target: "over3";
+        }
+        program {
+           name:   "button_unclick2";
+           signal: "mouse,up,1";
+           source: "over3";
+           action: STATE_SET "default" 0.0;
+            transition: DECELERATE 0.5;
+           target: "over3";
+        }
+        program {
+           name:   "button_unclick3";
+           signal: "mouse,up,1";
+           source: "over2";
+           action: SIGNAL_EMIT "elm,action,click" "";
+        }
+        program { name: "text_show";
+           signal: "elm,state,text,visible";
+           source: "elm";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.swallow.content", st, 30, vl);
+              if (!strcmp(st, "icononly"))
+                set_state(PART:"elm.swallow.content", "visible", 0.0);
+              set_state(PART:"elm.text", "visible", 0.0);
+           }
+        }
+        program { name: "text_hide";
+           signal: "elm,state,text,hidden";
+           source: "elm";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.swallow.content", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.swallow.content", "icononly", 0.0);
+              set_state(PART:"elm.text", "default", 0.0);
+           }
+        }
+        program { name: "icon_show";
+           signal: "elm,state,icon,visible";
+           source: "elm";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.text", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.swallow.content", "visible", 0.0);
+              else
+                set_state(PART:"elm.swallow.content", "icononly", 0.0);
+           }
+        }
+        program { name: "icon_hide";
+           signal: "elm,state,icon,hidden";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "elm.swallow.content";
+        }
+        program { name: "disable";
+           signal: "elm,state,disabled";
+           source: "elm";
+           action: STATE_SET "disabled" 0.0;
+           target: "button_image";
+           target: "over1";
+           target: "over2";
+           target: "disabler";
+            after: "disable_text";
+        }
+         program { name: "disable_text";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.text", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.text", "disabled_visible", 0.0);
+              else
+                set_state(PART:"elm.text", "disabled", 0.0);
+           }
+         }
+        program { name: "enable";
+           signal: "elm,state,enabled";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "button_image";
+           target: "over1";
+           target: "over2";
+           target: "disabler";
+            after: "enable_text";
+        }
+         program { name: "enable_text";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.text", st, 30, vl);
+              if (!strcmp(st, "disabled_visible"))
+                set_state(PART:"elm.text", "visible", 0.0);
+              else
+                set_state(PART:"elm.text", "default", 0.0);
+           }
+         }
+      }
+   }
+
+   group { name: "elm/button/base/hoversel_vertical_entry/default";
+      alias: "elm/button/base/hoversel_vertical_entry/entry";
+      alias: "elm/button/base/hoversel_horizontal_entry/default";
+      alias: "elm/button/base/hoversel_horizontal_entry/entry";
+      images {
+         image: "hoversel_entry_bg.png" COMP;
+      }
+      parts {
+        part { name: "button_image";
+           mouse_events: 1;
+           description { state: "default" 0.0;
+               color: 255 255 255 0;
+               image.normal: "hoversel_entry_bg.png";
+               image.border: 0 0 2 2;
+               fill.smooth: 0;
+           }
+           description { state: "clicked" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 255;
+           }
+        }
+        part { name: "elm.swallow.content";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              visible: 0;
+              align: 0.0 0.5;
+              rel1.offset: 4 4;
+              rel2.offset: 3 -5;
+              rel2.relative: 0.0 1.0;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              aspect: 1.0 1.0;
+              aspect_preference: VERTICAL;
+              rel2.offset: 4 -5;
+           }
+           description { state: "icononly" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              align: 0.5 0.5;
+              aspect: 1.0 1.0;
+              rel2.offset: -5 -5;
+              rel2.relative: 1.0 1.0;
+              aspect_preference: VERTICAL;
+           }
+        }
+        part { name: "textvis";
+            type: RECT;
+           mouse_events: 0;
+           description { state: "default" 0.0;
+               visible: 0;
+           }
+           description { state: "visible" 0.0;
+               visible: 1;
+           }
+        }
+         part {
+           name:          "elm.text";
+           type:          TEXT;
+           effect:        SOFT_SHADOW;
+           mouse_events:  0;
+           scale: 1;
+            clip_to:       "textvis";
+           description { state: "default" 0.0;
+              rel1.to_x: "elm.swallow.content";
+              rel1.relative: 1.0 0.0;
+               rel1.offset: 0 4;
+              rel2.offset: -5 -5;
+              color: 224 224 224 255;
+              color3: 0 0 0 64;
+              text {
+                 font:     "Sans,Edje-Vera";
+                 size:     10;
+                 min:      0 0;
+                 align:    0.5 0.5;
+              }
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              text.min: 1 1;
+           }
+           description { state: "clicked" 0.0;
+              inherit: "default" 0.0;
+              text.min: 1 1;
+              color: 0 0 0 255;
+              color3: 0 0 0 0;
+           }
+        }
+        part { name: "over2";
+            type: RECT;
+           mouse_events: 1;
+           description { state: "default" 0.0;
+               color: 0 0 0 0;
+           }
+        }
+      }
+      programs {
+        program {
+           name:   "button_click";
+           signal: "mouse,down,1";
+           source: "over2";
+           action: STATE_SET "clicked" 0.0;
+           target: "button_image";
+           target: "elm.text";
+        }
+        program {
+           name:   "button_unclick";
+           signal: "mouse,up,1";
+           source: "over2";
+           action: STATE_SET "default" 0.0;
+           target: "button_image";
+           target: "elm.text";
+        }
+        program {
+           name:   "button_unclick3";
+           signal: "mouse,up,1";
+           source: "over2";
+           action: SIGNAL_EMIT "elm,action,click" "";
+        }
+        program { name: "text_show";
+           signal: "elm,state,text,visible";
+           source: "elm";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.swallow.content", st, 30, vl);
+              if (!strcmp(st, "icononly"))
+                set_state(PART:"elm.swallow.content", "visible", 0.0);
+              set_state(PART:"textvis", "visible", 0.0);
+              set_state(PART:"elm.text", "visible", 0.0);
+           }
+        }
+        program { name: "text_hide";
+           signal: "elm,state,text,hidden";
+           source: "elm";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.swallow.content", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.swallow.content", "icononly", 0.0);
+              set_state(PART:"textvis", "default", 0.0);
+              set_state(PART:"elm.text", "default", 0.0);
+           }
+        }
+        program { name: "icon_show";
+           signal: "elm,state,icon,visible";
+           source: "elm";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"textvis", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.swallow.content", "visible", 0.0);
+              else
+                set_state(PART:"elm.swallow.content", "icononly", 0.0);
+           }
+        }
+        program { name: "icon_hide";
+           signal: "elm,state,icon,hidden";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "elm.swallow.content";
+        }
+      }
+   }
+
+   group { name: "elm/button/base/anchor";
+      images {
+        image: "bt_base1.png" COMP;
+        image: "bt_base2.png" COMP;
+        image: "bt_hilight.png" COMP;
+        image: "bt_shine.png" COMP;
+        image: "bt_glow.png" COMP;
+        image: "bt_dis_base.png" COMP;
+        image: "bt_dis_hilight.png" COMP;
+      }
+      parts {
+        part { name: "button_image";
+           mouse_events: 1;
+           description { state: "default" 0.0;
+           color: 255 255 255 0;
+              image {
+                 normal: "bt_base2.png";
+                 border: 7 7 7 7;
+              }
+               image.middle: SOLID;
+           }
+       description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+          color: 255 255 255 255;
+           }
+           description { state: "clicked" 0.0;
+              inherit: "default" 0.0;
+          inherit: "visible" 0.0;
+              image.normal: "bt_base1.png";
+               image.middle: SOLID;
+           }
+           description { state: "disabled" 0.0;
+              inherit:  "default" 0.0;
+          inherit: "visible" 0.0;
+              image {
+                 normal: "bt_dis_base.png";
+                 border: 4 4 4 4;
+              }
+           }
+        }
+        part { name: "elm.swallow.content";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+               fixed: 1 0;
+              visible: 0;
+              align: 0.0 0.5;
+              rel1.offset: 4 4;
+              rel2.offset: 3 -5;
+              rel2.relative: 0.0 1.0;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+               fixed: 1 0;
+              visible: 1;
+              aspect: 1.0 1.0;
+              aspect_preference: VERTICAL;
+              rel2.offset: 4 -5;
+           }
+           description { state: "icononly" 0.0;
+              inherit: "default" 0.0;
+               fixed: 0 0;
+              visible: 1;
+              align: 0.5 0.5;
+              aspect: 1.0 1.0;
+              rel2.offset: -5 -5;
+              rel2.relative: 1.0 1.0;
+              aspect_preference: VERTICAL;
+           }
+        }
+         part {
+           name:          "elm.text";
+           type:          TEXT;
+           effect:        SOFT_SHADOW;
+           mouse_events:  0;
+           scale: 1;
+           description { state: "default" 0.0;
+              visible: 0;
+              rel1.to_x: "elm.swallow.content";
+              rel1.relative: 1.0 0.0;
+               rel1.offset: 0 4;
+              rel2.offset: -5 -5;
+              color: 224 224 224 255;
+              color3: 0 0 0 64;
+              text {
+                 font:     "Sans,Edje-Vera";
+                 size:     10;
+                 min:      0 0;
+                 align:    0.5 0.5;
+              }
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              text.min: 1 1;
+           }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+              color: 0 0 0 128;
+              color3: 0 0 0 0;
+           }
+           description { state: "disabled_visible" 0.0;
+              inherit: "default" 0.0;
+              color: 0 0 0 128;
+              color3: 0 0 0 0;
+              visible: 1;
+              text.min: 1 1;
+           }
+        }
+        part {   name: "over1";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+           color: 255 255 255 0;
+              rel2.relative: 1.0 0.5;
+              image {
+                 normal: "bt_hilight.png";
+                 border: 7 7 7 0;
+              }
+           }
+       description { state: "visible" 0.0;
+              inherit:  "default" 0.0;
+          color: 255 255 255 255;
+           }
+           description { state: "disabled" 0.0;
+              inherit:  "default" 0.0;
+          inherit:  "visible" 0.0;
+              image {
+                 normal: "bt_dis_hilight.png";
+                 border: 4 4 4 0;
+              }
+           }
+        }
+        part { name: "over2";
+           mouse_events: 1;
+           repeat_events: 1;
+            ignore_flags: ON_HOLD;
+           description { state: "default" 0.0;
+              image {
+                 normal: "bt_shine.png";
+                 border: 7 7 7 7;
+              }
+           }
+           description { state: "disabled" 0.0;
+              inherit:  "default" 0.0;
+              visible: 0;
+           }
+        }
+         part { name: "over3";
+            mouse_events: 1;
+            repeat_events: 1;
+            description { state: "default" 0.0;
+               color: 255 255 255 0;
+               image {
+                  normal: "bt_glow.png";
+                  border: 12 12 12 12;
+               }
+              fill.smooth : 0;
+            }
+            description { state: "clicked" 0.0;
+               inherit:  "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+        part { name: "disabler";
+           type: RECT;
+           description { state: "default" 0.0;
+              color: 0 0 0 0;
+              visible: 0;
+           }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+           }
+        }
+      }
+      programs {
+    program {
+           name:   "button_mouse_in";
+           signal: "mouse,in";
+           source: "over2";
+           action: STATE_SET "visible" 0.0;
+           target: "button_image";
+       target: "over1";
+       transition: DECELERATE 0.5;
+        }
+        program {
+           name:   "button_mouse_out";
+           signal: "mouse,out";
+           source: "over2";
+           action: STATE_SET "default" 0.0;
+           target: "button_image";
+       target: "over1";
+       transition: DECELERATE 0.5;
+        }
+        program {
+           name:   "button_unclick";
+           signal: "mouse,up,1";
+           source: "over2";
+           action: STATE_SET "visible" 0.0;
+           target: "button_image";
+        }
+        program {
+           name:   "button_click2";
+           signal: "mouse,down,1";
+           source: "over3";
+           action: STATE_SET "clicked" 0.0;
+           target: "over3";
+        }
+        program {
+           name:   "button_unclick2";
+           signal: "mouse,up,1";
+           source: "over3";
+           action: STATE_SET "default" 0.0;
+            transition: DECELERATE 0.5;
+           target: "over3";
+        }
+        program {
+           name:   "button_unclick3";
+           signal: "mouse,up,1";
+           source: "over2";
+           action: SIGNAL_EMIT "elm,action,click" "";
+        }
+        program { name: "text_show";
+           signal: "elm,state,text,visible";
+           source: "elm";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.swallow.content", st, 30, vl);
+              if (!strcmp(st, "icononly"))
+                set_state(PART:"elm.swallow.content", "visible", 0.0);
+              set_state(PART:"elm.text", "visible", 0.0);
+           }
+        }
+        program { name: "text_hide";
+           signal: "elm,state,text,hidden";
+           source: "elm";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.swallow.content", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.swallow.content", "icononly", 0.0);
+              set_state(PART:"elm.text", "default", 0.0);
+           }
+        }
+        program { name: "icon_show";
+           signal: "elm,state,icon,visible";
+           source: "elm";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.text", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.swallow.content", "visible", 0.0);
+              else
+                set_state(PART:"elm.swallow.content", "icononly", 0.0);
+           }
+        }
+        program { name: "icon_hide";
+           signal: "elm,state,icon,hidden";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "elm.swallow.content";
+        }
+        program { name: "disable";
+           signal: "elm,state,disabled";
+           source: "elm";
+           action: STATE_SET "disabled" 0.0;
+           target: "button_image";
+           target: "over1";
+           target: "over2";
+           target: "disabler";
+            after: "disable_text";
+        }
+         program { name: "disable_text";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.text", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.text", "disabled_visible", 0.0);
+              else
+                set_state(PART:"elm.text", "disabled", 0.0);
+           }
+         }
+        program { name: "enable";
+           signal: "elm,state,enabled";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "button_image";
+           target: "over1";
+           target: "over2";
+           target: "disabler";
+            after: "enable_text";
+        }
+         program { name: "enable_text";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.text", st, 30, vl);
+              if (!strcmp(st, "disabled_visible"))
+                set_state(PART:"elm.text", "visible", 0.0);
+              else
+                set_state(PART:"elm.text", "default", 0.0);
+           }
+         }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/toggle/base/default";
+      images {
+         image: "shelf_inset.png" COMP;
+        image: "bt_basew.png" COMP;
+        image: "bt_bases.png" COMP;
+        image: "bt_hilightw.png" COMP;
+        image: "tog_base.png" COMP;
+        image: "tog_dis_base.png" COMP;
+      }
+      parts {
+         part { name: "bg";
+           type: RECT;
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              rel1.relative: 1.0 0.0;
+              rel1.offset: -4 3;
+              rel2.offset: -4 -4;
+              align: 1.0 0.5;
+              min: 96 16;
+              max: 96 16;
+              aspect: 4.0 4.0;
+              aspect_preference: VERTICAL;
+              color: 255 255 255 255;
+           }
+        }
+         part { name: "clipper";
+           type: RECT;
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "bg";
+              rel2.to: "bg";
+              color: 255 255 255 255;
+           }
+        }
+         part { name: "button";
+           type: RECT;
+           scale: 1;
+           clip_to: "clipper";
+           mouse_events: 1;
+           dragable {
+              x: 1 1 0;
+              y: 0 0 0;
+              confine: "bg";
+           }
+           description { state: "default" 0.0;
+              fixed: 1 1;
+              rel1.to: "bg";
+              rel2.to: "bg";
+              min: 16 16;
+              max: 16 16;
+              aspect: 1.0 1.0;
+              aspect_preference: VERTICAL;
+              color: 0 0 0 0;
+           }
+        }
+         part { name: "button_events";
+           type: RECT;
+           dragable {
+              events: "button";
+           }
+           description { state: "default" 0.0;
+              rel1.to_x: "bg";
+              rel1.offset: 0 0;
+              rel1.relative: 0.0 0.0;
+              rel2.to_x: "bg";
+              rel2.offset: -1 -1;
+              rel2.relative: 1.0 1.0;
+              color: 0 0 0 0;
+           }
+        }
+         part { name: "onrect";
+           type: RECT;
+           scale: 1;
+           clip_to: "clipper";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "button";
+              rel1.relative: -5.0 0.0;
+              rel2.to: "button";
+              rel2.relative: 0.0 1.0;
+              color: 0 0 0 0;
+           }
+        }
+         part { name: "offrect";
+           type: RECT;
+           scale: 1;
+           clip_to: "clipper";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "button";
+              rel1.relative: 1.0 0.0;
+              rel2.to: "button";
+              rel2.relative: 6.0 1.0;
+              color: 0 0 0 0;
+           }
+        }
+        part { name: "togbase";
+           mouse_events:  0;
+           clip_to: "clipper";
+           description { state: "default" 0.0;
+              rel1.to: "onrect";
+              rel2.to: "offrect";
+              image.normal: "tog_base.png";
+           }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "tog_dis_base.png";
+           }
+        }
+         part { name: "elm.offtext";
+           type: TEXT;
+           mouse_events:  0;
+           scale: 1;
+           clip_to: "clipper";
+           description { state: "default" 0.0;
+               fixed: 1 1;
+              rel1.to_x: "offrect";
+              rel2.to_x: "offrect";
+              color: 0 0 0 255;
+              text {
+                 font:     "Sans,Edje-Vera";
+                 size:     10;
+                 min:      0 1;
+                 align:    0.5 0.5;
+                 text:     "OFF";
+              }
+           }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 128;
+           }
+        }
+         part { name: "elm.ontext";
+           type: TEXT;
+           effect: SOFT_SHADOW;
+           mouse_events:  0;
+           scale: 1;
+           clip_to: "clipper";
+           description { state: "default" 0.0;
+               fixed: 1 1;
+              rel1.to_x: "onrect";
+              rel1.offset: 1 1;
+              rel2.to_x: "onrect";
+              rel2.offset: 0 0;
+              color: 224 224 224 255;
+              color3: 0 0 0 64;
+              text {
+                 font:     "Sans,Edje-Vera";
+                 size:     10;
+                 min:      0 1;
+                 align:    0.5 0.5;
+                 text:     "ON";
+              }
+           }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 128;
+              color3: 0 0 0 24;
+           }
+        }
+        part { name: "conf_over";
+           mouse_events:  0;
+           description { state: "default" 0.0;
+              rel1.offset: -1 -1;
+              rel1.to: "bg";
+              rel2.offset: 0 0;
+              rel2.to: "bg";
+              image {
+                 normal: "shelf_inset.png";
+                 border: 7 7 7 7;
+                 middle: 0;
+              }
+              fill.smooth : 0;
+           }
+        }
+        part { name: "button0";
+           mouse_events:  0;
+           clip_to: "clipper";
+           description { state: "default" 0.0;
+              rel1.to: "button2";
+              rel1.offset: -4 -4;
+              rel2.to: "button2";
+              rel2.offset: 3 3;
+              image {
+                 normal: "bt_bases.png";
+                 border: 11 11 11 11;
+              }
+               image.middle: SOLID;
+              color: 255 255 255 128;
+           }
+        }
+        part { name: "button2";
+           mouse_events:  0;
+           clip_to: "clipper";
+           description { state: "default" 0.0;
+              rel1.to: "button";
+              rel1.offset: -2 -2;
+              rel2.to: "button";
+              rel2.offset: 1 1;
+              image {
+                 normal: "bt_basew.png";
+                 border: 7 7 7 7;
+              }
+               image.middle: SOLID;
+           }
+        }
+        part { name: "button3";
+           mouse_events:  0;
+           clip_to: "clipper";
+           description { state: "default" 0.0;
+              rel1.to: "button2";
+              rel2.to: "button2";
+               rel2.relative: 1.0 0.5;
+              image {
+                  normal: "bt_hilightw.png";
+                 border: 4 4 4 0;
+              }
+           }
+        }
+        part { name: "elm.swallow.content";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+               fixed: 1 0;
+              visible: 0;
+              align: 0.0 0.5;
+              rel1.offset: 4 4;
+              rel2.relative: 0.0 1.0;
+              rel2.offset: 3 -5;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+               fixed: 1 1;
+              visible: 1;
+              aspect: 1.0 1.0;
+              aspect_preference: VERTICAL;
+              rel2.offset: 4 -5;
+           }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 128;
+           }
+           description { state: "disabled_visible" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 128;
+               fixed: 1 1;
+              visible: 1;
+              aspect: 1.0 1.0;
+           }
+        }
+         part { name: "elm.text";
+           type: TEXT;
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              visible: 0;
+              rel1.to_x: "elm.swallow.content";
+              rel1.relative: 1.0 0.0;
+               rel1.offset: 0 4;
+              rel2.to_x: "bg";
+              rel2.relative: 0.0 1.0;
+              rel2.offset: -5 -5;
+              color: 0 0 0 255;
+              text {
+                 font: "Sans,Edje-Vera";
+                 size: 10;
+                 min: 0 0;
+                 align: 0.0 0.5;
+              }
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              text.min: 1 1;
+           }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 128;
+           }
+           description { state: "disabled_visible" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 128;
+              visible: 1;
+           }
+        }
+        part { name: "disabler";
+           type: RECT;
+           description { state: "default" 0.0;
+              color: 0 0 0 0;
+              visible: 0;
+           }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+           }
+        }
+      }
+      programs {
+        program { name:   "drag_end";
+           signal: "mouse,up,1";
+           source: "button";
+           script {
+              new Float:dx, Float:dy;
+              get_drag(PART:"button", dx, dy);
+              if (dx > 0.5)
+                {
+                   set_drag(PART:"button", 1.0, 0.0);
+                   emit("elm,action,toggle,on", "");
+                }
+              else
+                {
+                   set_drag(PART:"button", 0.0, 0.0);
+                   emit("elm,action,toggle,off", "");
+                }
+           }
+        }
+        program { name: "toggle_on";
+           signal: "elm,state,toggle,on";
+           source: "elm";
+           script {
+              set_drag(PART:"button", 100.0, 0.0);
+           }
+        }
+        program { name: "toggle_off";
+           signal: "elm,state,toggle,off";
+           source: "elm";
+           script {
+              set_drag(PART:"button", 0.0, 0.0);
+           }
+        }
+        program { name: "text_show";
+           signal: "elm,state,text,visible";
+           source: "elm";
+           action:  STATE_SET "visible" 0.0;
+           target: "elm.text";
+        }
+        program { name: "text_hide";
+           signal: "elm,state,text,hidden";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "elm.text";
+        }
+        program { name: "icon_show";
+           signal: "elm,state,icon,visible";
+           source: "elm";
+           action:  STATE_SET "visible" 0.0;
+           target: "elm.swallow.content";
+        }
+        program { name: "icon_hide";
+           signal: "elm,state,icon,hidden";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "elm.swallow.content";
+        }
+        program { name: "disable";
+           signal: "elm,state,disabled";
+           source: "elm";
+           action: STATE_SET "disabled" 0.0;
+           target: "togbase";
+           target: "elm.offtext";
+           target: "elm.ontext";
+           target: "disabler";
+            after: "disable_text";
+        }
+         program { name: "disable_text";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.text", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.text", "disabled_visible", 0.0);
+              else
+                set_state(PART:"elm.text", "disabled", 0.0);
+
+               get_state(PART:"elm.swallow.content", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.swallow.content", "disabled_visible", 0.0);
+              else
+                set_state(PART:"elm.swallow.content", "disabled", 0.0);
+           }
+         }
+        program { name: "enable";
+           signal: "elm,state,enabled";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "disabler";
+            after: "enable_text";
+        }
+         program { name: "enable_text";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.text", st, 30, vl);
+              if (!strcmp(st, "disabled_visible"))
+                set_state(PART:"elm.text", "visible", 0.0);
+              else
+                set_state(PART:"elm.text", "default", 0.0);
+
+               get_state(PART:"elm.swallow.content", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.swallow.content", "visible", 0.0);
+              else
+                set_state(PART:"elm.swallow.content", "default", 0.0);
+           }
+         }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/clock/flipdigit/default";
+      images {
+         image: "flip_base.png" COMP;
+         image: "flip_base_shad.png" COMP;
+         image: "flip_shad.png" COMP;
+         image: "flip_0t.png" COMP;
+         image: "flip_0b.png" COMP;
+         image: "flip_1t.png" COMP;
+         image: "flip_1b.png" COMP;
+         image: "flip_2t.png" COMP;
+         image: "flip_2b.png" COMP;
+         image: "flip_3t.png" COMP;
+         image: "flip_3b.png" COMP;
+         image: "flip_4t.png" COMP;
+         image: "flip_4b.png" COMP;
+         image: "flip_5t.png" COMP;
+         image: "flip_5b.png" COMP;
+         image: "flip_6t.png" COMP;
+         image: "flip_6b.png" COMP;
+         image: "flip_7t.png" COMP;
+         image: "flip_7b.png" COMP;
+         image: "flip_8t.png" COMP;
+         image: "flip_8b.png" COMP;
+         image: "flip_9t.png" COMP;
+         image: "flip_9b.png" COMP;
+        image: "arrow_up.png" COMP;
+        image: "arrow_down.png" COMP;
+      }
+      script {
+        public v0_cur, v0_pre, v0_lock, v0_next;
+
+       public animator2(val, Float:pos) {
+         new st1[11], st2[11], v;
+
+         v = get_int(v0_cur);
+         snprintf(st1, 10, "%ih", v);
+         snprintf(st2, 10, "%i", v);
+         set_tween_state(PART:"bot", pos, st1, 0.0, st2, 0.0);
+         set_tween_state(PART:"sh", pos, "half", 0.0, "full", 0.0);
+         if (pos >= 1.0) {
+            set_state(PART:"sh", "default", 0.0);
+            set_int(v0_lock, 0);
+            v = get_int(v0_next);
+            if (v >= 0) {
+               set_int(v0_next, -1);
+               message(MSG_INT, 1, v);
+            }
+         }
+       }
+       public animator1(val, Float:pos) {
+         new st1[11], st2[11], v;
+
+         v = get_int(v0_pre);
+         snprintf(st1, 10, "%i", v);
+         snprintf(st2, 10, "%ih", v);
+         set_tween_state(PART:"top", pos, st1, 0.0, st2, 0.0);
+         set_tween_state(PART:"sh", pos, "default", 0.0, "half", 0.0);
+         if (pos >= 1.0) anim(0.2, "animator2", val);
+       }
+       public message(Msg_Type:type, id, ...) {
+         if ((type == MSG_INT) && (id == 1)) {
+            new value, v, buf[11];
+
+            value = getarg(2);
+            if (get_int(v0_lock) == 1) {
+               set_int(v0_next, value);
+               return;
+            }
+            v = get_int(v0_cur);
+            set_int(v0_pre, v);
+            set_int(v0_cur, value);
+            set_int(v0_lock, 1);
+            snprintf(buf, 10, "%i", get_int(v0_pre));
+            set_state(PART:"bot0", buf, 0.0);
+            snprintf(buf, 10, "%ih", get_int(v0_cur));
+            set_state(PART:"bot", buf, 0.0);
+            snprintf(buf, 10, "%i", get_int(v0_cur));
+            set_state(PART:"top0", buf, 0.0);
+            snprintf(buf, 10, "%i", get_int(v0_pre));
+            set_state(PART:"top", buf, 0.0);
+            set_state(PART:"sh", "default", 0.0);
+            anim(0.2, "animator1", 1);
+         }
+       }
+      }
+      parts {
+        part { name: "shad";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.offset: -4 -4;
+              rel1.to: "base";
+              rel2.offset: 3 3;
+              rel2.to: "base";
+              image {
+                  normal: "flip_base_shad.png";
+                 border: 8 8 8 8;
+              }
+           }
+        }
+        part { name: "base";
+           scale: 1;
+           description { state: "default" 0.0;
+              rel1.offset: 4 4;
+              rel2.offset: -5 -5;
+              // FIXME 48x96 should be the native pixel design, right now
+              // its 80x160. fix int he artwork later
+              min: 24 48;
+               aspect: 0.5 0.5;
+//            max: 24 48;
+              image.normal: "flip_base.png";
+           }
+        }
+        part { name: "b";
+           type: RECT;
+           mouse_events: 1;
+           description { state: "default" 0.0;
+              visible: 0;
+              rel1.to: "base";
+              rel1.relative: 0.0 0.5;
+              rel2.to: "base";
+              color: 0 0 0 0;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+           }
+        }
+        part { name: "t";
+           type: RECT;
+           mouse_events: 1;
+           description { state: "default" 0.0;
+              visible: 0;
+              rel1.to: "base";
+              rel2.to: "base";
+              rel2.relative: 1.0 0.5;
+              color: 0 0 0 0;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+           }
+        }
+        part { name: "bot0";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "b";
+              rel2.to: "b";
+              image.normal: "flip_0b.png";
+           }
+           description { state: "0" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_0b.png";
+           }
+           description { state: "1" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_1b.png";
+           }
+           description { state: "2" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_2b.png";
+           }
+           description { state: "3" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_3b.png";
+           }
+           description { state: "4" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_4b.png";
+           }
+           description { state: "5" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_5b.png";
+           }
+           description { state: "6" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_6b.png";
+           }
+           description { state: "7" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_7b.png";
+           }
+           description { state: "8" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_8b.png";
+           }
+           description { state: "9" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_9b.png";
+           }
+        }
+        part { name: "sh";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "b";
+              rel2.to: "b";
+              rel2.relative: 1.0 0.0;
+              image.normal: "flip_shad.png";
+           }
+           description { state: "half" 0.0;
+              inherit: "default" 0.0;
+              rel2.relative: 1.0 0.5;
+           }
+           description { state: "full" 0.0;
+              inherit: "default" 0.0;
+              rel2.relative: 1.0 1.0;
+           }
+        }
+        part { name: "bot";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              visible: 1;
+              rel1.to: "b";
+              rel2.to: "b";
+              image.normal: "flip_0b.png";
+           }
+           description { state: "0" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel2.relative: 1.0 1.0;
+              image.normal: "flip_0b.png";
+           }
+           description { state: "0h" 0.0;
+              inherit: "default" 0.0;
+              visible: 0;
+              rel2.relative: 1.0 0.0;
+              image.normal: "flip_0b.png";
+           }
+           description { state: "1" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel2.relative: 1.0 1.0;
+              image.normal: "flip_1b.png";
+           }
+           description { state: "1h" 0.0;
+              inherit: "default" 0.0;
+              visible: 0;
+              rel2.relative: 1.0 0.0;
+              image.normal: "flip_1b.png";
+           }
+           description { state: "2" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel2.relative: 1.0 1.0;
+              image.normal: "flip_2b.png";
+           }
+           description { state: "2h" 0.0;
+              inherit: "default" 0.0;
+              visible: 0;
+              rel2.relative: 1.0 0.0;
+              image.normal: "flip_2b.png";
+           }
+           description { state: "3" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel2.relative: 1.0 1.0;
+              image.normal: "flip_3b.png";
+           }
+           description { state: "3h" 0.0;
+              inherit: "default" 0.0;
+              visible: 0;
+              rel2.relative: 1.0 0.0;
+              image.normal: "flip_3b.png";
+           }
+           description { state: "4" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel2.relative: 1.0 1.0;
+              image.normal: "flip_4b.png";
+           }
+           description { state: "4h" 0.0;
+              inherit: "default" 0.0;
+              visible: 0;
+              rel2.relative: 1.0 0.0;
+              image.normal: "flip_4b.png";
+           }
+           description { state: "5" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel2.relative: 1.0 1.0;
+              image.normal: "flip_5b.png";
+           }
+           description { state: "5h" 0.0;
+              inherit: "default" 0.0;
+              visible: 0;
+              rel2.relative: 1.0 0.0;
+              image.normal: "flip_5b.png";
+           }
+           description { state: "6" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel2.relative: 1.0 1.0;
+              image.normal: "flip_6b.png";
+           }
+           description { state: "6h" 0.0;
+              inherit: "default" 0.0;
+              visible: 0;
+              rel2.relative: 1.0 0.0;
+              image.normal: "flip_6b.png";
+           }
+           description { state: "7" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel2.relative: 1.0 1.0;
+              image.normal: "flip_7b.png";
+           }
+           description { state: "7h" 0.0;
+              inherit: "default" 0.0;
+              visible: 0;
+              rel2.relative: 1.0 0.0;
+              image.normal: "flip_7b.png";
+           }
+           description { state: "8" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel2.relative: 1.0 1.0;
+              image.normal: "flip_8b.png";
+           }
+           description { state: "8h" 0.0;
+              inherit: "default" 0.0;
+              visible: 0;
+              rel2.relative: 1.0 0.0;
+              image.normal: "flip_8b.png";
+           }
+           description { state: "9" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel2.relative: 1.0 1.0;
+              image.normal: "flip_9b.png";
+           }
+           description { state: "9h" 0.0;
+              inherit: "default" 0.0;
+              visible: 0;
+              rel2.relative: 1.0 0.0;
+              image.normal: "flip_9b.png";
+           }
+        }
+        part { name: "top0";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "t";
+              rel2.to: "t";
+              image.normal: "flip_0t.png";
+           }
+           description { state: "0" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_0t.png";
+           }
+           description { state: "1" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_1t.png";
+           }
+           description { state: "2" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_2t.png";
+           }
+           description { state: "3" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_3t.png";
+           }
+           description { state: "4" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_4t.png";
+           }
+           description { state: "5" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_5t.png";
+           }
+           description { state: "6" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_6t.png";
+           }
+           description { state: "7" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_7t.png";
+           }
+           description { state: "8" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_8t.png";
+           }
+           description { state: "9" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_9t.png";
+           }
+        }
+        part { name: "top";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              visible: 1;
+              rel1.to: "t";
+              rel2.to: "t";
+              image.normal: "flip_0t.png";
+           }
+           description { state: "0" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel1.relative: 0.0 0.0;
+              image.normal: "flip_0t.png";
+           }
+           description { state: "0h" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 255;
+              visible: 0;
+              rel1.relative: 0.0 1.0;
+              image.normal: "flip_0t.png";
+           }
+           description { state: "1" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel1.relative: 0.0 0.0;
+              image.normal: "flip_1t.png";
+           }
+           description { state: "1h" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 255;
+              visible: 0;
+              rel1.relative: 0.0 1.0;
+              image.normal: "flip_1t.png";
+           }
+           description { state: "2" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel1.relative: 0.0 0.0;
+              image.normal: "flip_2t.png";
+           }
+           description { state: "2h" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 255;
+              visible: 0;
+              rel1.relative: 0.0 1.0;
+              image.normal: "flip_2t.png";
+           }
+           description { state: "3" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel1.relative: 0.0 0.0;
+              image.normal: "flip_3t.png";
+           }
+           description { state: "3h" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 255;
+              visible: 0;
+              rel1.relative: 0.0 1.0;
+              image.normal: "flip_3t.png";
+           }
+           description { state: "4" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel1.relative: 0.0 0.0;
+              image.normal: "flip_4t.png";
+           }
+           description { state: "4h" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 255;
+              visible: 0;
+              rel1.relative: 0.0 1.0;
+              image.normal: "flip_4t.png";
+           }
+           description { state: "5" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel1.relative: 0.0 0.0;
+              image.normal: "flip_5t.png";
+           }
+           description { state: "5h" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 255;
+              visible: 0;
+              rel1.relative: 0.0 1.0;
+              image.normal: "flip_5t.png";
+           }
+           description { state: "6" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel1.relative: 0.0 0.0;
+              image.normal: "flip_6t.png";
+           }
+           description { state: "6h" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 255;
+              visible: 0;
+              rel1.relative: 0.0 1.0;
+              image.normal: "flip_6t.png";
+           }
+           description { state: "7" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel1.relative: 0.0 0.0;
+              image.normal: "flip_7t.png";
+           }
+           description { state: "7h" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 255;
+              visible: 0;
+              rel1.relative: 0.0 1.0;
+              image.normal: "flip_7t.png";
+           }
+           description { state: "8" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel1.relative: 0.0 0.0;
+              image.normal: "flip_8t.png";
+           }
+           description { state: "8h" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 255;
+              visible: 0;
+              rel1.relative: 0.0 1.0;
+              image.normal: "flip_8t.png";
+           }
+           description { state: "9" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel1.relative: 0.0 0.0;
+              image.normal: "flip_9t.png";
+           }
+           description { state: "9h" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 255;
+              visible: 0;
+              rel1.relative: 0.0 1.0;
+              image.normal: "flip_9t.png";
+           }
+        }
+        part { name: "atop";
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              visible: 0;
+              min: 15 15;
+              max: 15 15;
+              align: 0.5 0.0;
+              rel1.to: "t";
+              rel2.to: "t";
+              image.normal: "arrow_up.png";
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+           }
+        }
+        part { name: "abot";
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              visible: 0;
+              min: 15 15;
+              max: 15 15;
+              align: 0.5 1.0;
+              rel1.to: "b";
+              rel2.to: "b";
+              image.normal: "arrow_down.png";
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+           }
+        }
+      }
+      programs {
+        program { name: "load";
+           signal: "load";
+           source: "";
+           script {
+              set_int(v0_cur, 0);
+              set_int(v0_pre, 0);
+              set_int(v0_lock, 0);
+              set_int(v0_next, -1);
+           }
+        }
+        program { name: "edit_on";
+            signal: "elm,state,edit,on";
+           source: "elm";
+           action: STATE_SET "visible" 0.0;
+           target: "atop";
+           target: "abot";
+           target: "t";
+           target: "b";
+        }
+        program { name: "edit_off";
+            signal: "elm,state,edit,off";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "atop";
+           target: "abot";
+           target: "t";
+           target: "b";
+        }
+        program { name: "up";
+           signal: "mouse,down,1";
+           source: "t";
+           action: SIGNAL_EMIT "elm,action,up" "";
+        }
+        program { name: "down";
+           signal: "mouse,down,1";
+           source: "b";
+           action: SIGNAL_EMIT "elm,action,down" "";
+        }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/clock/flipampm/default";
+      images {
+         image: "flip_base.png" COMP;
+         image: "flip_base_shad.png" COMP;
+         image: "flip_shad.png" COMP;
+         image: "flip_amt.png" COMP;
+         image: "flip_amb.png" COMP;
+         image: "flip_pmt.png" COMP;
+         image: "flip_pmb.png" COMP;
+        image: "arrow_up.png" COMP;
+        image: "arrow_down.png" COMP;
+      }
+      script {
+        public v0_cur, v0_pre, v0_lock, v0_next;
+
+       public animator2(val, Float:pos) {
+         new st1[11], st2[11], v;
+
+         v = get_int(v0_cur);
+         snprintf(st1, 10, "%ih", v);
+         snprintf(st2, 10, "%i", v);
+         set_tween_state(PART:"bot", pos, st1, 0.0, st2, 0.0);
+         set_tween_state(PART:"sh", pos, "half", 0.0, "full", 0.0);
+         if (pos >= 1.0) {
+            set_state(PART:"sh", "default", 0.0);
+            set_int(v0_lock, 0);
+            v = get_int(v0_next);
+            if (v >= 0) {
+               set_int(v0_next, -1);
+               message(MSG_INT, 1, v);
+            }
+         }
+       }
+       public animator1(val, Float:pos) {
+         new st1[11], st2[11], v;
+
+         v = get_int(v0_pre);
+         snprintf(st1, 10, "%i", v);
+         snprintf(st2, 10, "%ih", v);
+         set_tween_state(PART:"top", pos, st1, 0.0, st2, 0.0);
+         set_tween_state(PART:"sh", pos, "default", 0.0, "half", 0.0);
+         if (pos >= 1.0) anim(0.2, "animator2", val);
+       }
+       public message(Msg_Type:type, id, ...) {
+         if ((type == MSG_INT) && (id == 1)) {
+            new value, v, buf[11];
+
+            value = getarg(2);
+            if (get_int(v0_lock) == 1) {
+               set_int(v0_next, value);
+               return;
+            }
+            v = get_int(v0_cur);
+            set_int(v0_pre, v);
+            set_int(v0_cur, value);
+            set_int(v0_lock, 1);
+            snprintf(buf, 10, "%i", get_int(v0_pre));
+            set_state(PART:"bot0", buf, 0.0);
+            snprintf(buf, 10, "%ih", get_int(v0_cur));
+            set_state(PART:"bot", buf, 0.0);
+            snprintf(buf, 10, "%i", get_int(v0_cur));
+            set_state(PART:"top0", buf, 0.0);
+            snprintf(buf, 10, "%i", get_int(v0_pre));
+            set_state(PART:"top", buf, 0.0);
+            set_state(PART:"sh", "default", 0.0);
+            anim(0.2, "animator1", 1);
+         }
+       }
+      }
+      parts {
+        part { name: "shad";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.offset: -4 -4;
+              rel1.to: "base";
+              rel2.offset: 3 3;
+              rel2.to: "base";
+              image {
+                  normal: "flip_base_shad.png";
+                 border: 8 8 8 8;
+              }
+           }
+        }
+        part { name: "base";
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              rel1.offset: 4 4;
+              rel2.offset: -5 -5;
+              // FIXME 48x96 should be the native pixel design, right now
+              // its 80x160. fix int he artwork later
+               aspect: 0.5 0.5;
+              min: 24 48;
+//            max: 24 48;
+              image.normal: "flip_base.png";
+           }
+        }
+        part { name: "b";
+           type: RECT;
+           mouse_events: 1;
+           description { state: "default" 0.0;
+              rel1.to: "base";
+              rel1.relative: 0.0 0.5;
+              rel2.to: "base";
+              color: 0 0 0 0;
+           }
+        }
+        part { name: "t";
+           type: RECT;
+           mouse_events: 1;
+           description { state: "default" 0.0;
+              rel1.to: "base";
+              rel2.to: "base";
+              rel2.relative: 1.0 0.5;
+              color: 0 0 0 0;
+           }
+        }
+        part { name: "bot0";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "b";
+              rel2.to: "b";
+              image.normal: "flip_amb.png";
+           }
+           description { state: "0" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_amb.png";
+           }
+           description { state: "1" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_pmb.png";
+           }
+        }
+        part { name: "sh";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "b";
+              rel2.to: "b";
+              rel2.relative: 1.0 0.0;
+              image.normal: "flip_shad.png";
+           }
+           description { state: "half" 0.0;
+              inherit: "default" 0.0;
+              rel2.relative: 1.0 0.5;
+           }
+           description { state: "full" 0.0;
+              inherit: "default" 0.0;
+              rel2.relative: 1.0 1.0;
+           }
+        }
+        part { name: "bot";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              visible: 1;
+              rel1.to: "b";
+              rel2.to: "b";
+              image.normal: "flip_amb.png";
+           }
+           description { state: "0" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel2.relative: 1.0 1.0;
+              image.normal: "flip_amb.png";
+           }
+           description { state: "0h" 0.0;
+              inherit: "default" 0.0;
+              visible: 0;
+              rel2.relative: 1.0 0.0;
+              image.normal: "flip_amb.png";
+           }
+           description { state: "1" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel2.relative: 1.0 1.0;
+              image.normal: "flip_pmb.png";
+           }
+           description { state: "1h" 0.0;
+              inherit: "default" 0.0;
+              visible: 0;
+              rel2.relative: 1.0 0.0;
+              image.normal: "flip_pmb.png";
+           }
+        }
+        part { name: "top0";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "t";
+              rel2.to: "t";
+              image.normal: "flip_amt.png";
+           }
+           description { state: "0" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_amt.png";
+           }
+           description { state: "1" 0.0;
+              inherit: "default" 0.0;
+              image.normal: "flip_pmt.png";
+           }
+        }
+        part { name: "top";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              visible: 1;
+              rel1.to: "t";
+              rel2.to: "t";
+              image.normal: "flip_amt.png";
+           }
+           description { state: "0" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel1.relative: 0.0 0.0;
+              image.normal: "flip_amt.png";
+           }
+           description { state: "0h" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 255;
+              visible: 0;
+              rel1.relative: 0.0 1.0;
+              image.normal: "flip_amt.png";
+           }
+           description { state: "1" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              rel1.relative: 0.0 0.0;
+              image.normal: "flip_pmt.png";
+           }
+           description { state: "1h" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 255;
+              visible: 0;
+              rel1.relative: 0.0 1.0;
+              image.normal: "flip_pmt.png";
+           }
+        }
+        part { name: "atop";
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              visible: 0;
+              min: 15 15;
+              max: 15 15;
+              align: 0.5 0.0;
+              rel1.to: "t";
+              rel2.to: "t";
+              image.normal: "arrow_up.png";
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+           }
+        }
+        part { name: "abot";
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              visible: 0;
+              min: 15 15;
+              max: 15 15;
+              align: 0.5 1.0;
+              rel1.to: "b";
+              rel2.to: "b";
+              image.normal: "arrow_down.png";
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+           }
+        }
+      }
+      programs {
+        program { name: "load";
+           signal: "load";
+           source: "";
+           script {
+              set_int(v0_cur, 0);
+              set_int(v0_pre, 0);
+              set_int(v0_lock, 0);
+              set_int(v0_next, -1);
+           }
+        }
+        program { name: "edit_on";
+            signal: "elm,state,edit,on";
+           source: "elm";
+           action: STATE_SET "visible" 0.0;
+           target: "atop";
+           target: "abot";
+        }
+/*
+        program { name: "edit_off";
+            signal: "elm,state,edit,off";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "atop";
+           target: "abot";
+        }
+ */
+        program { name: "up";
+           signal: "mouse,down,1";
+           source: "t";
+           action: SIGNAL_EMIT "elm,action,up" "";
+        }
+        program { name: "down";
+           signal: "mouse,down,1";
+           source: "b";
+           action: SIGNAL_EMIT "elm,action,down" "";
+        }
+      }
+   }
+
+   ///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/menu/item/default";
+       images {
+           image: "bt_base1.png" COMP;
+           image: "bt_base2.png" COMP;
+           image: "bt_hilight.png" COMP;
+           image: "bt_shine.png" COMP;
+           image: "bt_glow.png" COMP;
+           image: "bt_dis_base.png" COMP;
+           image: "bt_dis_hilight.png" COMP;
+       }
+       script {
+            public menu_text_visible; //0:hide (default), 1:visible
+            public menu_disable; //0:enable, 1:disable
+       }
+       parts {
+           part { name: "item_image";
+               mouse_events: 1;
+               description { state: "default" 0.0;
+                   color: 255 255 255 0;
+                   image {
+                       normal: "bt_base2.png";
+                       border: 7 7 7 7;
+                   }
+                   image.middle: SOLID;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+                   color: 255 255 255 255;
+               }
+               description { state: "clicked" 0.0;
+                   inherit: "default" 0.0;
+                   inherit: "visible" 0.0;
+                   image.normal: "bt_base1.png";
+                   image.middle: SOLID;
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+               }
+           }
+           part { name: "item_image_disabled";
+               mouse_events: 1;
+               description { state: "default" 0.0;
+                   color: 255 255 255 0;
+                   image {
+                       normal: "bt_dis_base.png";
+                       border: 4 4 4 4;
+                   }
+                   image.middle: SOLID;
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   fixed: 1 0;
+                   visible: 1;
+                   align: 0.0 0.5;
+                   rel1.offset: 4 4;
+                   rel2.offset: 3 -5;
+                   rel2.relative: 0.0 1.0;
+                   aspect: 1.0 1.0;
+                   aspect_preference: VERTICAL;
+                   rel2.offset: 4 -5;
+               }
+           }
+           part {
+               name:          "elm.text";
+               type:          TEXT;
+               mouse_events:  0;
+               scale: 1;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   rel1.to_x: "elm.swallow.content";
+                   rel1.relative: 1.0 0.0;
+                   rel1.offset: 5 7;
+                   rel2.offset: -10 -8;
+                   color: 0 0 0 255;
+                   text {
+                       font:     "Sans,Edje-Vera";
+                       size:     10;
+                       min:      1 1;
+                       align:    0.0 0.5;
+                   }
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   text.min: 1 1;
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   inherit: "visible" 0.0;
+                   color: 254 254 254 255;
+               }
+               description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 128;
+               }
+               description { state: "disabled_visible" 0.0;
+                   inherit: "default" 0.0;
+                   inherit: "visible" 0.0;
+                   color: 0 0 0 128;
+               }
+           }
+           part {        name: "over1";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   color: 255 255 255 0;
+                   rel2.relative: 1.0 0.5;
+                   image {
+                       normal: "bt_hilight.png";
+                       border: 7 7 7 0;
+                   }
+               }
+               description { state: "visible" 0.0;
+                   inherit:  "default" 0.0;
+                   color: 255 255 255 255;
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+               }
+           }
+           part {        name: "over_disabled";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   color: 255 255 255 0;
+                   rel2.relative: 1.0 0.5;
+                   image {
+                       normal: "bt_dis_hilight.png";
+                       border: 4 4 4 0;
+                   }
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "over2";
+               mouse_events: 1;
+               repeat_events: 1;
+               ignore_flags: ON_HOLD;
+               description { state: "default" 0.0;
+                   image {
+                       normal: "bt_shine.png";
+                       border: 7 7 7 7;
+                   }
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+                   visible: 0;
+               }
+           }
+           part { name: "over3";
+               mouse_events: 1;
+               repeat_events: 1;
+               description { state: "default" 0.0;
+                   color: 255 255 255 0;
+                   image {
+                       normal: "bt_glow.png";
+                       border: 12 12 12 12;
+                   }
+                   fill.smooth : 0;
+               }
+               description { state: "clicked" 0.0;
+                   inherit:  "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "disabler";
+               type: RECT;
+               description { state: "default" 0.0;
+                   color: 0 0 0 0;
+                   visible: 0;
+               }
+               description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+               }
+           }
+       }
+       programs {
+          //
+           program {
+               name:   "item_mouse_in";
+               signal: "mouse,in";
+               source: "over2";
+               action: SIGNAL_EMIT "elm,action,activate" "";
+               after: "item_mouse_in_2";
+               after: "item_mouse_in_3";
+           }
+           program {
+               name:   "item_mouse_in_2";
+               transition: DECELERATE 0.5;
+               script {
+                   new v, d;
+                   v = get_int(menu_text_visible);
+                   d = get_int(menu_disable);
+
+                   if (v==1 && d==0)
+                        run_program(PROGRAM:"selected_text");
+               }
+           }
+           program {
+               name:   "item_mouse_in_3";
+               action : STATE_SET "visible" 0.0;
+               target: "item_image";
+               target: "over1";
+               transition: DECELERATE 0.5;
+           }
+           program {
+               name:   "selected_text";
+               action: STATE_SET "selected" 0.0;
+               target: "elm.text";
+               transition: DECELERATE 0.5;
+           }
+           //
+
+           //
+           program {
+               name:   "item_mouse_out";
+               signal: "mouse,out";
+               source: "over2";
+               after: "item_mouse_out_2";
+               after: "item_mouse_out_3";
+           }
+           program {
+               name:   "item_mouse_out_2";
+               transition: DECELERATE 0.5;
+               script {
+                   new v, d;
+                   v = get_int(menu_text_visible);
+                   d = get_int(menu_disable);
+
+                   if (v==1 && d==0)
+                        run_program(PROGRAM:"visible_text");
+               }
+           }
+           program {
+               name:   "item_mouse_out_3";
+               action: STATE_SET "default" 0.0;
+               target: "item_image";
+               target: "over1";
+               transition: DECELERATE 0.5;
+           }
+           program {
+               name:   "visible_text";
+               action: STATE_SET "visible" 0.0;
+               target: "elm.text";
+               transition: DECELERATE 0.5;
+           }
+           //
+
+           program {
+               name:   "item_unclick";
+               signal: "mouse,up,1";
+               source: "over2";
+               action: STATE_SET "visible" 0.0;
+               target: "item_image";
+           }
+           program {
+               name:   "item_click2";
+               signal: "mouse,down,1";
+               source: "over3";
+               action: STATE_SET "clicked" 0.0;
+               target: "over3";
+           }
+           program {
+               name:   "item_unclick2";
+               signal: "mouse,up,1";
+               source: "over3";
+               action: STATE_SET "default" 0.0;
+               transition: DECELERATE 0.5;
+               target: "over3";
+           }
+           program {
+               name:   "item_unclick3";
+               signal: "mouse,up,1";
+               source: "over2";
+               action: SIGNAL_EMIT "elm,action,click" "";
+           }
+           program { name: "text_show";
+               signal: "elm,state,text,visible";
+               source: "elm";
+               script {
+                   set_int(menu_text_visible, 1);
+                   set_state(PART:"elm.text", "visible", 0.0);
+               }
+           }
+           program { name: "text_hide";
+               signal: "elm,state,text,hidden";
+               source: "elm";
+               script {
+                   set_int(menu_text_visible, 0);
+                   set_state(PART:"elm.text", "default", 0.0);
+               }
+           }
+           program { name: "disable";
+               signal: "elm,state,disabled";
+               source: "elm";
+               action: STATE_SET "disabled" 0.0;
+               target: "item_image";
+               target: "item_image_disabled";
+               target: "over1";
+               target: "over2";
+               target: "over_disabled";
+               target: "disabler";
+               after: "disable_text";
+           }
+           program { name: "disable_text";
+               script {
+                   new v;
+                   v = get_int(menu_text_visible);
+                   if (v==1)
+                    set_state(PART:"elm.text", "disabled_visible", 0.0);
+                   else if (v==0)
+                    set_state(PART:"elm.text", "disabled", 0.0);
+                   set_int(menu_disable, 1);
+               }
+           }
+           program { name: "enable";
+               signal: "elm,state,enabled";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "item_image";
+               target: "item_image_disabled";
+               target: "over1";
+               target: "over2";
+               target: "over_disabled";
+               target: "disabler";
+               after: "enable_text";
+           }
+           program { name: "enable_text";
+               script {
+                   new v;
+                   v = get_int(menu_text_visible);
+                   if (v==1)
+                    set_state(PART:"elm.text", "visible", 0.0);
+                   else  if (v==0)
+                    set_state(PART:"elm.text", "default", 0.0);
+                   set_int(menu_disable, 0);
+               }
+           }
+       }
+   }
+
+   group { name: "elm/menu/item_with_submenu/default";
+       images {
+           image: "bt_base1.png" COMP;
+           image: "bt_base2.png" COMP;
+           image: "bt_hilight.png" COMP;
+           image: "bt_shine.png" COMP;
+           image: "bt_glow.png" COMP;
+           image: "bt_dis_base.png" COMP;
+           image: "bt_dis_hilight.png" COMP;
+           image: "arrow_right.png" COMP;
+       }
+       script {
+            public menu_text_visible; //0:hide (default), 1:visible
+            public menu_disable; //0:enable, 1:disable
+       }
+       parts {
+           part { name: "item_image";
+               mouse_events: 1;
+               description { state: "default" 0.0;
+                   color: 255 255 255 0;
+                   image {
+                       normal: "bt_base2.png";
+                       border: 7 7 7 7;
+                   }
+                   image.middle: SOLID;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+                   color: 255 255 255 255;
+               }
+               description { state: "clicked" 0.0;
+                   inherit: "default" 0.0;
+                   inherit: "visible" 0.0;
+                   image.normal: "bt_base1.png";
+                   image.middle: SOLID;
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+               }
+           }
+           part { name: "item_image_disabled";
+               mouse_events: 1;
+               description { state: "default" 0.0;
+                   color: 255 255 255 0;
+                   image {
+                       normal: "bt_dis_base.png";
+                       border: 4 4 4 4;
+                   }
+                   image.middle: SOLID;
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "arrow";
+               mouse_events: 1;
+               description { state: "default" 0.0;
+                   color: 255 255 255 255;
+                   align: 1.0 0.5;
+                   aspect: 1 1;
+                   aspect_preference: BOTH;
+                   image {
+                       normal: "arrow_right.png";
+                   }
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   fixed: 1 0;
+                   visible: 1;
+                   align: 0.0 0.5;
+                   rel1.offset: 4 4;
+                   rel2.offset: 3 -5;
+                   rel2.relative: 0.0 1.0;
+                   aspect: 1.0 1.0;
+                   aspect_preference: VERTICAL;
+                   rel2.offset: 4 -5;
+               }
+           }
+           part {
+               name:          "elm.text";
+               type:          TEXT;
+               mouse_events:  0;
+               scale: 1;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   rel1.to_x: "elm.swallow.content";
+                   rel1.relative: 1.0 0.0;
+                   rel1.offset: 5 7;
+                   rel2.offset: -10 -8;
+                   color: 0 0 0 255;
+                   text {
+                       font:     "Sans,Edje-Vera";
+                       size:     10;
+                       min:      1 1;
+                       align:    0.0 0.5;
+                   }
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   text.min: 1 1;
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   inherit: "visible" 0.0;
+                   color: 254 254 254 255;
+               }
+               description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 128;
+               }
+               description { state: "disabled_visible" 0.0;
+                   inherit: "default" 0.0;
+                   inherit: "visible" 0.0;
+                   color: 0 0 0 128;
+               }
+           }
+           part {        name: "over1";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   color: 255 255 255 0;
+                   rel2.relative: 1.0 0.5;
+                   image {
+                       normal: "bt_hilight.png";
+                       border: 7 7 7 0;
+                   }
+               }
+               description { state: "visible" 0.0;
+                   inherit:  "default" 0.0;
+                   color: 255 255 255 255;
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+               }
+           }
+           part { name: "over_disabled";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   color: 255 255 255 0;
+                   rel2.relative: 1.0 0.5;
+                   image {
+                       normal: "bt_dis_hilight.png";
+                       border: 4 4 4 0;
+                   }
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "over2";
+               mouse_events: 1;
+               repeat_events: 1;
+               ignore_flags: ON_HOLD;
+               description { state: "default" 0.0;
+                   image {
+                       normal: "bt_shine.png";
+                       border: 7 7 7 7;
+                   }
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+                   visible: 0;
+               }
+           }
+           part { name: "over3";
+               mouse_events: 1;
+               repeat_events: 1;
+               description { state: "default" 0.0;
+                   color: 255 255 255 0;
+                   image {
+                       normal: "bt_glow.png";
+                       border: 12 12 12 12;
+                   }
+                   fill.smooth : 0;
+               }
+               description { state: "clicked" 0.0;
+                   inherit:  "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "disabler";
+               type: RECT;
+               description { state: "default" 0.0;
+                   color: 0 0 0 0;
+                   visible: 0;
+               }
+               description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+               }
+           }
+       }
+       programs {
+           //
+           program {
+               name:   "item_mouse_in";
+               signal: "mouse,in";
+               source: "over2";
+               action: SIGNAL_EMIT "elm,action,activate" "";
+               after: "item_mouse_in_2";
+               after: "item_mouse_in_3";
+           }
+           program {
+               name:   "item_mouse_in_2";
+               transition: DECELERATE 0.5;
+               script {
+                   new v, d;
+                   v = get_int(menu_text_visible);
+                   d = get_int(menu_disable);
+
+                   if (v==1 && d==0)
+                        run_program(PROGRAM:"selected_text");
+               }
+           }
+           program {
+               name:   "item_mouse_in_3";
+               action : STATE_SET "visible" 0.0;
+               target: "item_image";
+               target: "over1";
+               transition: DECELERATE 0.5;
+           }
+           program {
+               name:   "selected_text";
+               action: STATE_SET "selected" 0.0;
+               target: "elm.text";
+               transition: DECELERATE 0.5;
+           }
+           //
+
+           //
+           program {
+               name:   "item_mouse_out";
+               signal: "mouse,out";
+               source: "over2";
+               after: "item_mouse_out_2";
+               after: "item_mouse_out_3";
+           }
+           program {
+               name:   "item_mouse_out_2";
+               transition: DECELERATE 0.5;
+               script {
+                   new v, d;
+                   v = get_int(menu_text_visible);
+                   d = get_int(menu_disable);
+
+                   if (v==1 && d==0)
+                        run_program(PROGRAM:"visible_text");
+               }
+           }
+           program {
+               name:   "item_mouse_out_3";
+               action: STATE_SET "default" 0.0;
+               target: "item_image";
+               target: "over1";
+               transition: DECELERATE 0.5;
+           }
+           program {
+               name:   "visible_text";
+               action: STATE_SET "visible" 0.0;
+               target: "elm.text";
+               transition: DECELERATE 0.5;
+           }
+           //
+
+           program {
+               name:   "item_unclick";
+               signal: "mouse,up,1";
+               source: "over2";
+               action: STATE_SET "visible" 0.0;
+               target: "item_image";
+           }
+           program {
+               name:   "item_click2";
+               signal: "mouse,down,1";
+               source: "over3";
+               action: STATE_SET "clicked" 0.0;
+               target: "over3";
+           }
+           program {
+               name:   "item_unclick2";
+               signal: "mouse,up,1";
+               source: "over3";
+               action: STATE_SET "default" 0.0;
+               transition: DECELERATE 0.5;
+               target: "over3";
+           }
+           program {
+               name:   "item_unclick3";
+               signal: "mouse,up,1";
+               source: "over2";
+               action: SIGNAL_EMIT "elm,action,click" "";
+           }
+           program {
+               name:   "menu_open";
+               signal: "mouse,in";
+               source: "over2";
+               action: SIGNAL_EMIT "elm,action,open" "";
+           }
+            program { name: "text_show";
+               signal: "elm,state,text,visible";
+               source: "elm";
+               script {
+                   set_int(menu_text_visible, 1);
+                   set_state(PART:"elm.text", "visible", 0.0);
+               }
+           }
+           program { name: "text_hide";
+               signal: "elm,state,text,hidden";
+               source: "elm";
+               script {
+                   set_int(menu_text_visible, 0);
+                   set_state(PART:"elm.text", "default", 0.0);
+               }
+           }
+           program { name: "disable";
+               signal: "elm,state,disabled";
+               source: "elm";
+               action: STATE_SET "disabled" 0.0;
+               target: "item_image";
+               target: "item_image_disabled";
+               target: "over1";
+               target: "over2";
+               target: "over_disabled";
+               target: "disabler";
+               after: "disable_text";
+           }
+           program { name: "disable_text";
+               script {
+                   new st[31];
+                   new Float:vl;
+                   get_state(PART:"elm.text", st, 30, vl);
+                   if (!strcmp(st, "visible"))
+                   set_state(PART:"elm.text", "disabled_visible", 0.0);
+                   else if (!strcmp(st, "default"))
+                   set_state(PART:"elm.text", "disabled", 0.0);
+               }
+           }
+           program { name: "enable";
+               signal: "elm,state,enabled";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "item_image";
+               target: "item_image_disabled";
+               target: "over1";
+               target: "over2";
+               target: "over_disabled";
+               target: "disabler";
+               after: "enable_text";
+           }
+           program { name: "enable_text";
+               script {
+                   new v;
+                   v = get_int(menu_text_visible);
+                   if (v==1)
+                    set_state(PART:"elm.text", "visible", 0.0);
+                   else  if (v==0)
+                    set_state(PART:"elm.text", "default", 0.0);
+                   set_int(menu_disable, 0);
+               }
+           }
+       }
+   }
+
+   group { name: "elm/menu/separator/default";
+       images {
+           image: "separator_h.png" COMP;
+       }
+       parts {
+           part { name: "separator"; // separator group
+               description { state: "default" 0.0;
+                   min: 2 2;
+                   rel1.offset: 4 4;
+                   rel2.offset: -5 -5;
+                   image {
+                       normal: "separator_h.png";
+                   }
+                   fill {
+                       smooth: 0;
+                   }
+               }
+           }
+       }
+   }
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/clock/base-all/default";
+      parts {
+        part { name: "d0";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.0000000 0.0;
+              rel2.relative: 0.1250000 1.0;
+           }
+        }
+        part { name: "d1";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.1250000 0.0;
+              rel2.relative: 0.2500000 1.0;
+           }
+        }
+        part { name: "c0";
+           type: SWALLOW;
+           type: TEXT;
+           mouse_events:  0;
+           scale: 1;
+           description { state: "default" 0.0;
+              rel1.relative: 0.2500000 0.0;
+              rel2.relative: 0.3125000 1.0;
+              color: 0 0 0 255;
+              text {
+                 font:     "Sans,Edje-Vera";
+                 text:     ":";
+                 size:     10;
+                 min:      1 1;
+                 align:    0.5 0.5;
+              }
+           }
+        }
+        part { name: "d2";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.3125000 0.0;
+              rel2.relative: 0.4375000 1.0;
+           }
+        }
+        part { name: "d3";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.4375000 0.0;
+              rel2.relative: 0.5625000 1.0;
+           }
+        }
+        // (if seconds)
+        part { name: "c1";
+           type: SWALLOW;
+           type: TEXT;
+           mouse_events:  0;
+           scale: 1;
+           description { state: "default" 0.0;
+              rel1.relative: 0.5625000 0.0;
+              rel2.relative: 0.6250000 1.0;
+              color: 0 0 0 255;
+              text {
+                 font:     "Sans,Edje-Vera";
+                 text:     ":";
+                 size:     10;
+                 min:      1 1;
+                 align:    0.5 0.5;
+              }
+           }
+        }
+        // (if seconds)
+        part { name: "d4";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.6250000 0.0;
+              rel2.relative: 0.7500000 1.0;
+           }
+        }
+        // (if seconds)
+        part { name: "d5";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.7500000 0.0;
+              rel2.relative: 0.8750000 1.0;
+           }
+        }
+        // (if am_pm)
+        part { name: "ampm";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.8750000 0.0;
+              rel2.relative: 1.0 1.0;
+           }
+        }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/clock/base-seconds/default";
+      parts {
+        part { name: "d0";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.000000000 0.0;
+              rel2.relative: 0.142857143 1.0;
+           }
+        }
+        part { name: "d1";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.142857143 0.0;
+              rel2.relative: 0.285714286 1.0;
+           }
+        }
+        part { name: "c0";
+           type: SWALLOW;
+           type: TEXT;
+           mouse_events:  0;
+           scale: 1;
+           description { state: "default" 0.0;
+              rel1.relative: 0.285714286 0.0;
+              rel2.relative: 0.357142857 1.0;
+              color: 0 0 0 255;
+              text {
+                 font:     "Sans,Edje-Vera";
+                 text:     ":";
+                 size:     10;
+                 min:      1 1;
+                 align:    0.5 0.5;
+              }
+           }
+        }
+        part { name: "d2";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.357142857 0.0;
+              rel2.relative: 0.500000000 1.0;
+           }
+        }
+        part { name: "d3";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.500000000 0.0;
+              rel2.relative: 0.642857143 1.0;
+           }
+        }
+        // (if seconds)
+        part { name: "c1";
+           type: SWALLOW;
+           type: TEXT;
+           mouse_events:  0;
+           scale: 1;
+           description { state: "default" 0.0;
+              rel1.relative: 0.642857143 0.0;
+              rel2.relative: 0.714285714 1.0;
+              color: 0 0 0 255;
+              text {
+                 font:     "Sans,Edje-Vera";
+                 text:     ":";
+                 size:     10;
+                 min:      1 1;
+                 align:    0.5 0.5;
+              }
+           }
+        }
+        // (if seconds)
+        part { name: "d4";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.714285714 0.0;
+              rel2.relative: 0.857142857 1.0;
+           }
+        }
+        // (if seconds)
+        part { name: "d5";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.857142857 0.0;
+              rel2.relative: 1.000000000 1.0;
+           }
+        }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/clock/base-am_pm/default";
+      parts {
+        part { name: "d0";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.000000000 0.0;
+              rel2.relative: 0.181818182 1.0;
+           }
+        }
+        part { name: "d1";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.181818182 0.0;
+              rel2.relative: 0.363636364 1.0;
+           }
+        }
+        part { name: "c0";
+           type: SWALLOW;
+           type: TEXT;
+           mouse_events:  0;
+           scale: 1;
+           description { state: "default" 0.0;
+              rel1.relative: 0.363636364 0.0;
+              rel2.relative: 0.454545455 1.0;
+              color: 0 0 0 255;
+              text {
+                 font:     "Sans,Edje-Vera";
+                 text:     ":";
+                 size:     10;
+                 min:      1 1;
+                 align:    0.5 0.5;
+              }
+           }
+        }
+        part { name: "d2";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.454545455 0.0;
+              rel2.relative: 0.636363636 1.0;
+           }
+        }
+        part { name: "d3";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.636363636 0.0;
+              rel2.relative: 0.818181818 1.0;
+           }
+        }
+        // (if am_pm)
+        part { name: "ampm";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.818181818 0.0;
+              rel2.relative: 1.0 1.0;
+           }
+        }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/clock/base/default";
+      parts {
+        part { name: "d0";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.000000000 0.0;
+              rel2.relative: 0.222222222 1.0;
+           }
+        }
+        part { name: "d1";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.222222222 0.0;
+              rel2.relative: 0.444444444 1.0;
+           }
+        }
+        part { name: "c0";
+           type: SWALLOW;
+           type: TEXT;
+           mouse_events:  0;
+           scale: 1;
+           description { state: "default" 0.0;
+              rel1.relative: 0.444444444 0.0;
+              rel2.relative: 0.555555556 1.0;
+              color: 0 0 0 255;
+              text {
+                 font:     "Sans,Edje-Vera";
+                 text:     ":";
+                 size:     10;
+                 min:      1 1;
+                 align:    0.5 0.5;
+              }
+           }
+        }
+        part { name: "d2";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.555555556 0.0;
+              rel2.relative: 0.777777778 1.0;
+           }
+        }
+        part { name: "d3";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.relative: 0.777777778 0.0;
+              rel2.relative: 1.000000000 1.0;
+           }
+        }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/frame/base/default";
+       images {
+           image: "frame_1.png" COMP;
+           image: "frame_2.png" COMP;
+           image: "dia_grad.png" COMP;
+       }
+       parts {
+           part { name: "base0";
+               mouse_events:  0;
+               description { state: "default" 0.0;
+                   image.normal: "dia_grad.png";
+                   rel1.to: "over";
+                   rel2.to: "over";
+                   fill {
+                       smooth: 0;
+                       size {
+                           relative: 0.0 1.0;
+                           offset: 64 0;
+                       }
+                   }
+               }
+           }
+           part { name: "base";
+               mouse_events:  0;
+               description { state:    "default" 0.0;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 9 9;
+                   image {
+                       normal: "frame_2.png";
+                       border: 5 5 32 26;
+                       middle: 0;
+                   }
+                   fill.smooth : 0;
+               }
+           }
+           part { name: "elm.text";
+               type: TEXT;
+               mouse_events:   0;
+               scale: 1;
+               description { state: "default" 0.0;
+                   align: 0.0 0.0;
+                   fixed: 0 1;
+                   rel1 {
+                       relative: 0.0 0.0;
+                       offset: 6 6;
+                   }
+                   rel2 {
+                       relative: 1.0 0.0;
+                       offset: -7 6;
+                   }
+                   color: 0 0 0 64;
+                   text {
+                       font: "Sans:style=Bold,Edje-Vera-Bold";
+                       size: 10;
+                       min: 1 1;
+                       max: 1 1;
+                       align: 0.0 0.0;
+                   }
+               }
+           }
+           part { name: "over";
+               mouse_events:  0;
+               description { state:    "default" 0.0;
+                   rel1.offset: 4 4;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 5 5;
+                   image {
+                       normal: "frame_1.png";
+                       border: 2 2 28 22;
+                       middle: 0;
+                   }
+                   fill.smooth : 0;
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   align: 0.0 0.0;
+                   rel1 {
+                       to_y: "elm.text";
+                       relative: 0.0 1.0;
+                       offset: 8 2;
+                   }
+                   rel2.offset: -9 -9;
+               }
+           }
+       }
+   }
+
+   group { name: "elm/frame/base/pad_small";
+       parts {
+           part { name: "b0";
+               mouse_events:  0;
+               type: RECT;
+               scale: 1;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   min: 4 4;
+                   max: 4 4;
+                   align: 0.0 0.0;
+               }
+           }
+           part { name: "b1";
+               mouse_events:  0;
+               type: RECT;
+               scale: 1;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   min: 4 4;
+                   max: 4 4;
+                   align: 1.0 1.0;
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   rel1 {
+                       to: "b0";
+                       relative: 1.0 1.0;
+                       offset: 0 0;
+                   }
+                   rel2 {
+                       to: "b1";
+                       relative: 0.0 0.0;
+                       offset: -1 -1;
+                   }
+               }
+           }
+       }
+   }
+
+   group { name: "elm/frame/base/pad_medium";
+       parts {
+           part { name: "b0";
+               mouse_events:  0;
+               type: RECT;
+               scale: 1;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   min: 8 8;
+                   max: 8 8;
+                   align: 0.0 0.0;
+               }
+           }
+           part { name: "b1";
+               mouse_events:  0;
+               type: RECT;
+               scale: 1;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   min: 8 8;
+                   max: 8 8;
+                   align: 1.0 1.0;
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   rel1 {
+                       to: "b0";
+                       relative: 1.0 1.0;
+                       offset: 0 0;
+                   }
+                   rel2 {
+                       to: "b1";
+                       relative: 0.0 0.0;
+                       offset: -1 -1;
+                   }
+               }
+           }
+       }
+   }
+
+   group { name: "elm/frame/base/pad_large";
+       parts {
+           part { name: "b0";
+               mouse_events:  0;
+               type: RECT;
+               scale: 1;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   min: 16 16;
+                   max: 16 16;
+                   align: 0.0 0.0;
+               }
+           }
+           part { name: "b1";
+               mouse_events:  0;
+               type: RECT;
+               scale: 1;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   min: 16 16;
+                   max: 16 16;
+                   align: 1.0 1.0;
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   rel1 {
+                       to: "b0";
+                       relative: 1.0 1.0;
+                       offset: 0 0;
+                   }
+                   rel2 {
+                       to: "b1";
+                       relative: 0.0 0.0;
+                       offset: -1 -1;
+                   }
+               }
+           }
+       }
+   }
+
+   group { name: "elm/frame/base/pad_huge";
+       parts {
+           part { name: "b0";
+               mouse_events:  0;
+               type: RECT;
+               scale: 1;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   min: 32 32;
+                   max: 32 32;
+                   align: 0.0 0.0;
+               }
+           }
+           part { name: "b1";
+               mouse_events:  0;
+               type: RECT;
+               scale: 1;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   min: 32 32;
+                   max: 32 32;
+                   align: 1.0 1.0;
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   rel1 {
+                       to: "b0";
+                       relative: 1.0 1.0;
+                       offset: 0 0;
+                   }
+                   rel2 {
+                       to: "b1";
+                       relative: 0.0 0.0;
+                       offset: -1 -1;
+                   }
+               }
+           }
+       }
+   }
+
+   group { name: "elm/frame/base/outdent_top";
+       images {
+           image: "outdent-top.png" COMP;
+       }
+       parts {
+           part { name: "base0";
+               mouse_events:  0;
+               description { state: "default" 0.0;
+                   image.normal: "outdent-top.png";
+                   image.border: 0 0 0 13;
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   rel1.offset: 2 2;
+                   rel2.offset: -3 -13;
+               }
+           }
+       }
+   }
+
+   group { name: "elm/frame/base/outdent_bottom";
+       images {
+           image: "outdent-bottom.png" COMP;
+       }
+       parts {
+           part { name: "base0";
+               mouse_events:  0;
+               description { state: "default" 0.0;
+                   image.normal: "outdent-bottom.png";
+                   image.border: 0 0 13 0;
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   rel1.offset: 2 12;
+                   rel2.offset: -3 -3;
+               }
+           }
+       }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/hover/base/default";
+      images {
+        image: "shad_circ.png" COMP;
+      }
+      parts {
+        part { name: "elm.swallow.offset";
+            type: SWALLOW;
+           description { state: "default" 0.0;
+              align: 0.0 0.0;
+              rel1.relative: 0.0 0.0;
+              rel2.relative: 0.0 0.0;
+           }
+        }
+        part { name: "elm.swallow.size";
+            type: SWALLOW;
+           description { state: "default" 0.0;
+              align: 0.0 0.0;
+              rel1.to: "elm.swallow.offset";
+              rel1.relative: 1.0 1.0;
+              rel2.to: "elm.swallow.offset";
+              rel2.relative: 1.0 1.0;
+           }
+        }
+        part { name: "base";
+           type: RECT;
+           mouse_events: 1;
+           description { state: "default" 0.0;
+              color: 0 0 0 64;
+           }
+        }
+         part { name: "shad";
+           mouse_events:  0;
+           description { state: "default" 0.0;
+              image.normal: "shad_circ.png";
+              rel1.to: "elm.swallow.size";
+              rel1.offset: -32 -32;
+              rel2.to: "elm.swallow.size";
+              rel2.offset: 31 31;
+               fill.smooth: 0;
+           }
+        }
+        part { name: "box";
+           type: RECT;
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              color: 0 0 0 0;
+              rel1.to: "elm.swallow.size";
+              rel1.offset: -2 -2;
+              rel2.to: "elm.swallow.size";
+              rel2.offset: 1 1;
+           }
+        }
+        part { name: "elm.swallow.slot.left";
+            type: SWALLOW;
+           description { state: "default" 0.0;
+              align: 1.0 0.5;
+              rel1.to: "elm.swallow.slot.middle";
+              rel1.relative: 0.0 0.0;
+              rel1.offset: -1 0;
+              rel2.to: "elm.swallow.slot.middle";
+              rel2.relative: 0.0 1.0;
+              rel2.offset: -1 -1;
+           }
+        }
+        part { name: "elm.swallow.slot.right";
+            type: SWALLOW;
+           description { state: "default" 0.0;
+              align: 0.0 0.5;
+              rel1.to: "elm.swallow.slot.middle";
+              rel1.relative: 1.0 0.0;
+              rel1.offset: 0 0;
+              rel2.to: "elm.swallow.slot.middle";
+              rel2.relative: 1.0 1.0;
+              rel2.offset: 0 -1;
+           }
+        }
+        part { name: "elm.swallow.slot.top";
+            type: SWALLOW;
+           description { state: "default" 0.0;
+              align: 0.5 1.0;
+              rel1.to: "elm.swallow.slot.middle";
+              rel1.relative: 0.0 0.0;
+              rel1.offset: 0 -1;
+              rel2.to: "elm.swallow.slot.middle";
+              rel2.relative: 1.0 0.0;
+              rel2.offset: -1 -1;
+           }
+        }
+        part { name: "elm.swallow.slot.bottom";
+            type: SWALLOW;
+           description { state: "default" 0.0;
+              align: 0.5 0.0;
+              rel1.to: "elm.swallow.slot.middle";
+              rel1.relative: 0.0 1.0;
+              rel1.offset: 0 0;
+              rel2.to: "elm.swallow.slot.middle";
+              rel2.relative: 1.0 1.0;
+              rel2.offset: -1 0;
+           }
+        }
+        part { name: "elm.swallow.slot.middle";
+            type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.to: "elm.swallow.size";
+              rel2.to: "elm.swallow.size";
+           }
+        }
+      }
+      programs {
+        program { name: "end";
+           signal: "mouse,up,1";
+           source: "base";
+           action: SIGNAL_EMIT "elm,action,dismiss" "";
+        }
+      }
+   }
+
+   group { name: "elm/hover/base/popout";
+      images {
+        image: "shad_circ.png" COMP;
+        image: "bt_dis_base.png" COMP;
+        image: "bt_dis_hilight.png" COMP;
+      }
+      parts {
+        part { name: "elm.swallow.offset";
+            type: SWALLOW;
+           description { state: "default" 0.0;
+              align: 0.0 0.0;
+              rel1.relative: 0.0 0.0;
+              rel2.relative: 0.0 0.0;
+           }
+        }
+        part { name: "elm.swallow.size";
+            type: SWALLOW;
+           description { state: "default" 0.0;
+              align: 0.0 0.0;
+              rel1.to: "elm.swallow.offset";
+              rel1.relative: 1.0 1.0;
+              rel2.to: "elm.swallow.offset";
+              rel2.relative: 1.0 1.0;
+           }
+        }
+        part { name: "base";
+           type: RECT;
+           mouse_events: 1;
+           description { state: "default" 0.0;
+              color: 0 0 0 0;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 1.0;
+              color: 0 0 0 64;
+           }
+        }
+        part { name: "leftclip";
+           type: RECT;
+           description { state: "default" 0.0;
+              rel2.to_x: "pop";
+              rel2.relative: 0.0 1.0;
+               rel2.offset: 1 -1;
+           }
+        }
+        part { name: "left";
+           clip_to: "leftclip";
+           description { state: "default" 0.0;
+              visible: 0;
+              rel1.to: "elm.swallow.slot.left";
+               rel1.offset: -5 -5;
+              rel2.to: "elm.swallow.slot.left";
+               rel2.offset: 4 4;
+               image {
+                 normal: "bt_dis_base.png";
+                 border: 4 4 4 4;
+              }
+               image.middle: SOLID;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+           }
+        }
+        part { name: "elm.swallow.slot.left";
+            type: SWALLOW;
+           clip_to: "leftclip";
+           description { state: "default" 0.0;
+              align: 0.0 0.5;
+              rel1.to: "elm.swallow.slot.middle";
+              rel1.relative: 0.0 0.0;
+              rel1.offset: -1 0;
+              rel2.to: "elm.swallow.slot.middle";
+              rel2.relative: 0.0 1.0;
+              rel2.offset: -1 -1;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              rel1.offset: -7 0;
+              rel2.offset: -7 -1;
+              align: 1.0 0.5;
+           }
+        }
+         part { name: "leftover";
+           clip_to: "leftclip";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "left";
+              rel2.to: "left";
+              rel2.relative: 1.0 0.5;
+              image {
+                 normal: "bt_dis_hilight.png";
+                 border: 4 4 4 0;
+              }
+           }
+        }
+        part { name: "rightclip";
+           type: RECT;
+           description { state: "default" 0.0;
+              rel1.to_x: "pop";
+              rel1.relative: 1.0 0.0;
+               rel1.offset: -2 0;
+           }
+        }
+        part { name: "right";
+           clip_to: "rightclip";
+           description { state: "default" 0.0;
+              visible: 0;
+              rel1.to: "elm.swallow.slot.right";
+               rel1.offset: -5 -5;
+              rel2.to: "elm.swallow.slot.right";
+               rel2.offset: 4 4;
+               image {
+                 normal: "bt_dis_base.png";
+                 border: 4 4 4 4;
+              }
+               image.middle: SOLID;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+           }
+        }
+        part { name: "elm.swallow.slot.right";
+            type: SWALLOW;
+           clip_to: "rightclip";
+           description { state: "default" 0.0;
+              align: 1.0 0.5;
+              rel1.to: "elm.swallow.slot.middle";
+              rel1.relative: 1.0 0.0;
+              rel1.offset: 0 0;
+              rel2.to: "elm.swallow.slot.middle";
+              rel2.relative: 1.0 1.0;
+              rel2.offset: 0 -1;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              rel1.offset: 6 0;
+              rel2.offset: 6 -1;
+              align: 0.0 0.5;
+           }
+        }
+         part { name: "rightover";
+           clip_to: "rightclip";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "right";
+              rel2.to: "right";
+              rel2.relative: 1.0 0.5;
+              image {
+                 normal: "bt_dis_hilight.png";
+                 border: 4 4 4 0;
+              }
+           }
+        }
+        part { name: "topclip";
+           type: RECT;
+           description { state: "default" 0.0;
+              rel2.to_y: "pop";
+              rel2.relative: 1.0 0.0;
+               rel2.offset: -1 1;
+           }
+        }
+        part { name: "top";
+           clip_to: "topclip";
+           description { state: "default" 0.0;
+              visible: 0;
+              rel1.to: "elm.swallow.slot.top";
+               rel1.offset: -5 -5;
+              rel2.to: "elm.swallow.slot.top";
+               rel2.offset: 4 4;
+               image {
+                 normal: "bt_dis_base.png";
+                 border: 4 4 4 4;
+              }
+               image.middle: SOLID;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+           }
+        }
+        part { name: "elm.swallow.slot.top";
+            type: SWALLOW;
+           clip_to: "topclip";
+           description { state: "default" 0.0;
+              visible: 1;
+              align: 0.5 0.0;
+              rel1.to: "elm.swallow.slot.middle";
+              rel1.relative: 0.0 0.0;
+              rel1.offset: 0 -1;
+              rel2.to: "elm.swallow.slot.middle";
+              rel2.relative: 1.0 0.0;
+              rel2.offset: -1 -1;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              rel1.offset: 0 -7;
+              rel2.offset: -1 -7;
+              align: 0.5 1.0;
+           }
+        }
+         part { name: "topover";
+           clip_to: "topclip";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "top";
+              rel2.to: "top";
+              rel2.relative: 1.0 0.5;
+              image {
+                 normal: "bt_dis_hilight.png";
+                 border: 4 4 4 0;
+              }
+           }
+        }
+        part { name: "bottomclip";
+           type: RECT;
+           description { state: "default" 0.0;
+              rel1.to_y: "pop";
+              rel1.relative: 0.0 1.0;
+               rel1.offset: -1 -2;
+           }
+        }
+        part { name: "bottom";
+           clip_to: "bottomclip";
+           description { state: "default" 0.0;
+              visible: 0;
+              rel1.to: "elm.swallow.slot.bottom";
+               rel1.offset: -5 -5;
+              rel2.to: "elm.swallow.slot.bottom";
+               rel2.offset: 4 4;
+               image {
+                 normal: "bt_dis_base.png";
+                 border: 4 4 4 4;
+              }
+               image.middle: SOLID;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+           }
+        }
+        part { name: "elm.swallow.slot.bottom";
+            type: SWALLOW;
+           clip_to: "bottomclip";
+           description { state: "default" 0.0;
+              align: 0.5 1.0;
+              rel1.to: "elm.swallow.slot.middle";
+              rel1.relative: 0.0 1.0;
+              rel1.offset: 0 0;
+              rel2.to: "elm.swallow.slot.middle";
+              rel2.relative: 1.0 1.0;
+              rel2.offset: -1 0;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              rel1.offset: 0 6;
+              rel2.offset: -1 6;
+              align: 0.5 0.0;
+           }
+        }
+         part { name: "bottomover";
+           clip_to: "bottomclip";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "bottom";
+              rel2.to: "bottom";
+              rel2.relative: 1.0 0.5;
+              image {
+                 normal: "bt_dis_hilight.png";
+                 border: 4 4 4 0;
+              }
+           }
+        }
+         part { name: "shad";
+           mouse_events:  0;
+           description { state: "default" 0.0;
+              image.normal: "shad_circ.png";
+              rel1.to: "elm.swallow.size";
+              rel1.offset: -64 -64;
+              rel2.to: "elm.swallow.size";
+              rel2.offset: 63 63;
+               fill.smooth: 0;
+           }
+        }
+        part { name: "pop";
+           mouse_events: 1;
+           description { state: "default" 0.0;
+              rel1.to: "elm.swallow.slot.middle";
+               rel1.offset: -5 -5;
+              rel2.to: "elm.swallow.slot.middle";
+               rel2.offset: 4 4;
+               image {
+                 normal: "bt_dis_base.png";
+                 border: 4 4 4 4;
+              }
+               image.middle: SOLID;
+           }
+        }
+        part { name: "elm.swallow.slot.middle";
+            type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.to: "elm.swallow.size";
+              rel2.to: "elm.swallow.size";
+           }
+        }
+         part { name: "popover";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "pop";
+              rel2.to: "pop";
+              rel2.relative: 1.0 0.5;
+              image {
+                 normal: "bt_dis_hilight.png";
+                 border: 4 4 4 0;
+              }
+           }
+        }
+      }
+      programs {
+        program { name: "end";
+           signal: "mouse,up,1";
+           source: "base";
+           action: SIGNAL_EMIT "elm,action,dismiss" "";
+        }
+
+        program { name: "show";
+            signal: "elm,action,show";
+           source: "elm";
+           action: STATE_SET "visible" 0.0;
+//         transition: DECELERATE 0.5;
+           target: "base";
+        }
+        program { name: "hide";
+            signal: "elm,action,hide";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+//         transition: DECELERATE 0.5;
+           target: "base";
+        }
+
+        program { name: "leftshow";
+            signal: "elm,action,slot,left,show";
+           source: "elm";
+           action: STATE_SET "visible" 0.0;
+           transition: DECELERATE 0.5;
+           target: "left";
+           target: "elm.swallow.slot.left";
+        }
+        program { name: "lefthide";
+            signal: "elm,action,slot,left,hide";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           transition: DECELERATE 0.5;
+           target: "left";
+           target: "elm.swallow.slot.left";
+        }
+        program { name: "rightshow";
+            signal: "elm,action,slot,right,show";
+           source: "elm";
+           action: STATE_SET "visible" 0.0;
+           transition: DECELERATE 0.5;
+           target: "right";
+           target: "elm.swallow.slot.right";
+        }
+        program { name: "righthide";
+            signal: "elm,action,slot,right,hide";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           transition: DECELERATE 0.5;
+           target: "right";
+           target: "elm.swallow.slot.right";
+        }
+        program { name: "topshow";
+            signal: "elm,action,slot,top,show";
+           source: "elm";
+           action: STATE_SET "visible" 0.0;
+           transition: DECELERATE 0.5;
+           target: "top";
+           target: "elm.swallow.slot.top";
+        }
+        program { name: "tophide";
+            signal: "elm,action,slot,top,hide";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           transition: DECELERATE 0.5;
+           target: "top";
+           target: "elm.swallow.slot.top";
+        }
+        program { name: "bottomshow";
+            signal: "elm,action,slot,bottom,show";
+           source: "elm";
+           action: STATE_SET "visible" 0.0;
+           transition: DECELERATE 0.5;
+           target: "bottom";
+           target: "elm.swallow.slot.bottom";
+        }
+        program { name: "bottomhide";
+            signal: "elm,action,slot,bottom,hide";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           transition: DECELERATE 0.5;
+           target: "bottom";
+           target: "elm.swallow.slot.bottom";
+        }
+      }
+   }
+
+   //In the hover used by the menu only the bottom part is used.
+   group { name: "elm/hover/base/menu";
+       images {
+           image: "shad_circ.png" COMP;
+           image: "bt_dis_base.png" COMP;
+       }
+       parts {
+           part { name: "elm.swallow.offset";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   align: 0.0 0.0;
+                   rel1.relative: 0.0 0.0;
+                   rel2.relative: 0.0 0.0;
+               }
+           }
+           part { name: "elm.swallow.size";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   align: 0.0 0.0;
+                   rel1.to: "elm.swallow.offset";
+                   rel1.relative: 1.0 1.0;
+                   rel2.to: "elm.swallow.offset";
+                   rel2.relative: 1.0 1.0;
+               }
+           }
+           part { name: "base";
+               type: RECT;
+               mouse_events: 1;
+               description { state: "default" 0.0;
+                   color: 0 0 0 0;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 1.0;
+                   color: 0 0 0 64;
+               }
+           }
+           part { name: "elm.swallow.slot.left";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+               }
+           }
+           part { name: "elm.swallow.slot.right";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+               }
+           }
+           part { name: "elm.swallow.slot.top";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+               }
+           }
+           part { name: "bottomclip";
+               type: RECT;
+               description { state: "default" 0.0;
+                   rel1.to_y: "pop";
+                   rel1.relative: 0.0 1.0;
+                   rel1.offset: -1 -2;
+               }
+           }
+           part { name: "bottom";
+               clip_to: "bottomclip";
+               description { state: "default" 0.0;
+                   visible: 0;
+                   rel1.to: "elm.swallow.slot.bottom";
+                   rel1.offset: -5 -5;
+                   rel2.to: "elm.swallow.slot.bottom";
+                   rel2.offset: 4 4;
+                   image {
+                       normal: "bt_dis_base.png";
+                       border: 4 4 4 4;
+                   }
+                   image.middle: SOLID;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+               }
+           }
+           part { name: "elm.swallow.slot.bottom";
+               type: SWALLOW;
+               clip_to: "bottomclip";
+               description { state: "default" 0.0;
+                   align: 0.5 1.0;
+                   rel1.to: "elm.swallow.slot.middle";
+                   rel1.relative: 0.0 1.0;
+                   rel1.offset: 0 0;
+                   rel2.to: "elm.swallow.slot.middle";
+                   rel2.relative: 1.0 1.0;
+                   rel2.offset: -1 0;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+                   rel1.offset: 0 6;
+                   rel2.offset: -1 6;
+                   align: 0.5 0.0;
+               }
+           }
+           part { name: "pop";
+               mouse_events: 1;
+               repeat_events:1;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.swallow.slot.middle";
+                   rel1.offset: -5 -5;
+                   rel2.to: "elm.swallow.slot.middle";
+                   rel2.offset: 4 4;
+               }
+           }
+           part { name: "elm.swallow.slot.middle";
+               type: SWALLOW;
+               repeat_events:1;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.swallow.size";
+                   rel2.to: "elm.swallow.size";
+               }
+           }
+       }
+       programs {
+           program { name: "end";
+               signal: "mouse,up,1";
+               source: "base";
+               action: SIGNAL_EMIT "elm,action,dismiss" "";
+           }
+           program { name: "show";
+               signal: "elm,action,show";
+               source: "elm";
+               action: STATE_SET "visible" 0.0;
+                       //          transition: DECELERATE 0.5;
+               target: "base";
+           }
+           program { name: "hide";
+               signal: "elm,action,hide";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+                       //          transition: DECELERATE 0.5;
+               target: "base";
+           }
+           program { name: "bottomshow";
+               signal: "elm,action,slot,bottom,show";
+               source: "elm";
+               action: STATE_SET "visible" 0.0;
+               transition: DECELERATE 0.3;
+               target: "bottom";
+               target: "elm.swallow.slot.bottom";
+           }
+           program { name: "bottomhide";
+               signal: "elm,action,slot,bottom,hide";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               transition: DECELERATE 0.5;
+               target: "bottom";
+               target: "elm.swallow.slot.bottom";
+           }
+       }
+   }
+
+   //In the hover used by the submenu only the bottom part is used
+   //and no part should interact except the bottom area
+   group { name: "elm/hover/base/submenu";
+       images {
+           image: "shad_circ.png" COMP;
+           image: "bt_dis_base.png" COMP;
+       }
+       parts {
+           part { name: "elm.swallow.offset";
+               type: SWALLOW;
+               repeat_events:1;
+               description { state: "default" 0.0;
+                   align: 0.0 0.0;
+                   rel1.relative: 0.0 0.0;
+                   rel2.relative: 0.0 0.0;
+               }
+           }
+           part { name: "elm.swallow.size";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   align: 0.0 0.0;
+                   rel1.to: "elm.swallow.offset";
+                   rel1.relative: 1.0 1.0;
+                   rel2.to: "elm.swallow.offset";
+                   rel2.relative: 1.0 1.0;
+               }
+           }
+           //here we do non catch events like the hover hover does
+           part { name: "base";
+               type: RECT;
+               mouse_events: 1;
+               description { state: "default" 0.0;
+                   color: 0 0 0 0;
+                   visible: 0;
+               }
+           }
+           part { name: "elm.swallow.slot.left";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+               }
+           }
+           part { name: "elm.swallow.slot.right";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+               }
+           }
+           part { name: "elm.swallow.slot.top";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+               }
+           }
+           part { name: "bottomclip";
+               type: RECT;
+               description { state: "default" 0.0;
+                   rel1.to_y: "pop";
+                   rel1.relative: 0.0 1.0;
+                   rel1.offset: -1 -2;
+               }
+           }
+           part { name: "bottom";
+               clip_to: "bottomclip";
+               description { state: "default" 0.0;
+                   visible: 0;
+                   rel1.to: "elm.swallow.slot.bottom";
+                   rel1.offset: -5 -5;
+                   rel2.to: "elm.swallow.slot.bottom";
+                   rel2.offset: 4 4;
+                   image {
+                       normal: "bt_dis_base.png";
+                       border: 4 4 4 4;
+                   }
+                   image.middle: SOLID;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+               }
+           }
+           part { name: "elm.swallow.slot.bottom";
+               type: SWALLOW;
+               clip_to: "bottomclip";
+               description { state: "default" 0.0;
+                   align: 0.5 1.0;
+                   rel1.to: "elm.swallow.slot.middle";
+                   rel1.relative: 0.0 1.0;
+                   rel1.offset: 0 0;
+                   rel2.to: "elm.swallow.slot.middle";
+                   rel2.relative: 1.0 1.0;
+                   rel2.offset: -1 0;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+                   rel1.offset: 0 6;
+                   rel2.offset: -1 6;
+                   align: 0.5 0.0;
+               }
+           }
+           part { name: "pop";
+               mouse_events: 1;
+               repeat_events:1;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.swallow.slot.middle";
+                   rel1.offset: -5 -5;
+                   rel2.to: "elm.swallow.slot.middle";
+                   rel2.offset: 4 4;
+               }
+           }
+           part { name: "elm.swallow.slot.middle";
+               type: SWALLOW;
+               repeat_events:1;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.swallow.size";
+                   rel2.to: "elm.swallow.size";
+               }
+           }
+       }
+       programs {
+           program { name: "end";
+               signal: "mouse,up,1";
+               source: "base";
+               action: SIGNAL_EMIT "elm,action,dismiss" "";
+           }
+           program { name: "show";
+               signal: "elm,action,show";
+               source: "elm";
+               action: STATE_SET "visible" 0.0;
+                       //          transition: DECELERATE 0.5;
+               target: "base";
+           }
+           program { name: "hide";
+               signal: "elm,action,hide";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+                       //          transition: DECELERATE 0.5;
+               target: "base";
+           }
+           program { name: "bottomshow";
+               signal: "elm,action,slot,bottom,show";
+               source: "elm";
+               action: STATE_SET "visible" 0.0;
+               transition: DECELERATE 0.3;
+               target: "bottom";
+               target: "elm.swallow.slot.bottom";
+           }
+           program { name: "bottomhide";
+               signal: "elm,action,slot,bottom,hide";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               transition: DECELERATE 0.5;
+               target: "bottom";
+               target: "elm.swallow.slot.bottom";
+           }
+       }
+   }
+
+   group { name: "elm/hover/base/hoversel_vertical/default";
+      alias: "elm/hover/base/hoversel_vertical/entry";
+      images {
+//      image: "shad_circ.png" COMP;
+        image: "bt_base2.png" COMP;
+        image: "bt_hilight.png" COMP;
+        image: "bt_shine.png" COMP;
+        image: "outdent-top.png" COMP;
+        image: "outdent-bottom.png" COMP;
+      }
+      parts {
+        part { name: "elm.swallow.offset";
+            type: SWALLOW;
+           description { state: "default" 0.0;
+              align: 0.0 0.0;
+              rel1.relative: 0.0 0.0;
+              rel2.relative: 0.0 0.0;
+           }
+        }
+        part { name: "elm.swallow.size";
+            type: SWALLOW;
+           description { state: "default" 0.0;
+              align: 0.0 0.0;
+              rel1.to: "elm.swallow.offset";
+              rel1.relative: 1.0 1.0;
+              rel2.to: "elm.swallow.offset";
+              rel2.relative: 1.0 1.0;
+           }
+        }
+/*
+        part { name: "shad";
+           mouse_events:  0;
+           description { state: "default" 0.0;
+              image.normal: "shad_circ.png";
+              rel1.to: "button_image";
+              rel1.offset: -64 -64;
+              rel2.to: "button_image";
+              rel2.offset: 63 63;
+               fill.smooth: 0;
+           }
+        }
+ */
+        part { name: "button_image";
+           mouse_events: 1;
+           description { state: "default" 0.0;
+              rel1.to_x: "elm.swallow.slot.top";
+              rel1.to_y: "elm.swallow.slot.top";
+               rel1.offset: -2 -6;
+              rel2.to_x: "elm.swallow.slot.top";
+              rel2.to_y: "elm.swallow.slot.bottom";
+               rel2.offset: 1 5;
+              image {
+                 normal: "bt_base2.png";
+                 border: 7 7 7 7;
+              }
+               image.middle: SOLID;
+           }
+           description { state: "bottom" 0.0;
+              rel1.to_x: "elm.swallow.slot.bottom";
+              rel1.to_y: "elm.swallow.slot.top";
+               rel1.offset: -2 -6;
+              rel2.to_x: "elm.swallow.slot.bottom";
+              rel2.to_y: "elm.swallow.slot.bottom";
+               rel2.offset: 1 5;
+              image {
+                 normal: "bt_base2.png";
+                 border: 7 7 7 7;
+              }
+               image.middle: SOLID;
+           }
+        }
+
+        part { name: "base";
+           type: RECT;
+           mouse_events: 1;
+           description { state: "default" 0.0;
+              color: 0 0 0 0;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 1.0;
+              color: 0 0 0 64;
+           }
+        }
+
+        part { name: "topclip";
+           type: RECT;
+           description { state: "default" 0.0;
+              rel2.to_y: "edge_top";
+              rel2.relative: 1.0 0.0;
+               rel2.offset: -1 7;
+           }
+        }
+        part { name: "elm.swallow.slot.top";
+            type: SWALLOW;
+           clip_to: "topclip";
+           description { state: "default" 0.0;
+              visible: 1;
+              align: 0.5 0.0;
+              rel1.to: "elm.swallow.slot.middle";
+              rel1.relative: 0.0 0.0;
+              rel1.offset: 0 -1;
+              rel2.to: "elm.swallow.slot.middle";
+              rel2.relative: 1.0 0.0;
+              rel2.offset: -1 -1;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              rel1.offset: 0 -7;
+              rel2.offset: -1 -7;
+              align: 0.5 1.0;
+           }
+        }
+
+        part { name: "bottomclip";
+           type: RECT;
+           description { state: "default" 0.0;
+              rel1.to_y: "edge_bottom";
+              rel1.relative: 0.0 1.0;
+               rel1.offset: -1 -8;
+           }
+        }
+        part { name: "elm.swallow.slot.bottom";
+            type: SWALLOW;
+           clip_to: "bottomclip";
+           description { state: "default" 0.0;
+              align: 0.5 1.0;
+              rel1.to: "elm.swallow.slot.middle";
+              rel1.relative: 0.0 1.0;
+              rel1.offset: 0 0;
+              rel2.to: "elm.swallow.slot.middle";
+              rel2.relative: 1.0 1.0;
+              rel2.offset: -1 0;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              rel1.offset: 0 6;
+              rel2.offset: -1 6;
+              align: 0.5 0.0;
+           }
+        }
+
+        part {   name: "over1";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+               rel1.to: "button_image";
+               rel2.to: "button_image";
+              rel2.relative: 1.0 0.5;
+              image {
+                 normal: "bt_hilight.png";
+                 border: 7 7 7 0;
+              }
+           }
+        }
+        part { name: "over2";
+           mouse_events: 1;
+           repeat_events: 1;
+            ignore_flags: ON_HOLD;
+           description { state: "default" 0.0;
+               rel1.to: "button_image";
+               rel2.to: "button_image";
+              image {
+                 normal: "bt_shine.png";
+                 border: 7 7 7 7;
+              }
+           }
+        }
+         part { name: "edge_top";
+           mouse_events:  0;
+           description { state: "default" 0.0;
+               visible: 0;
+              rel1 {
+                  to: "elm.swallow.size";
+                  offset: 0 -10;
+               }
+              rel2 {
+                  to: "elm.swallow.size";
+               }
+              image.normal: "outdent-bottom.png";
+               image.border: 0 0 13 0;
+               fill.smooth: 0;
+           }
+           description { state: "visible" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+           }
+        }
+         part { name: "edge_bottom";
+           mouse_events:  0;
+           description { state: "default" 0.0;
+               visible: 0;
+              rel1 {
+                  to: "elm.swallow.size";
+               }
+              rel2 {
+                  to: "elm.swallow.size";
+                  offset: -1 9;
+               }
+              image.normal: "outdent-top.png";
+               image.border: 0 0 0 13;
+               fill.smooth: 0;
+           }
+           description { state: "visible" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+           }
+        }
+        part { name: "elm.swallow.slot.middle";
+            type: SWALLOW;
+           description { state: "default" 0.0;
+              rel1.to: "elm.swallow.size";
+              rel2.to: "elm.swallow.size";
+           }
+        }
+      }
+      programs {
+        program { name: "end";
+           signal: "mouse,up,1";
+           source: "base";
+           action: SIGNAL_EMIT "elm,action,dismiss" "";
+        }
+
+        program { name: "show";
+            signal: "elm,action,show";
+           source: "elm";
+           action: STATE_SET "visible" 0.0;
+//         transition: DECELERATE 0.5;
+           target: "base";
+        }
+        program { name: "hide";
+            signal: "elm,action,hide";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+//         transition: DECELERATE 0.5;
+           target: "base";
+        }
+        program { name: "topshow";
+            signal: "elm,action,slot,top,show";
+           source: "elm";
+           action: STATE_SET "visible" 0.0;
+           target: "edge_top";
+            after: "topshow2";
+        }
+        program { name: "topshow2";
+           action: STATE_SET "visible" 0.0;
+           transition: DECELERATE 0.5;
+           target: "elm.swallow.slot.top";
+        }
+        program { name: "topshow3";
+            signal: "elm,action,slot,top,show";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "button_image";
+        }
+        program { name: "tophide";
+            signal: "elm,action,slot,top,hide";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           transition: DECELERATE 0.5;
+           target: "elm.swallow.slot.top";
+            after: "tophide2";
+        }
+        program { name: "tophide2";
+           action: STATE_SET "default" 0.0;
+           target: "edge_top";
+        }
+        program { name: "bottomshow";
+            signal: "elm,action,slot,bottom,show";
+           source: "elm";
+           action: STATE_SET "visible" 0.0;
+           target: "edge_bottom";
+            after: "bottomshow2";
+        }
+        program { name: "bottomshow2";
+           action: STATE_SET "visible" 0.0;
+           transition: DECELERATE 0.5;
+           target: "elm.swallow.slot.bottom";
+        }
+        program { name: "bottomshow3";
+            signal: "elm,action,slot,bottom,show";
+           source: "elm";
+           action: STATE_SET "bottom" 0.0;
+           target: "button_image";
+        }
+        program { name: "bottomhide";
+            signal: "elm,action,slot,bottom,hide";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           transition: DECELERATE 0.5;
+           target: "elm.swallow.slot.bottom";
+            after: "bottomhide2";
+        }
+        program { name: "bottomhide2";
+           action: STATE_SET "default" 0.0;
+           target: "edge_bottom";
+        }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+// emoticon images from:
+// Tanya - Latvia
+// http://lazycrazy.deviantart.com/
+// http://lazycrazy.deviantart.com/art/Very-Emotional-Emoticons-144461621
+  group { name: "elm/entry/emoticon/angry/default"; images.image:
+     "emo-angry.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-angry.png"; } } } }
+  group { name: "elm/entry/emoticon/angry-shout/default"; images.image:
+     "emo-angry-shout.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-angry-shout.png"; } } } }
+  group { name: "elm/entry/emoticon/crazy-laugh/default"; images.image:
+     "emo-crazy-laugh.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-crazy-laugh.png"; } } } }
+  group { name: "elm/entry/emoticon/evil-laugh/default"; images.image:
+     "emo-evil-laugh.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-evil-laugh.png"; } } } }
+  group { name: "elm/entry/emoticon/evil/default"; images.image:
+     "emo-evil.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-evil.png"; } } } }
+  group { name: "elm/entry/emoticon/goggle-smile/default"; images.image:
+     "emo-goggle-smile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-goggle-smile.png"; } } } }
+  group { name: "elm/entry/emoticon/grumpy/default"; images.image:
+     "emo-grumpy.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-grumpy.png"; } } } }
+  group { name: "elm/entry/emoticon/grumpy-smile/default"; images.image:
+     "emo-grumpy-smile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-grumpy-smile.png"; } } } }
+  group { name: "elm/entry/emoticon/guilty/default"; images.image:
+     "emo-guilty.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-guilty.png"; } } } }
+  group { name: "elm/entry/emoticon/guilty-smile/default"; images.image:
+     "emo-guilty-smile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-guilty-smile.png"; } } } }
+  group { name: "elm/entry/emoticon/haha/default"; images.image:
+     "emo-haha.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-haha.png"; } } } }
+  group { name: "elm/entry/emoticon/half-smile/default"; images.image:
+     "emo-half-smile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-half-smile.png"; } } } }
+  group { name: "elm/entry/emoticon/happy-panting/default"; images.image:
+     "emo-happy-panting.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-happy-panting.png"; } } } }
+  group { name: "elm/entry/emoticon/happy/default"; images.image:
+     "emo-happy.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-happy.png"; } } } }
+  group { name: "elm/entry/emoticon/indifferent/default"; images.image:
+     "emo-indifferent.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-indifferent.png"; } } } }
+  group { name: "elm/entry/emoticon/kiss/default"; images.image:
+     "emo-kiss.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-kiss.png"; } } } }
+  group { name: "elm/entry/emoticon/knowing-grin/default"; images.image:
+     "emo-knowing-grin.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-knowing-grin.png"; } } } }
+  group { name: "elm/entry/emoticon/laugh/default"; images.image:
+     "emo-laugh.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-laugh.png"; } } } }
+  group { name: "elm/entry/emoticon/little-bit-sorry/default"; images.image:
+     "emo-little-bit-sorry.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-little-bit-sorry.png"; } } } }
+  group { name: "elm/entry/emoticon/love-lots/default"; images.image:
+     "emo-love-lots.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-love-lots.png"; } } } }
+  group { name: "elm/entry/emoticon/love/default"; images.image:
+     "emo-love.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-love.png"; } } } }
+  group { name: "elm/entry/emoticon/minimal-smile/default"; images.image:
+     "emo-minimal-smile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-minimal-smile.png"; } } } }
+  group { name: "elm/entry/emoticon/not-happy/default"; images.image:
+     "emo-not-happy.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-not-happy.png"; } } } }
+  group { name: "elm/entry/emoticon/not-impressed/default"; images.image:
+     "emo-not-impressed.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-not-impressed.png"; } } } }
+  group { name: "elm/entry/emoticon/omg/default"; images.image:
+     "emo-omg.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-omg.png"; } } } }
+  group { name: "elm/entry/emoticon/opensmile/default"; images.image:
+     "emo-opensmile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-opensmile.png"; } } } }
+  group { name: "elm/entry/emoticon/smile/default"; images.image:
+     "emo-smile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-smile.png"; } } } }
+  group { name: "elm/entry/emoticon/sorry/default"; images.image:
+     "emo-sorry.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-sorry.png"; } } } }
+  group { name: "elm/entry/emoticon/squint-laugh/default"; images.image:
+     "emo-squint-laugh.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-squint-laugh.png"; } } } }
+  group { name: "elm/entry/emoticon/surprised/default"; images.image:
+     "emo-surprised.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-surprised.png"; } } } }
+  group { name: "elm/entry/emoticon/suspicious/default"; images.image:
+     "emo-suspicious.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-suspicious.png"; } } } }
+  group { name: "elm/entry/emoticon/tongue-dangling/default"; images.image:
+     "emo-tongue-dangling.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-tongue-dangling.png"; } } } }
+  group { name: "elm/entry/emoticon/tongue-poke/default"; images.image:
+     "emo-tongue-poke.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-tongue-poke.png"; } } } }
+  group { name: "elm/entry/emoticon/uh/default"; images.image:
+     "emo-uh.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-uh.png"; } } } }
+  group { name: "elm/entry/emoticon/unhappy/default"; images.image:
+     "emo-unhappy.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-unhappy.png"; } } } }
+  group { name: "elm/entry/emoticon/very-sorry/default"; images.image:
+     "emo-very-sorry.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-very-sorry.png"; } } } }
+  group { name: "elm/entry/emoticon/what/default"; images.image:
+     "emo-what.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-what.png"; } } } }
+  group { name: "elm/entry/emoticon/wink/default"; images.image:
+     "emo-wink.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-wink.png"; } } } }
+  group { name: "elm/entry/emoticon/worried/default"; images.image:
+     "emo-worried.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-worried.png"; } } } }
+  group { name: "elm/entry/emoticon/wtf/default"; images.image:
+     "emo-wtf.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal: 
+        "emo-wtf.png"; } } } }
+//------------------------------------------------------------
+   group { name: "elm/entry/base/default";
+      styles
+       {
+          style { name: "entry_textblock_style";
+             base: "font=Sans font_size=10 align=left color=#000 wrap=word";
+             tag:  "br" "\n";
+             tag:  "tab" "\t";
+             tag:  "em" "+ font=Sans:style=Oblique";
+             tag:  "b" "+ font=Sans:style=Bold";
+             tag:  "link" "+ color=#800 underline=on underline_color=#8008";
+             tag:  "hilight" "+ font=Sans:style=Bold";
+          }
+          style { name: "entry_textblock_disabled_style";
+             base: "font=Sans font_size=10 align=left color=#00000080 wrap=word";
+             tag:  "br" "\n";
+             tag:  "tab" "\t";
+             tag:  "em" "+ font=Sans:style=Oblique";
+             tag:  "b" "+ font=Sans:style=Bold";
+             tag:  "link" "+ color=#00000080 underline=on underline_color=#00000080";
+             tag:  "hilight" "+ font=Sans:style=Bold";
+          }
+       }
+      data {
+//         item: context_menu_orientation "horizontal";
+      }
+      parts {
+        part { name: "elm.text";
+           type: TEXTBLOCK;
+           mouse_events: 1;
+           scale: 1;
+           entry_mode: EDITABLE;
+           select_mode: EXPLICIT;
+           multiline: 1;
+           source: "elm/entry/selection/default"; // selection under
+//         source2: "X"; // selection over
+//         source3: "X"; // cursor under
+           source4: "elm/entry/cursor/default"; // cursorover
+           source5: "elm/entry/anchor/default"; // anchor under
+//         source6: "X"; // anchor over
+           description { state: "default" 0.0;
+               fixed: 1 0;
+              text {
+                 style: "entry_textblock_style";
+                 min: 0 1;
+              }
+           }
+           description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+              text {
+                 style: "entry_textblock_disabled_style";
+                 min: 0 1;
+              }
+           }
+        }
+      }
+      programs {
+        program { name: "focus";
+            signal: "load";
+           source: "";
+           action: FOCUS_SET;
+           target: "elm.text";
+        }
+        program { name: "disable";
+           signal: "elm,state,disabled";
+           source: "elm";
+           action: STATE_SET "disabled" 0.0;
+           target: "elm.text";
+        }
+        program { name: "enable";
+           signal: "elm,state,enabled";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "elm.text";
+        }
+      }
+   }
+
+    group { name: "elm/entry/base-charwrap/default";
+      styles
+       {
+          style { name: "entry_textblock_style_charwrap";
+             base: "font=Sans font_size=10 align=left color=#000 wrap=char";
+             tag:  "br" "\n";
+             tag:  "tab" "\t";
+             tag:  "em" "+ font=Sans:style=Oblique";
+             tag:  "b" "+ font=Sans:style=Bold";
+             tag:  "link" "+ color=#800 underline=on underline_color=#8008";
+             tag:  "hilight" "+ font=Sans:style=Bold";
+          }
+          style { name: "entry_textblock_disabled_style_charwrap";
+             base: "font=Sans font_size=10 align=left color=#00000080 wrap=char";
+             tag:  "br" "\n";
+             tag:  "tab" "\t";
+             tag:  "em" "+ font=Sans:style=Oblique";
+             tag:  "b" "+ font=Sans:style=Bold";
+             tag:  "link" "+ color=#00000080 underline=on underline_color=#00000080";
+             tag:  "hilight" "+ font=Sans:style=Bold";
+          }
+       }
+      parts {
+        part { name: "elm.text";
+           type: TEXTBLOCK;
+           mouse_events: 1;
+           scale: 1;
+           entry_mode: EDITABLE;
+           select_mode: EXPLICIT;
+           multiline: 1;
+           source: "elm/entry/selection/default"; // selection under
+//         source2: "X"; // selection over
+//         source3: "X"; // cursor under
+           source4: "elm/entry/cursor/default"; // cursorover
+           source5: "elm/entry/anchor/default"; // anchor under
+//         source6: "X"; // anchor over
+           description { state: "default" 0.0;
+               fixed: 1 0;
+              text {
+                 style: "entry_textblock_style_charwrap";
+                 min: 0 1;
+              }
+           }
+           description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+              text {
+                 style: "entry_textblock_disabled_style_charwrap";
+                 min: 0 1;
+              }
+           }
+        }
+      }
+      programs {
+        program { name: "focus";
+            signal: "load";
+           source: "";
+           action: FOCUS_SET;
+           target: "elm.text";
+        }
+        program { name: "disable";
+           signal: "elm,state,disabled";
+           source: "elm";
+           action: STATE_SET "disabled" 0.0;
+           target: "elm.text";
+        }
+        program { name: "enable";
+           signal: "elm,state,enabled";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "elm.text";
+        }
+      }
+   }
+
+
+   group { name: "elm/entry/base-nowrap/default";
+      parts {
+        part { name: "elm.text";
+           type: TEXTBLOCK;
+           mouse_events: 1;
+           scale: 1;
+           entry_mode: EDITABLE;
+           select_mode: EXPLICIT;
+           multiline: 1;
+           source: "elm/entry/selection/default"; // selection under
+           source4: "elm/entry/cursor/default"; // cursorover
+           source5: "elm/entry/anchor/default"; // anchor under
+           description { state: "default" 0.0;
+              text {
+                 style: "entry_textblock_style";
+                 min: 1 1;
+              }
+           }
+           description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+              text {
+                 style: "entry_textblock_disabled_style";
+                 min: 0 1;
+              }
+           }
+        }
+/*
+        part { name: "sel";
+           type: RECT;
+            mouse_events: 0;
+           description { state: "default" 0.0;
+               align: 1.0 1.0;
+               max: 16 16;
+               aspect: 1.0 1.0;
+               color: 255 0 0 0;
+           }
+           description { state: "visible" 0.0;
+               inherit: "default" 0.0;
+               color: 255 0 0 50;
+            }
+        }
+ */
+      }
+      programs {
+        program { name: "focus";
+            signal: "load";
+           source: "";
+           action: FOCUS_SET;
+           target: "elm.text";
+        }
+        program { name: "disable";
+           signal: "elm,state,disabled";
+           source: "elm";
+           action: STATE_SET "disabled" 0.0;
+           target: "elm.text";
+        }
+        program { name: "enable";
+           signal: "elm,state,enabled";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "elm.text";
+        }
+/*
+        program { name: "selmode0";
+            signal: "elm,state,select,on";
+           source: "elm";
+           action: STATE_SET "visible" 0.0;
+           target: "sel";
+        }
+        program { name: "selmode1";
+            signal: "elm,state,select,off";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "sel";
+        }
+ */
+      }
+   }
+
+   group { name: "elm/entry/base-single/default";
+      styles
+       {
+          style { name: "entry_single_textblock_style";
+             base: "font=Sans font_size=10 align=left color=#000 wrap=none";
+             tag:  "br" "\n";
+             tag:  "tab" "\t";
+             tag:  "em" "+ font=Sans:style=Oblique";
+             tag:  "b" "+ font=Sans:style=Bold";
+             tag:  "link" "+ color=#800 underline=on underline_color=#8008";
+             tag:  "hilight" "+ font=Sans:style=Bold";
+          }
+          style { name: "entry_single_textblock_disabled_style";
+             base: "font=Sans font_size=10 align=left color=#00000080 wrap=none";
+             tag:  "br" "\n";
+             tag:  "tab" "\t";
+             tag:  "em" "+ font=Sans:style=Oblique";
+             tag:  "b" "+ font=Sans:style=Bold";
+             tag:  "link" "+ color=#00000080 underline=on underline_color=#00000080";
+             tag:  "hilight" "+ font=Sans:style=Bold";
+          }
+       }
+      parts {
+        part { name: "elm.text";
+           type: TEXTBLOCK;
+           mouse_events: 1;
+           scale: 1;
+           entry_mode: EDITABLE;
+           select_mode: EXPLICIT;
+           multiline: 0;
+           source: "elm/entry/selection/default"; // selection under
+           source4: "elm/entry/cursor/default"; // cursorover
+           source5: "elm/entry/anchor/default"; // anchor under
+           description { state: "default" 0.0;
+              text {
+                 style: "entry_single_textblock_style";
+                 min: 1 1;
+                  max: 0 1;
+              }
+           }
+           description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+              text {
+                 style: "entry_single_textblock_disabled_style";
+              }
+           }
+        }
+      }
+      programs {
+        program { name: "focus";
+            signal: "load";
+           source: "";
+           action: FOCUS_SET;
+           target: "elm.text";
+        }
+        program { name: "disable";
+           signal: "elm,state,disabled";
+           source: "elm";
+           action: STATE_SET "disabled" 0.0;
+           target: "elm.text";
+        }
+        program { name: "enable";
+           signal: "elm,state,enabled";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "elm.text";
+        }
+      }
+   }
+
+   group { name: "elm/entry/base-single-noedit/default";
+      parts {
+        part { name: "elm.text";
+           type: TEXTBLOCK;
+           mouse_events: 1;
+           scale: 1;
+           entry_mode: PLAIN;
+           select_mode: EXPLICIT;
+           multiline: 0;
+           source: "elm/entry/selection/default"; // selection under
+           source5: "elm/entry/anchor/default"; // anchor under
+           description { state: "default" 0.0;
+              text {
+                 style: "entry_single_textblock_style";
+                 min: 1 1;
+                  max: 0 1;
+              }
+           }
+           description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+              text {
+                 style: "entry_single_textblock_disabled_style";
+              }
+           }
+        }
+      }
+      programs {
+        program { name: "focus";
+            signal: "load";
+           source: "";
+           action: FOCUS_SET;
+           target: "elm.text";
+        }
+        program { name: "disable";
+           signal: "elm,state,disabled";
+           source: "elm";
+           action: STATE_SET "disabled" 0.0;
+           target: "elm.text";
+        }
+        program { name: "enable";
+           signal: "elm,state,enabled";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "elm.text";
+        }
+      }
+   }
+
+   group { name: "elm/entry/base-noedit/default";
+      parts {
+        part { name: "elm.text";
+           type: TEXTBLOCK;
+           mouse_events: 1;
+           scale: 1;
+           entry_mode: PLAIN;
+           select_mode: EXPLICIT;
+           multiline: 1;
+           source: "elm/entry/selection/default"; // selection under
+           source5: "elm/entry/anchor/default"; // anchor under
+           description { state: "default" 0.0;
+               fixed: 1 0;
+              text {
+                 style: "entry_textblock_style";
+                 min: 0 1;
+              }
+           }
+           description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+              text {
+                 style: "entry_textblock_disabled_style";
+              }
+           }
+        }
+      }
+      programs {
+        program { name: "focus";
+            signal: "load";
+           source: "";
+           action: FOCUS_SET;
+           target: "elm.text";
+        }
+        program { name: "disable";
+           signal: "elm,state,disabled";
+           source: "elm";
+           action: STATE_SET "disabled" 0.0;
+           target: "elm.text";
+        }
+        program { name: "enable";
+           signal: "elm,state,enabled";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "elm.text";
+        }
+      }
+   }
+
+   group { name: "elm/entry/base-noedit-charwrap/default";
+      parts {
+        part { name: "elm.text";
+           type: TEXTBLOCK;
+           mouse_events: 1;
+           scale: 1;
+           entry_mode: PLAIN;
+           select_mode: EXPLICIT;
+           multiline: 1;
+           source: "elm/entry/selection/default"; // selection under
+           source5: "elm/entry/anchor/default"; // anchor under
+           description { state: "default" 0.0;
+               fixed: 1 0;
+              text {
+                 style: "entry_textblock_style_charwrap";
+                 min: 0 1;
+              }
+           }
+           description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+              text {
+                 style: "entry_textblock_disabled_style_charwrap";
+              }
+           }
+        }
+      }
+      programs {
+        program { name: "focus";
+            signal: "load";
+           source: "";
+           action: FOCUS_SET;
+           target: "elm.text";
+        }
+        program { name: "disable";
+           signal: "elm,state,disabled";
+           source: "elm";
+           action: STATE_SET "disabled" 0.0;
+           target: "elm.text";
+        }
+        program { name: "enable";
+           signal: "elm,state,enabled";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "elm.text";
+        }
+      }
+   }
+
+   group { name: "elm/entry/base-nowrap-noedit/default";
+      parts {
+        part { name: "elm.text";
+           type: TEXTBLOCK;
+           mouse_events: 1;
+           scale: 1;
+           entry_mode: PLAIN;
+           select_mode: EXPLICIT;
+           multiline: 1;
+           source: "elm/entry/selection/default"; // selection under
+           source5: "elm/entry/anchor/default"; // anchor under
+           description { state: "default" 0.0;
+              text {
+                 style: "entry_textblock_style";
+                 min: 1 1;
+              }
+           }
+           description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+              text {
+                 style: "entry_textblock_disabled_style";
+              }
+           }
+        }
+      }
+      programs {
+        program { name: "focus";
+            signal: "load";
+           source: "";
+           action: FOCUS_SET;
+           target: "elm.text";
+        }
+        program { name: "disable";
+           signal: "elm,state,disabled";
+           source: "elm";
+           action: STATE_SET "disabled" 0.0;
+           target: "elm.text";
+        }
+        program { name: "enable";
+           signal: "elm,state,enabled";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "elm.text";
+        }
+      }
+   }
+
+  group { name: "elm/entry/base-password/default";
+      parts {
+        part { name: "elm.text";
+           type: TEXTBLOCK;
+           mouse_events: 1;
+           scale: 1;
+           entry_mode: PASSWORD;
+           select_mode: EXPLICIT;
+           multiline: 0;
+           source: "elm/entry/selection/default"; // selection under
+           source4: "elm/entry/cursor/default"; // cursorover
+           source5: "elm/entry/anchor/default"; // anchor under
+           description { state: "default" 0.0;
+              text {
+                 style: "entry_single_textblock_style";
+                 repch: "*";
+                 min: 1 1;
+                  max: 0 1;
+              }
+           }
+           description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+              text {
+                 style: "entry_single_textblock_disabled_style";
+              }
+           }
+        }
+      }
+      programs {
+        program { name: "focus";
+            signal: "load";
+           source: "";
+           action: FOCUS_SET;
+           target: "elm.text";
+        }
+        program { name: "disable";
+           signal: "elm,state,disabled";
+           source: "elm";
+           action: STATE_SET "disabled" 0.0;
+           target: "elm.text";
+        }
+        program { name: "enable";
+           signal: "elm,state,enabled";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "elm.text";
+        }
+      }
+   }
+
+   group { name: "elm/entry/cursor/default";
+      images {
+        image: "cur_box.png" COMP;
+        image: "cur_hi.png" COMP;
+        image: "cur_shad.png" COMP;
+        image: "cur_shine.png" COMP;
+        image: "cur_glow.png" COMP;
+      }
+      parts {
+         part { name: "clip2";
+           type: RECT;
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "clip";
+              rel2.to: "clip";
+               visible: 0;
+           }
+           description { state: "focused" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+           }
+        }
+         part { name: "clip";
+           type: RECT;
+           mouse_events: 0;
+            clip_to: "clip2";
+           description { state: "default" 0.0;
+              rel1.offset: -10 0;
+              rel2.offset: 9 9;
+           }
+           description { state: "hidden" 0.0;
+              inherit: "default" 0.0;
+              visible: 0;
+           }
+        }
+         part { name: "bg";
+           mouse_events: 0;
+           clip_to: "clip";
+           description { state: "default" 0.0;
+              rel1.to: "base";
+              rel1.offset: -2 0;
+              rel2.to: "base";
+              rel2.offset: 1 1;
+              image.border: 2 2 2 2;
+              image.normal: "cur_shad.png";
+           }
+        }
+         part { name: "base";
+           mouse_events: 0;
+           scale: 1;
+           clip_to: "clip";
+           description { state: "default" 0.0;
+              min: 2 2;
+              align: 0.5 1.0;
+              rel1.relative: 0.0 1.0;
+              rel1.offset: 0 -1;
+              rel2.relative: 1.0 1.0;
+              rel2.offset: -1 -1;
+              image.normal: "cur_box.png";
+           }
+        }
+         part { name: "hi";
+           mouse_events: 0;
+           clip_to: "clip";
+           description { state: "default" 0.0;
+              rel1.to: "base";
+              rel2.to: "base";
+              rel2.relative: 1.0 0.5;
+              image.normal: "cur_hi.png";
+           }
+        }
+         part { name: "shine";
+           mouse_events: 0;
+           clip_to: "clip";
+            clip_to: "clip2";
+           description { state: "default" 0.0;
+              rel1.to: "base";
+              rel2.to: "base";
+              rel2.relative: 1.0 0.75;
+              image.border: 2 2 1 0;
+              image.normal: "cur_shine.png";
+              fill.smooth: 0;
+           }
+        }
+         part { name: "glow";
+           mouse_events: 0;
+            clip_to: "clip2";
+           description { state: "default" 0.0;
+              rel1.to: "base";
+              rel1.relative: 0.0 -2.0;
+              rel1.offset: -2 0;
+              rel2.to: "base";
+              rel2.relative: 1.0 0.0;
+              rel2.offset: 1 1;
+              image.border: 2 2 0 4;
+              image.normal: "cur_glow.png";
+              fill.smooth: 0;
+           }
+           description { state: "hidden" 0.0;
+              inherit: "default" 0.0;
+              color: 255 255 255 0;
+           }
+        }
+      }
+      programs {
+        program { name: "show";
+            signal: "show";
+           source: "";
+            action: STATE_SET "hidden" 0.0;
+           in: 1.0 0.0;
+           transition: DECELERATE 2.0;
+           target: "glow";
+           after: "show2";
+        }
+        program { name: "show2";
+            action: STATE_SET "hidden" 0.0;
+           in: 0.2 0.0;
+           target: "clip";
+           after: "show3";
+        }
+        program { name: "show3";
+            action: STATE_SET "default" 0.0;
+           in: 0.5 0.0;
+           target: "clip";
+           after: "show4";
+        }
+        program { name: "show4";
+            action: STATE_SET "default" 0.0;
+           in: 0.5 0.0;
+           transition: DECELERATE 0.5;
+           target: "glow";
+           after: "show";
+        }
+        program { name: "focused";
+           signal: "elm,action,focus";
+           source: "elm";
+            action: STATE_SET "focused" 0.0;
+           target: "clip2";
+        }
+        program { name: "unfocused";
+           signal: "elm,action,unfocus";
+           source: "elm";
+            action: STATE_SET "default" 0.0;
+           target: "clip2";
+        }
+      }
+   }
+
+   group { name: "elm/entry/selection/default";
+      parts {
+         part { name: "bg";
+           type: RECT;
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              color: 128 128 128 128;
+           }
+        }
+      }
+   }
+
+   group { name: "elm/entry/anchor/default";
+      parts {
+         part { name: "bg";
+           type: RECT;
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              color: 128 0 0 64;
+           }
+        }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+  group { name: "elm/bubble/top_left/default";
+    alias: "elm/bubble/base/default";
+    images {
+      image: "bubble_3.png" COMP;
+      image: "bubble_shine3.png" COMP;
+    }
+    parts {
+      part { name: "elm.swallow.icon";
+        type: SWALLOW;
+        description { state: "default" 0.0;
+          fixed: 1 1;
+          align: 0.0 0.0;
+          aspect: 1.0 1.0;
+          aspect_preference: VERTICAL;
+          rel1 {
+            relative: 0.0 0.0;
+            offset: 4 4;
+          }
+          rel2 {
+            to_y: "elm.text";
+            relative: 0.0 1.0;
+            offset: 4 -1;
+          }
+        }
+      }
+      part { name: "elm.text";
+        type: TEXT;
+        mouse_events:   0;
+        scale: 1;
+        description { state: "default" 0.0;
+          align: 0.0 0.0;
+          fixed: 0 1;
+          rel1 {
+            to_x: "elm.swallow.icon";
+            relative: 1.0 0.0;
+            offset: 4 4;
+          }
+          rel2 {
+            to_x: "elm.info";
+            relative: 0.0 0.0;
+            offset: -5 4;
+          }
+          color: 0 0 0 255;
+          text {
+            font: "Sans:style=Bold,Edje-Vera-Bold";
+            size: 10;
+            min: 0 1;
+            max: 0 1;
+            align: 0.0 0.0;
+          }
+        }
+      }
+      part { name: "elm.info";
+        type: TEXT;
+        mouse_events:   0;
+        scale: 1;
+        description { state: "default" 0.0;
+          align: 1.0 0.0;
+          fixed: 1 1;
+          rel1 {
+            relative: 1.0 0.0;
+            offset: -5 4;
+          }
+          rel2 {
+            relative: 1.0 0.0;
+            offset: -5 4;
+          }
+          color: 0 0 0 64;
+          text {
+            font: "Sans:style=Bold,Edje-Vera-Bold";
+            size: 10;
+            min: 1 1;
+            max: 1 1;
+            align: 1.0 0.0;
+          }
+        }
+      }
+      part { name: "base0";
+        mouse_events:  0;
+        description { state: "default" 0.0;
+          rel1 {
+            to_y: "elm.swallow.icon";
+            relative: 0.0 1.0;
+            offset: 0 0;
+          }
+          image {
+            normal: "bubble_3.png";
+            border: 36 11 18 9;
+          }
+          image.middle: SOLID;
+          fill.smooth: 0;
+        }
+      }
+      part { name: "elm.swallow.content";
+        type: SWALLOW;
+        description { state: "default" 0.0;
+          rel1 {
+            to: "base0";
+            offset: 9 16;
+          }
+          rel2 {
+            to: "base0";
+            offset: -10 -9;
+          }
+        }
+      }
+      part { name: "shine";
+        mouse_events:  0;
+        description { state:    "default" 0.0;
+          rel1 {
+            to: "base0";
+            offset: 5 4;
+          }
+          rel2 {
+            to: "base0";
+            relative: 1.0 0.5;
+            offset: -6 7;
+          }
+          image {
+            normal: "bubble_shine3.png";
+            border: 36 5 14 0;
+          }
+          fill.smooth: 0;
+        }
+      }
+    }
+  }
+
+  group { name: "elm/bubble/top_right/default";
+    images {
+      image: "bubble_4.png" COMP;
+      image: "bubble_shine4.png" COMP;
+    }
+    parts {
+      part { name: "elm.swallow.icon";
+        type: SWALLOW;
+        description { state: "default" 0.0;
+          fixed: 1 1;
+          align: 1.0 0.0;
+          aspect: 1.0 1.0;
+          aspect_preference: VERTICAL;
+          rel1 {
+            relative: 1.0 0.0;
+            offset: -5 4;
+          }
+          rel2 {
+            to_y: "elm.text";
+            relative: 1.0 1.0;
+            offset: -5 -1;
+          }
+        }
+      }
+      part { name: "elm.text";
+        type: TEXT;
+        mouse_events:   0;
+        scale: 1;
+        description { state: "default" 0.0;
+          align: 0.0 0.0;
+          fixed: 0 1;
+          rel1 {
+            relative: 0.0 0.0;
+            offset: 4 4;
+          }
+          rel2 {
+            to_x: "elm.info";
+            relative: 0.0 0.0;
+            offset: -5 4;
+          }
+          color: 0 0 0 255;
+          text {
+            font: "Sans:style=Bold,Edje-Vera-Bold";
+            size: 10;
+            min: 0 1;
+            max: 0 1;
+            align: 0.0 0.0;
+          }
+        }
+      }
+      part { name: "elm.info";
+        type: TEXT;
+        mouse_events:   0;
+        scale: 1;
+        description { state: "default" 0.0;
+          align: 1.0 0.0;
+          fixed: 1 1;
+          rel1 {
+            relative: 1.0 0.0;
+            offset: -5 4;
+          }
+          rel2 {
+            to_x: "elm.swallow.icon";
+            relative: 0.0 0.0;
+            offset: -5 4;
+          }
+          color: 0 0 0 64;
+          text {
+            font: "Sans:style=Bold,Edje-Vera-Bold";
+            size: 10;
+            min: 1 1;
+            max: 1 1;
+            align: 1.0 0.0;
+          }
+        }
+      }
+      part { name: "base0";
+        mouse_events:  0;
+        description { state: "default" 0.0;
+          rel1 {
+            to_y: "elm.swallow.icon";
+            relative: 0.0 1.0;
+            offset: 0 0;
+          }
+          image {
+            normal: "bubble_4.png";
+            border: 11 36 18 9;
+          }
+          image.middle: SOLID;
+          fill.smooth: 0;
+        }
+      }
+      part { name: "elm.swallow.content";
+        type: SWALLOW;
+        description { state: "default" 0.0;
+          rel1 {
+            to: "base0";
+            offset: 9 16;
+          }
+          rel2 {
+            to: "base0";
+            offset: -10 -9;
+          }
+        }
+      }
+      part { name: "shine";
+        mouse_events:  0;
+        description { state:    "default" 0.0;
+          rel1 {
+            to: "base0";
+            offset: 5 4;
+          }
+          rel2 {
+            to: "base0";
+            relative: 1.0 0.5;
+            offset: -6 7;
+          }
+          image {
+            normal: "bubble_shine4.png";
+            border: 5 36 14 0;
+          }
+          fill.smooth: 0;
+        }
+      }
+    }
+  }
+
+  group { name: "elm/bubble/bottom_left/default";
+    images {
+      image: "bubble_1.png" COMP;
+      image: "bubble_shine.png" COMP;
+    }
+    parts {
+      part { name: "elm.swallow.icon";
+        type: SWALLOW;
+        description { state: "default" 0.0;
+          fixed: 1 1;
+          align: 0.0 1.0;
+          aspect: 1.0 1.0;
+          aspect_preference: VERTICAL;
+          rel1 {
+            to_y: "elm.text";
+            relative: 0.0 0.0;
+            offset: 4 0;
+          }
+          rel2 {
+            relative: 0.0 1.0;
+            offset: 4 -5;
+          }
+        }
+      }
+      part { name: "elm.text";
+        type: TEXT;
+        mouse_events:   0;
+        scale: 1;
+        description { state: "default" 0.0;
+          align: 0.0 1.0;
+          fixed: 0 1;
+          rel1 {
+            to_x: "elm.swallow.icon";
+            relative: 1.0 1.0;
+            offset: 4 -5;
+          }
+          rel2 {
+            to_x: "elm.info";
+            relative: 0.0 1.0;
+            offset: -5 -5;
+          }
+          color: 0 0 0 255;
+          text {
+            font: "Sans:style=Bold,Edje-Vera-Bold";
+            size: 10;
+            min: 0 1;
+            max: 0 1;
+            align: 0.0 1.0;
+          }
+        }
+      }
+      part { name: "elm.info";
+        type: TEXT;
+        mouse_events:   0;
+        scale: 1;
+        description { state: "default" 0.0;
+          align: 1.0 1.0;
+          fixed: 1 1;
+          rel1 {
+            relative: 1.0 1.0;
+            offset: -5 -5;
+          }
+          rel2 {
+            relative: 1.0 1.0;
+            offset: -5 -5;
+          }
+          color: 0 0 0 64;
+          text {
+            font: "Sans:style=Bold,Edje-Vera-Bold";
+            size: 10;
+            min: 1 1;
+            max: 1 1;
+            align: 1.0 1.0;
+          }
+        }
+      }
+      part { name: "base0";
+        mouse_events:  0;
+        description { state: "default" 0.0;
+          rel2 {
+            to_y: "elm.swallow.icon";
+            relative: 1.0 0.0;
+            offset: -1 -1;
+          }
+          image {
+            normal: "bubble_1.png";
+            border: 36 11 10 19;
+          }
+          image.middle: SOLID;
+          fill.smooth: 0;
+        }
+      }
+      part { name: "elm.swallow.content";
+        type: SWALLOW;
+        description { state: "default" 0.0;
+          rel1 {
+            to: "base0";
+            offset: 9 8;
+          }
+          rel2 {
+            to: "base0";
+            offset: -10 -17;
+          }
+        }
+      }
+      part { name: "shine";
+        mouse_events:  0;
+        description { state:    "default" 0.0;
+          rel1 {
+            to: "base0";
+            offset: 5 4;
+          }
+          rel2 {
+            to: "base0";
+            relative: 1.0 0.5;
+            offset: -6 -16;
+          }
+          image {
+            normal: "bubble_shine.png";
+            border: 5 5 5 0;
+          }
+          fill.smooth: 0;
+        }
+      }
+    }
+  }
+
+  group { name: "elm/bubble/bottom_right/default";
+    images {
+      image: "bubble_2.png" COMP;
+      image: "bubble_shine.png" COMP;
+    }
+    parts {
+      part { name: "elm.swallow.icon";
+        type: SWALLOW;
+        description { state: "default" 0.0;
+          fixed: 1 1;
+          align: 1.0 1.0;
+          aspect: 1.0 1.0;
+          aspect_preference: VERTICAL;
+          rel1 {
+            to_y: "elm.text";
+            relative: 1.0 0.0;
+            offset: -5 0;
+          }
+          rel2 {
+            relative: 1.0 1.0;
+            offset: -5 -5;
+          }
+        }
+      }
+      part { name: "elm.text";
+        type: TEXT;
+        mouse_events:   0;
+        scale: 1;
+        description { state: "default" 0.0;
+          align: 0.0 1.0;
+          fixed: 0 1;
+          rel1 {
+            relative: 0.0 1.0;
+            offset: 4 -5;
+          }
+          rel2 {
+            to_x: "elm.info";
+            relative: 0.0 1.0;
+            offset: -5 -5;
+          }
+          color: 0 0 0 255;
+          text {
+            font: "Sans:style=Bold,Edje-Vera-Bold";
+            size: 10;
+            min: 0 1;
+            max: 0 1;
+            align: 0.0 1.0;
+          }
+        }
+      }
+      part { name: "elm.info";
+        type: TEXT;
+        mouse_events:   0;
+        scale: 1;
+        description { state: "default" 0.0;
+          align: 1.0 1.0;
+          fixed: 1 1;
+          rel1 {
+            relative: 1.0 1.0;
+            offset: -5 -5;
+          }
+          rel2 {
+            to_x: "elm.swallow.icon";
+            relative: 0.0 1.0;
+            offset: -5 -5;
+          }
+          color: 0 0 0 64;
+          text {
+            font: "Sans:style=Bold,Edje-Vera-Bold";
+            size: 10;
+            min: 1 1;
+            max: 1 1;
+            align: 1.0 1.0;
+          }
+        }
+      }
+      part { name: "base0";
+        mouse_events:  0;
+        description { state: "default" 0.0;
+          rel2 {
+            to_y: "elm.swallow.icon";
+            relative: 1.0 0.0;
+            offset: -1 -1;
+          }
+          image {
+            normal: "bubble_2.png";
+            border: 11 36 10 19;
+          }
+          image.middle: SOLID;
+          fill.smooth: 0;
+        }
+      }
+      part { name: "elm.swallow.content";
+        type: SWALLOW;
+        description { state: "default" 0.0;
+          rel1 {
+            to: "base0";
+            offset: 9 8;
+          }
+          rel2 {
+            to: "base0";
+            offset: -10 -17;
+          }
+        }
+      }
+      part { name: "shine";
+        mouse_events:  0;
+        description { state:    "default" 0.0;
+          rel1 {
+            to: "base0";
+            offset: 5 4;
+          }
+          rel2 {
+            to: "base0";
+            relative: 1.0 0.5;
+            offset: -6 -16;
+          }
+          image {
+            normal: "bubble_shine.png";
+            border: 5 5 5 0;
+          }
+          fill.smooth: 0;
+        }
+      }
+    }
+  }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/photo/base/default";
+      images {
+        image: "frame_1.png" COMP;
+        image: "frame_2.png" COMP;
+         image: "dia_grad.png" COMP;
+         image: "head.png" COMP;
+      }
+      parts {
+         part { name: "base0";
+           mouse_events:  0;
+           description { state: "default" 0.0;
+              image.normal: "dia_grad.png";
+              rel1.to: "over";
+              rel2.to: "over";
+               fill {
+                 smooth: 0;
+                 size {
+                    relative: 0.0 1.0;
+                     offset: 64 0;
+                 }
+              }
+           }
+        }
+        part { name: "base";
+           mouse_events:  0;
+           description { state:    "default" 0.0;
+              image {
+                 normal: "frame_2.png";
+                 border: 5 5 32 26;
+                 middle: 0;
+              }
+              fill.smooth : 0;
+           }
+        }
+         part { name: "head";
+           mouse_events:  0;
+           description { state:    "default" 0.0;
+              rel1.offset: 4 4;
+              rel2.offset: -5 -5;
+               aspect: 1.0 1.0;
+               aspect_preference: BOTH;
+              image.normal: "head.png";
+           }
+        }
+         part { name: "clip";
+           mouse_events:  0;
+            type: RECT;
+           description { state:    "default" 0.0;
+              rel1.offset: 4 4;
+              rel2.offset: -5 -5;
+               color: 255 255 255 255;
+           }
+        }
+        part { name: "elm.swallow.content";
+           type: SWALLOW;
+            clip_to: "clip";
+           description { state: "default" 0.0;
+              rel1.offset: 4 4;
+              rel2.offset: -5 -5;
+           }
+        }
+         part { name: "over";
+           mouse_events:  0;
+           description { state:    "default" 0.0;
+              rel1.offset: 4 4;
+              rel2.offset: -5 -5;
+              image {
+                 normal: "frame_1.png";
+                 border: 2 2 28 22;
+                 middle: 0;
+              }
+              fill.smooth: 0;
+           }
+        }
+     }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/thumb/base/default";
+      images {
+        image: "frame_1.png" COMP;
+        image: "frame_2.png" COMP;
+        image: "dia_grad.png" COMP;
+        image: "busy-1.png" COMP;
+        image: "busy-2.png" COMP;
+        image: "busy-3.png" COMP;
+        image: "busy-4.png" COMP;
+        image: "busy-5.png" COMP;
+        image: "busy-6.png" COMP;
+        image: "busy-7.png" COMP;
+        image: "busy-8.png" COMP;
+        image: "busy-9.png" COMP;
+      }
+      parts {
+        part { name: "base0";
+           mouse_events:  0;
+           description { state:        "default" 0.0;
+              image.normal: "dia_grad.png";
+              rel1.to: "over";
+              rel2.to: "over";
+              fill {
+                 smooth: 0;
+                 size {
+                    relative: 0.0 1.0;
+                    offset: 64 0;
+                 }
+              }
+           }
+        }
+        part { name: "base";
+           mouse_events:  0;
+           description { state:        "default" 0.0;
+              image {
+                 normal: "frame_2.png";
+                 border: 5 5 32 26;
+                 middle: 0;
+              }
+              fill.smooth : 0;
+           }
+        }
+        part { name: "clip";
+           mouse_events:  0;
+           type: RECT;
+           description { state:        "default" 0.0;
+              rel1.offset: 4 4;
+              rel2.offset: -5 -5;
+              color: 255 255 255 255;
+           }
+        }
+        part { name: "elm.swallow.content";
+           type: SWALLOW;
+           clip_to: "clip";
+           description { state:        "default" 0.0;
+              rel1.offset: 4 4;
+              rel2.offset: -5 -5;
+           }
+        }
+        part { name: "progress";
+           mouse_events: 0;
+
+           clip_to: "clip";
+           description { state:        "default" 0.0;
+              min: 32 32;
+              max: 32 32;
+              visible: 0;
+              aspect: 1.0 1.0;
+              aspect_preference: BOTH;
+           }
+           description { state:        "pulse" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              image {
+                 normal: "busy-9.png";
+                 tween:  "busy-1.png";
+                 tween:  "busy-2.png";
+                 tween:  "busy-3.png";
+                 tween:  "busy-4.png";
+                 tween:  "busy-5.png";
+                 tween:  "busy-6.png";
+                 tween:  "busy-7.png";
+                 tween:  "busy-8.png";
+                 border: 7 7 7 7;
+              }
+           }
+        }
+        part { name: "over";
+           mouse_events:  0;
+           description { state:        "default" 0.0;
+              rel1.offset: 4 4;
+              rel2.offset: -5 -5;
+              image {
+                 normal: "frame_1.png";
+                 border: 2 2 28 22;
+                 middle: 0;
+              }
+              fill.smooth: 0;
+           }
+        }
+        programs {
+           program { name: "start_pulse";
+              signal: "elm,state,pulse,start";
+              source: "elm";
+              action: STATE_SET "pulse" 0.0;
+              target: "progress";
+              transition: LINEAR 0.5;
+              after: "start_pulse";
+           }
+           program { name: "stop_pulse";
+              signal: "elm,state,pulse,stop";
+              source: "elm";
+              action: STATE_SET "default" 0.0;
+              target: "progress";
+           }
+        }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/icon/home/default"; min: 32 32;
+      images.image: "icon_home.png" COMP; parts { part { name: "base";
+        description { state: "default" 0.0; aspect: 1.0 1.0; aspect_preference: BOTH;
+           image.normal: "icon_home.png"; } } } }
+   group { name: "elm/icon/close/default"; min: 32 32;
+      images.image: "icon_close.png" COMP; parts { part { name: "base";
+        description { state: "default" 0.0; aspect: 1.0 1.0; aspect_preference: BOTH;
+           image.normal: "icon_close.png"; } } } }
+   group { name: "elm/icon/apps/default"; min: 32 32;
+      images.image: "icon_apps.png" COMP; parts { part { name: "base";
+        description { state: "default" 0.0; aspect: 1.0 1.0; aspect_preference: BOTH;
+           image.normal: "icon_apps.png"; } } } }
+   group { name: "elm/icon/arrow_up/default"; min: 32 32;
+      images.image: "icon_arrow_up.png" COMP; parts { part { name: "base";
+        description { state: "default" 0.0; aspect: 1.0 1.0; aspect_preference: BOTH;
+           image.normal: "icon_arrow_up.png"; } } } }
+   group { name: "elm/icon/arrow_down/default"; min: 32 32;
+      images.image: "icon_arrow_down.png" COMP; parts { part { name: "base";
+        description { state: "default" 0.0; aspect: 1.0 1.0; aspect_preference: BOTH;
+           image.normal: "icon_arrow_down.png"; } } } }
+   group { name: "elm/icon/arrow_left/default"; min: 32 32;
+      images.image: "icon_arrow_left.png" COMP; parts { part { name: "base";
+        description { state: "default" 0.0; aspect: 1.0 1.0; aspect_preference: BOTH;
+           image.normal: "icon_arrow_left.png"; } } } }
+   group { name: "elm/icon/arrow_right/default"; min: 32 32;
+      images.image: "icon_arrow_right.png" COMP; parts { part { name: "base";
+        description { state: "default" 0.0; aspect: 1.0 1.0; aspect_preference: BOTH;
+           image.normal: "icon_arrow_right.png"; } } } }
+   group { name: "elm/icon/chat/default"; min: 32 32;
+      images.image: "icon_chat.png" COMP; parts { part { name: "base";
+        description { state: "default" 0.0; aspect: 1.0 1.0; aspect_preference: BOTH;
+           image.normal: "icon_chat.png"; } } } }
+   group { name: "elm/icon/clock/default"; min: 32 32;
+      images.image: "icon_clock.png" COMP; parts { part { name: "base";
+        description { state: "default" 0.0; aspect: 1.0 1.0; aspect_preference: BOTH;
+           image.normal: "icon_clock.png"; } } } }
+   group { name: "elm/icon/delete/default"; min: 32 32;
+      images.image: "icon_delete.png" COMP; parts { part { name: "base";
+        description { state: "default" 0.0; aspect: 1.0 1.0; aspect_preference: BOTH;
+           image.normal: "icon_delete.png"; } } } }
+   group { name: "elm/icon/edit/default"; min: 32 32;
+      images.image: "icon_edit.png" COMP; parts { part { name: "base";
+        description { state: "default" 0.0; aspect: 1.0 1.0; aspect_preference: BOTH;
+           image.normal: "icon_edit.png"; } } } }
+   group { name: "elm/icon/refresh/default"; min: 32 32;
+      images.image: "icon_refresh.png" COMP; parts { part { name: "base";
+        description { state: "default" 0.0; aspect: 1.0 1.0; aspect_preference: BOTH;
+           image.normal: "icon_refresh.png"; } } } }
+   group { name: "elm/icon/folder/default"; min: 32 32;
+      images.image: "icon_folder.png" COMP; parts { part { name: "base";
+        description { state: "default" 0.0; aspect: 1.0 1.0; aspect_preference: BOTH;
+           image.normal: "icon_folder.png"; } } } }
+   group { name: "elm/icon/file/default"; min: 32 32;
+      images.image: "icon_file.png" COMP; parts { part { name: "base";
+        description { state: "default" 0.0; aspect: 1.0 1.0; aspect_preference: BOTH;
+           image.normal: "icon_file.png"; } } } }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/toolbar/base/default";
+      images {
+         image: "bt_dis_base.png" COMP;
+         image: "bt_dis_hilight.png" COMP;
+         image: "bt_dis_shine.png" COMP;
+         image: "icon_left_arrow.png" COMP;
+         image: "icon_right_arrow.png" COMP;
+      }
+      parts {
+         part { name: "base";
+            mouse_events: 1;
+            description { state: "default" 0.0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: 2 2;
+               }
+               rel2.offset: -3 -3;
+               image {
+                  normal: "bt_dis_base.png";
+                  border: 4 4 4 4;
+               }
+               image.middle: SOLID;
+            }
+         }
+         part { name: "clipper";
+            type: RECT;
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               rel1 {
+                  to: "base";
+                  offset: 2 2;
+               }
+               rel2 {
+                  to: "base";
+                  offset: -3 -3;
+               }
+            }
+         }
+         part { name: "elm.swallow.content";
+            clip_to: "clipper";
+            type: SWALLOW;
+            description {
+               state: "default" 0.0;
+               rel1.to: "clipper";
+               rel2.to: "clipper";
+            }
+         }
+         part { name: "over2";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               rel1.to: "base";
+               rel2.to: "base";
+               image {
+                  normal: "bt_dis_shine.png";
+                  border: 4 4 4 4;
+               }
+            }
+         }
+         part { name: "over1";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               rel1.to: "base";
+               rel2.to: "base";
+               rel2.relative: 1.0 0.5;
+               image {
+                  normal: "bt_dis_hilight.png";
+                  border: 4 4 4 0;
+               }
+               color: 255 255 255 128;
+            }
+         }
+         part { name: "left_arrow";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               image.normal: "icon_left_arrow.png";
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               align: 0.0 0.5;
+               min: 32 32;
+               max: 32 32;
+            }
+            description { state: "hidden" 0.0;
+               inherit: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+            }
+         }
+         part { name: "right_arrow";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               image.normal: "icon_right_arrow.png";
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               align: 1.0 0.5;
+               min: 32 32;
+               max: 32 32;
+            }
+            description { state: "hidden" 0.0;
+               inherit: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+            }
+         }
+         part { name: "event";
+            type: RECT;
+            mouse_events: 1;
+            repeat_events: 1;
+            description { state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+      }
+      programs {
+         program { name: "sb_hbar_show";
+            signal: "elm,action,show,hbar";
+            source: "elm";
+            action:  STATE_SET "default" 0.0;
+            transition: LINEAR 0.5;
+            target: "left_arrow";
+            target: "right_arrow";
+         }
+         program { name: "sb_hbar_hide";
+            signal: "elm,action,hide,hbar";
+            source: "elm";
+            action:  STATE_SET "hidden" 0.0;
+            target: "left_arrow";
+            target: "right_arrow";
+            transition: LINEAR 0.5;
+         }
+      }
+   }
+
+   group { name: "elm/toolbar/item/default";
+       images {
+           image: "toolbar_sel.png" COMP;
+       }
+       parts {
+           part { name: "label2";
+               type: TEXT;
+               mouse_events:  0;
+               scale: 1;
+               description { state: "default" 0.0;
+                   align: 0.5 1.0;
+                   fixed: 0 1;
+                   rel1.to: "elm.text";
+                   rel2.to: "elm.text";
+                   color: 0 0 0 255;
+                   text {
+                       font: "Sans";
+                       text_source: "elm.text";
+                       size: 10;
+                       min: 1 1;
+                       align: 0.5 0.5;
+                   }
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 0;
+               }
+               description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 128;
+                   color3: 0 0 0 0;
+               }
+               description { state: "disabled_visible" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 128;
+                   color3: 0 0 0 0;
+                   visible: 1;
+                   text.min: 1 1;
+               }
+           }
+           part { name: "bg";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+                   image {
+                       normal: "toolbar_sel.png";
+                       border: 3 3 0 0;
+                   }
+                   image.middle: SOLID;
+                   fill.smooth: 0;
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+               description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+               }
+           }
+           part { name: "elm.swallow.icon";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   align: 0.5 0.5;
+                   fixed: 0 0;
+                   //aspect: 1.0 1.0;
+                   //aspect_preference: VERTICAL;
+                   rel1 {
+                       relative: 0.0 0.0;
+                       offset: 2 2;
+                   }
+                   rel2 {
+                       to_y: "elm.text";
+                       relative: 1.0 0.0;
+                       offset: -3 -1;
+                   }
+                   color: 0 0 0 0;
+               }
+           }
+           part { name: "elm.text";
+               type: TEXT;
+               effect: SOFT_SHADOW;
+               mouse_events:  0;
+               scale: 1;
+               description { state: "default" 0.0;
+                   align: 0.5 1.0;
+                   fixed: 0 1;
+                   rel1 {
+                       relative: 0.0 1.0;
+                       offset:   0 -1;
+                   }
+                   rel2 {
+                       relative: 1.0 1.0;
+                       offset:   -1 -1;
+                   }
+                   visible: 0;
+                   color: 224 224 224 255;
+                   color3: 0 0 0 32;
+                   text {
+                       font: "Sans:style=Bold";
+                       size: 10;
+                       min: 1 1;
+                       align: 0.5 0.5;
+                   }
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   text.min: 1 1;
+               }
+               description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 128;
+                   color3: 0 0 0 0;
+               }
+               description { state: "disabled_visible" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 128;
+                   color3: 0 0 0 0;
+                   visible: 1;
+                   text.min: 1 1;
+               }
+           }
+           part { name: "event";
+               type: RECT;
+               mouse_events: 1;
+               ignore_flags: ON_HOLD;
+               description { state: "default" 0.0;
+                   color: 0 0 0 0;
+               }
+           }
+       }
+       programs {
+           program { name: "go_active";
+               signal:  "elm,state,selected";
+               source:  "elm";
+               action:  STATE_SET "selected" 0.0;
+               target:  "bg";
+               target:  "elm.text";
+               target:  "label2";
+               transition: LINEAR 0.2;
+           }
+           program { name: "go_passive";
+               signal:  "elm,state,unselected";
+               source:  "elm";
+               action:  STATE_SET "default" 0.0;
+               target:  "bg";
+               target:  "elm.text";
+               target:  "label2";
+               transition: LINEAR 0.1;
+           }
+           program { name: "go";
+               signal:  "mouse,up,1";
+               source:  "event";
+               action:  SIGNAL_EMIT "elm,action,click" "elm";
+           }
+           program { name: "disable";
+               signal: "elm,state,disabled";
+               source: "elm";
+               action: STATE_SET "disabled" 0.0;
+               target: "label2";
+               target: "bg";
+               after: "disable_text";
+           }
+           program { name: "disable_text";
+               script {
+                   new st[31];
+                   new Float:vl;
+                   get_state(PART:"elm.text", st, 30, vl);
+                   if (!strcmp(st, "visible"))
+                   set_state(PART:"elm.text", "disabled_visible", 0.0);
+                   else
+                   set_state(PART:"elm.text", "disabled", 0.0);
+               }
+           }
+           program { name: "enable";
+               signal: "elm,state,enabled";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "label2";
+               target: "bg";
+               after: "enable_text";
+           }
+           program { name: "enable_text";
+               script {
+                   new st[31];
+                   new Float:vl;
+                   get_state(PART:"elm.text", st, 30, vl);
+                   if (!strcmp(st, "disabled_visible"))
+                   set_state(PART:"elm.text", "visible", 0.0);
+                   else
+                   set_state(PART:"elm.text", "default", 0.0);
+               }
+           }
+       }
+   }
+
+   group { name: "elm/toolbar/separator/default";
+      images {
+         image: "toolbar_separator_v.png" COMP;
+      }
+      parts {
+         part { name: "separator"; // separator group
+            description { state: "default" 0.0;
+               min: 2 2;
+               max: 2 9999;
+              rel1.offset: 4 4;
+              rel2.offset: -5 -5;
+              image {
+                 normal: "toolbar_separator_v.png";
+              }
+              fill {
+                 smooth: 0;
+              }
+           }
+        }
+      }
+   }
+
+   ///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/notify/block_events/default";
+       parts {
+           part { name: "block_events";
+               type: RECT;
+               description { state: "default" 0.0;
+                   color: 0 0 0 64;
+                   visible: 1;
+               }
+           }
+       }
+          programs {
+                  program {
+                               name: "block_clicked";
+                               signal: "mouse,clicked,1";
+                               source: "block_events";
+                               action: SIGNAL_EMIT "elm,action,clicked" "elm";
+                  }
+          }
+   }
+   group { name: "elm/notify/base/default";
+       //this group is a design similar to the inwin group
+       images {
+           image: "shad_circ.png" COMP;
+           image: "bt_dis_base.png" COMP;
+           image: "bt_dis_hilight.png" COMP;
+       }
+       parts {
+           part { name: "base";
+               type: RECT;
+               mouse_events: 0;
+               repeat_events: 1;
+               description { state: "default" 0.0;
+                   color: 0 0 0 0;
+                   rel1.offset: 10 10;
+                   rel2.offset: -10 -10;
+                   rel1.relative: 0.0 -1.0;
+                   rel2.relative: 1.0 0.0;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 64;
+                   rel1.relative: 0.0 0.0;
+                   rel2.relative: 1.0 1.0;
+               }
+           }
+           part { name: "shad";
+               mouse_events:  0;
+               description { state: "default" 0.0;
+                   image.normal: "shad_circ.png";
+                   rel1.to: "elm.swallow.content";
+                   rel1.offset: -64 -64;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 63 63;
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "pop";
+               mouse_events: 1;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.swallow.content";
+                   rel1.offset: -5 -5;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 4 4;
+                   image {
+                       normal: "bt_dis_base.png";
+                       border: 4 4 4 4;
+                   }
+                   image.middle: SOLID;
+               }
+           }
+           part { name: "popover";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "pop";
+                   rel2.to: "pop";
+                   rel2.relative: 1.0 0.5;
+                   image {
+                       normal: "bt_dis_hilight.png";
+                       border: 4 4 4 0;
+                   }
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel2.to: "base";
+               }
+           }
+       }
+       programs {
+           program { name: "show";
+               signal: "elm,action,show";
+               source: "elm";
+               action: STATE_SET "visible" 0.0;
+               target: "base";
+           }
+           program { name: "show_2";
+                signal: "show";
+                action: STATE_SET "default" 0.0;
+                target: "base";
+                after: "show_3";
+           }
+           program { name: "show_3";
+                signal: "show";
+                action: STATE_SET "visible" 0.0;
+                target: "base";
+                transition: LINEAR 0.5;
+           }
+           program { name: "hide";
+               signal: "elm,action,hide";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "base";
+           }
+       }
+   }
+   group { name: "elm/notify/base/center";
+       //this group is a design similar to the inwin group
+       images {
+           image: "bt_dis_base.png" COMP;
+       }
+       parts {
+           part { name: "base";
+               type: RECT;
+               mouse_events: 0;
+               repeat_events: 1;
+               description { state: "default" 0.0;
+                   color: 0 0 0 0;
+                   rel1.relative: 0.0 0.0;
+                   rel2.relative: 1.0 1.0;
+               }
+           }
+           part { name: "pop";
+               mouse_events: 1;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.swallow.content";
+                   rel1.offset: -5 -5;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 4 4;
+                   image {
+                       normal: "bt_dis_base.png";
+                       border: 4 4 4 4;
+                   }
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel2.to: "base";
+               }
+           }
+       }
+       programs {
+           program { name: "show";
+               signal: "elm,action,show";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "base";
+           }
+           program { name: "show_2";
+                signal: "show";
+                action: STATE_SET "default" 0.0;
+                target: "base";
+           }
+           program { name: "hide";
+               signal: "elm,action,hide";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "base";
+           }
+       }
+   }
+   group { name: "elm/notify/base/bottom";
+       //this group is a design similar to the inwin group
+       images {
+           image: "shad_circ.png" COMP;
+           image: "bt_dis_base.png" COMP;
+           image: "bt_dis_hilight.png" COMP;
+       }
+       parts {
+           part { name: "base";
+               type: RECT;
+               mouse_events: 0;
+               repeat_events: 1;
+               description { state: "default" 0.0;
+                   color: 0 0 0 0;
+                   rel1.offset: 10 10;
+                   rel2.offset: -10 -10;
+                   rel1.relative: 0.0 1.0;
+                   rel2.relative: 1.0 2.0;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 64;
+                   rel1.relative: 0.0 0.0;
+                   rel2.relative: 1.0 1.0;
+               }
+           }
+           part { name: "shad";
+               mouse_events:  0;
+               description { state: "default" 0.0;
+                   image.normal: "shad_circ.png";
+                   rel1.to: "elm.swallow.content";
+                   rel1.offset: -64 -64;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 63 63;
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "pop";
+               mouse_events: 1;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.swallow.content";
+                   rel1.offset: -5 -5;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 4 4;
+                   image {
+                       normal: "bt_dis_base.png";
+                       border: 4 4 4 4;
+                   }
+                   image.middle: SOLID;
+               }
+           }
+           part { name: "popover";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "pop";
+                   rel2.to: "pop";
+                   rel2.relative: 1.0 0.5;
+                   image {
+                       normal: "bt_dis_hilight.png";
+                       border: 4 4 4 0;
+                   }
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel2.to: "base";
+               }
+           }
+       }
+       programs {
+           program { name: "show";
+               signal: "elm,action,show";
+               source: "elm";
+               action: STATE_SET "visible" 0.0;
+               target: "base";
+           }
+           program { name: "show_2";
+                signal: "show";
+                action: STATE_SET "default" 0.0;
+                target: "base";
+                after: "show_3";
+           }
+           program { name: "show_3";
+                signal: "show";
+                action: STATE_SET "visible" 0.0;
+                target: "base";
+                transition: LINEAR 0.5;
+           }
+           program { name: "hide";
+               signal: "elm,action,hide";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "base";
+           }
+       }
+   }
+   group { name: "elm/notify/base/left";
+       //this group is a design similar to the inwin group
+       images {
+           image: "shad_circ.png" COMP;
+           image: "bt_dis_base.png" COMP;
+           image: "bt_dis_hilight.png" COMP;
+       }
+       parts {
+           part { name: "base";
+               type: RECT;
+               mouse_events: 0;
+               repeat_events: 1;
+               description { state: "default" 0.0;
+                   color: 0 0 0 0;
+                   rel1.offset: 10 10;
+                   rel2.offset: -10 -10;
+                   rel1.relative: -1.0 0.0;
+                   rel2.relative: 0.0 1.0;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 64;
+                   rel1.relative: 0.0 0.0;
+                   rel2.relative: 1.0 1.0;
+               }
+           }
+           part { name: "shad";
+               mouse_events:  0;
+               description { state: "default" 0.0;
+                   image.normal: "shad_circ.png";
+                   rel1.to: "elm.swallow.content";
+                   rel1.offset: -64 -64;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 63 63;
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "pop";
+               mouse_events: 1;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.swallow.content";
+                   rel1.offset: -5 -5;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 4 4;
+                   image {
+                       normal: "bt_dis_base.png";
+                       border: 4 4 4 4;
+                   }
+                   image.middle: SOLID;
+               }
+           }
+           part { name: "popover";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "pop";
+                   rel2.to: "pop";
+                   rel2.relative: 1.0 0.5;
+                   image {
+                       normal: "bt_dis_hilight.png";
+                       border: 4 4 4 0;
+                   }
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel2.to: "base";
+               }
+           }
+       }
+       programs {
+           program { name: "show";
+               signal: "elm,action,show";
+               source: "elm";
+               action: STATE_SET "visible" 0.0;
+               target: "base";
+           }
+           program { name: "show_2";
+               signal: "show";
+               action: STATE_SET "default" 0.0;
+               target: "base";
+               after: "show_3";
+           }
+           program { name: "show_3";
+               signal: "show";
+               action: STATE_SET "visible" 0.0;
+               target: "base";
+               transition: LINEAR 0.5;
+           }
+           program { name: "hide";
+               signal: "elm,action,hide";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "base";
+           }
+       }
+   }
+   group { name: "elm/notify/base/right";
+       //this group is a design similar to the inwin group
+       images {
+           image: "shad_circ.png" COMP;
+           image: "bt_dis_base.png" COMP;
+           image: "bt_dis_hilight.png" COMP;
+       }
+       parts {
+           part { name: "base";
+               type: RECT;
+               mouse_events: 0;
+               repeat_events: 1;
+                description { state: "default" 0.0;
+                   color: 0 0 0 0;
+                   rel1.offset: 10 10;
+                   rel2.offset: -10 -10;
+                   rel1.relative: 1.0 0.0;
+                   rel2.relative: 2.0 1.0;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 64;
+                   rel1.relative: 0.0 0.0;
+                   rel2.relative: 1.0 1.0;
+               }
+           }
+           part { name: "shad";
+               mouse_events:  0;
+               description { state: "default" 0.0;
+                   image.normal: "shad_circ.png";
+                   rel1.to: "elm.swallow.content";
+                   rel1.offset: -64 -64;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 63 63;
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "pop";
+               mouse_events: 1;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.swallow.content";
+                   rel1.offset: -5 -5;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 4 4;
+                   image {
+                       normal: "bt_dis_base.png";
+                       border: 4 4 4 4;
+                   }
+                   image.middle: SOLID;
+               }
+           }
+           part { name: "popover";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "pop";
+                   rel2.to: "pop";
+                   rel2.relative: 1.0 0.5;
+                   image {
+                       normal: "bt_dis_hilight.png";
+                       border: 4 4 4 0;
+                   }
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel2.to: "base";
+               }
+           }
+       }
+       programs {
+           program { name: "show";
+               signal: "elm,action,show";
+               source: "elm";
+               action: STATE_SET "visible" 0.0;
+               target: "base";
+           }
+           program { name: "show_2";
+               signal: "show";
+               action: STATE_SET "default" 0.0;
+               target: "base";
+               after: "show_3";
+           }
+           program { name: "show_3";
+               signal: "show";
+               action: STATE_SET "visible" 0.0;
+               target: "base";
+               transition: LINEAR 0.5;
+           }
+           program { name: "hide";
+               signal: "elm,action,hide";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "base";
+           }
+       }
+   }
+   group { name: "elm/notify/base/top_left";
+       //this group is a design similar to the inwin group
+       images {
+           image: "shad_circ.png" COMP;
+           image: "bt_dis_base.png" COMP;
+           image: "bt_dis_hilight.png" COMP;
+       }
+       parts {
+           part { name: "base";
+               type: RECT;
+               mouse_events: 0;
+               repeat_events: 1;
+                description { state: "default" 0.0;
+                   color: 0 0 0 0;
+                   rel1.offset: 10 10;
+                   rel2.offset: -10 -10;
+                   rel1.relative: 0.0 -1.0;
+                   rel2.relative: 1.0 0.0;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 64;
+                   rel1.relative: 0.0 0.0;
+                   rel2.relative: 1.0 1.0;
+               }
+           }
+           part { name: "shad";
+               mouse_events:  0;
+               description { state: "default" 0.0;
+                   image.normal: "shad_circ.png";
+                   rel1.to: "elm.swallow.content";
+                   rel1.offset: -64 -64;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 63 63;
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "pop";
+               mouse_events: 1;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.swallow.content";
+                   rel1.offset: -5 -5;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 4 4;
+                   image {
+                       normal: "bt_dis_base.png";
+                       border: 4 4 4 4;
+                   }
+                   image.middle: SOLID;
+               }
+           }
+           part { name: "popover";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "pop";
+                   rel2.to: "pop";
+                   rel2.relative: 1.0 0.5;
+                   image {
+                       normal: "bt_dis_hilight.png";
+                       border: 4 4 4 0;
+                   }
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel2.to: "base";
+               }
+           }
+       }
+       programs {
+           program { name: "show";
+               signal: "elm,action,show";
+               source: "elm";
+               action: STATE_SET "visible" 0.0;
+               target: "base";
+           }
+           program { name: "show_2";
+               signal: "show";
+               action: STATE_SET "default" 0.0;
+               target: "base";
+               after: "show_3";
+           }
+           program { name: "show_3";
+               signal: "show";
+               action: STATE_SET "visible" 0.0;
+               target: "base";
+               transition: LINEAR 0.5;
+           }
+           program { name: "hide";
+               signal: "elm,action,hide";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "base";
+           }
+       }
+   }
+   group { name: "elm/notify/base/top_right";
+       //this group is a design similar to the inwin group
+       images {
+           image: "shad_circ.png" COMP;
+           image: "bt_dis_base.png" COMP;
+           image: "bt_dis_hilight.png" COMP;
+       }
+       parts {
+           part { name: "base";
+               type: RECT;
+               mouse_events: 0;
+               repeat_events: 1;
+               description { state: "default" 0.0;
+                   color: 0 0 0 0;
+                   rel1.offset: 10 10;
+                   rel2.offset: -10 -10;
+                   rel1.relative: 0.0 -1.0;
+                   rel2.relative: 1.0 0.0;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 64;
+                   rel1.relative: 0.0 0.0;
+                   rel2.relative: 1.0 1.0;
+               }
+           }
+           part { name: "shad";
+               mouse_events:  0;
+               description { state: "default" 0.0;
+                   image.normal: "shad_circ.png";
+                   rel1.to: "elm.swallow.content";
+                   rel1.offset: -64 -64;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 63 63;
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "pop";
+               mouse_events: 1;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.swallow.content";
+                   rel1.offset: -5 -5;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 4 4;
+                   image {
+                       normal: "bt_dis_base.png";
+                       border: 4 4 4 4;
+                   }
+                   image.middle: SOLID;
+               }
+           }
+           part { name: "popover";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "pop";
+                   rel2.to: "pop";
+                   rel2.relative: 1.0 0.5;
+                   image {
+                       normal: "bt_dis_hilight.png";
+                       border: 4 4 4 0;
+                   }
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel2.to: "base";
+               }
+           }
+       }
+       programs {
+           program { name: "show";
+               signal: "elm,action,show";
+               source: "elm";
+               action: STATE_SET "visible" 0.0;
+               target: "base";
+           }
+           program { name: "show_2";
+               signal: "show";
+               action: STATE_SET "default" 0.0;
+               target: "base";
+               after: "show_3";
+           }
+           program { name: "show_3";
+               signal: "show";
+               action: STATE_SET "visible" 0.0;
+               target: "base";
+               transition: LINEAR 0.5;
+           }
+           program { name: "hide";
+               signal: "elm,action,hide";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "base";
+           }
+       }
+   }
+   group { name: "elm/notify/base/bottom_left";
+       //this group is a design similar to the inwin group
+       images {
+           image: "shad_circ.png" COMP;
+           image: "bt_dis_base.png" COMP;
+           image: "bt_dis_hilight.png" COMP;
+       }
+       parts {
+           part { name: "base";
+               type: RECT;
+               mouse_events: 0;
+               repeat_events: 1;
+               description { state: "default" 0.0;
+                   color: 0 0 0 0;
+                   rel1.offset: 10 10;
+                   rel2.offset: -10 -10;
+                   rel1.relative: 0.0 1.0;
+                   rel2.relative: 1.0 2.0;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 64;
+                   rel1.relative: 0.0 0.0;
+                   rel2.relative: 1.0 1.0;
+               }
+           }
+           part { name: "shad";
+               mouse_events:  0;
+               description { state: "default" 0.0;
+                   image.normal: "shad_circ.png";
+                   rel1.to: "elm.swallow.content";
+                   rel1.offset: -64 -64;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 63 63;
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "pop";
+               mouse_events: 1;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.swallow.content";
+                   rel1.offset: -5 -5;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 4 4;
+                   image {
+                       normal: "bt_dis_base.png";
+                       border: 4 4 4 4;
+                   }
+                   image.middle: SOLID;
+               }
+           }
+           part { name: "popover";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "pop";
+                   rel2.to: "pop";
+                   rel2.relative: 1.0 0.5;
+                   image {
+                       normal: "bt_dis_hilight.png";
+                       border: 4 4 4 0;
+                   }
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel2.to: "base";
+               }
+           }
+       }
+       programs {
+           program { name: "show";
+               signal: "elm,action,show";
+               source: "elm";
+               action: STATE_SET "visible" 0.0;
+               target: "base";
+           }
+           program { name: "show_2";
+               signal: "show";
+               action: STATE_SET "default" 0.0;
+               target: "base";
+               after: "show_3";
+           }
+           program { name: "show_3";
+               signal: "show";
+               action: STATE_SET "visible" 0.0;
+               target: "base";
+               transition: LINEAR 0.5;
+           }
+           program { name: "hide";
+               signal: "elm,action,hide";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "base";
+           }
+       }
+   }
+   group { name: "elm/notify/base/bottom_right";
+       //this group is a design similar to the inwin group
+       images {
+           image: "shad_circ.png" COMP;
+           image: "bt_dis_base.png" COMP;
+           image: "bt_dis_hilight.png" COMP;
+       }
+       parts {
+           part { name: "base";
+               type: RECT;
+               mouse_events: 0;
+               repeat_events: 1;
+              description { state: "default" 0.0;
+                   color: 0 0 0 0;
+                   rel1.offset: 10 10;
+                   rel2.offset: -10 -10;
+                   rel1.relative: 0.0 1.0;
+                   rel2.relative: 1.0 2.0;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 64;
+                   rel1.relative: 0.0 0.0;
+                   rel2.relative: 1.0 1.0;
+               }
+           }
+           part { name: "shad";
+               mouse_events:  0;
+               description { state: "default" 0.0;
+                   image.normal: "shad_circ.png";
+                   rel1.to: "elm.swallow.content";
+                   rel1.offset: -64 -64;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 63 63;
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "pop";
+               mouse_events: 1;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.swallow.content";
+                   rel1.offset: -5 -5;
+                   rel2.to: "elm.swallow.content";
+                   rel2.offset: 4 4;
+                   image {
+                       normal: "bt_dis_base.png";
+                       border: 4 4 4 4;
+                   }
+                   image.middle: SOLID;
+               }
+           }
+           part { name: "popover";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "pop";
+                   rel2.to: "pop";
+                   rel2.relative: 1.0 0.5;
+                   image {
+                       normal: "bt_dis_hilight.png";
+                       border: 4 4 4 0;
+                   }
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel2.to: "base";
+               }
+           }
+       }
+       programs {
+           program { name: "show";
+               signal: "elm,action,show";
+               source: "elm";
+               action: STATE_SET "visible" 0.0;
+               target: "base";
+           }
+           program { name: "show_2";
+               signal: "show";
+               action: STATE_SET "default" 0.0;
+               target: "base";
+               after: "show_3";
+           }
+           program { name: "show_3";
+               signal: "show";
+               action: STATE_SET "visible" 0.0;
+               target: "base";
+               transition: LINEAR 0.5;
+           }
+           program { name: "hide";
+               signal: "elm,action,hide";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "base";
+           }
+       }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/slideshow/base/default";
+      data {
+         item: transitions "fade black_fade horizontal vertical square";
+      }
+      parts {
+         part { name: "whole";
+            description {
+               state: "default" 0.0;
+               visible: 1;
+               color: 0 0 0 0;
+            }
+         }
+         part { name: "image_1_whole";
+            description {
+               state: "default" 0.0;
+               color: 255 255 255 255;
+            }
+            description {
+               state: "fade_prev_next" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 0;
+            }
+            description {
+               state: "black_fade_prev_next_init" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 255;
+            }
+            description {
+               state: "black_fade_prev_next" 0.0;
+               inherit: "default" 0.0;
+               color: 0 0 0 255;
+            }
+            description {
+               state: "horizontal_next_init" 0.0;
+               inherit: "default" 0.0;
+            }
+            description {
+               state: "horizontal_next" 0.0;
+               inherit: "default" 0.0;
+               rel1.relative: -1.0 0.0;
+               rel2.relative: 0.0 1.0;
+            }
+            description {
+               state: "horizontal_prev_init" 0.0;
+               inherit: "default" 0.0;
+            }
+            description {
+               state: "horizontal_prev" 0.0;
+               inherit: "default" 0.0;
+               rel1.relative: 1.0 0.0;
+               rel2.relative: 2.0 1.0;
+            }
+            description {
+               state: "vertical_next_init" 0.0;
+               inherit: "default" 0.0;
+            }
+            description {
+               state: "vertical_next" 0.0;
+               inherit: "default" 0.0;
+               rel1.relative: 0.0 -1.0;
+               rel2.relative: 1.0 0.0;
+            }
+            description {
+               state: "vertical_prev_init" 0.0;
+               inherit: "default" 0.0;
+            }
+            description {
+               state: "vertical_prev" 0.0;
+               inherit: "default" 0.0;
+               rel1.relative: 0.0 1.0;
+               rel2.relative: 1.0 2.0;
+            }
+         }
+         part { name: "image_2_whole";
+            description {
+               state: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 0;
+            }
+            description {
+               state: "fade_prev_next" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 255;
+            }
+            description {
+               state: "black_fade_prev_next_init" 0.0;
+               inherit: "default" 0.0;
+               color: 0 0 0 0;
+            }
+            description {
+               state: "black_fade_prev_next" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 255;
+            }
+            description {
+               state: "horizontal_next_init" 0.0;
+               inherit: "default" 0.0;
+               rel1.relative: 1.0 0.0;
+               rel2.relative: 2.0 1.0;
+               color: 255 255 255 255;
+            }
+            description {
+               state: "horizontal_next" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 255;
+            }
+            description {
+               state: "horizontal_prev_init" 0.0;
+               inherit: "default" 0.0;
+               rel1.relative: -1.0 0.0;
+               rel2.relative: 0.0 1.0;
+               color: 255 255 255 255;
+            }
+            description {
+               state: "horizontal_prev" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 255;
+            }
+            description {
+               state: "vertical_next_init" 0.0;
+               inherit: "default" 0.0;
+               rel1.relative: 0.0 1.0;
+               rel2.relative: 1.0 2.0;
+               color: 255 255 255 255;
+            }
+            description {
+               state: "vertical_next" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 255;
+            }
+            description {
+               state: "vertical_prev_init" 0.0;
+               inherit: "default" 0.0;
+               rel1.relative: 0.0 -1.0;
+               rel2.relative: 1.0 0.0;
+               color: 255 255 255 255;
+            }
+            description {
+               state: "vertical_prev" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 255;
+            }
+            description {
+               state: "square_prev_next_init" 0.0;
+               inherit: "default" 0.0;
+               rel1.relative: 0.5 0.5;
+               rel2.relative: 0.5 0.5;
+               color: 255 255 255 255;
+            }
+            description {
+               state: "square_prev_next" 0.0;
+               inherit: "default" 0.0;
+               rel1.relative: 0.0 0.0;
+               rel2.relative: 1.0 1.0;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "elm.swallow.1";
+            type: SWALLOW;
+            clip_to: "image_1_whole";
+            description {
+               state: "default" 0.0;
+               rel1.to: "image_1_whole";
+               rel2.to: "image_1_whole";
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "elm.swallow.2";
+            type: SWALLOW;
+            clip_to: "image_2_whole";
+            description {
+               state: "default" 0.0;
+               color: 255 255 255 255;
+               rel1.to: "image_2_whole";
+               rel2.to: "image_2_whole";
+            }
+         }
+         part { name: "events_catcher";
+            type: RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               visible: 1;
+               color: 0 0 0 0;
+            }
+         }
+      }
+      programs {
+         program { name: "fade_next";
+            signal: "fade,next";
+            source: "slideshow";
+            action: STATE_SET "default" 0.0;
+            target: "image_1_whole";
+            target: "image_2_whole";
+            after: "fade_next_2";
+         }
+         program { name: "fade_next_2";
+            action: STATE_SET "fade_prev_next" 0.0;
+            target: "image_1_whole";
+            target: "image_2_whole";
+            transition: SINUSOIDAL 1.5;
+            after: "end";
+         }
+         program { name: "fade_previous";
+            signal: "fade,previous";
+            source: "slideshow";
+            action: STATE_SET "default" 0.0;
+            target: "image_1_whole";
+            target: "image_2_whole";
+            after: "fade_previous_2";
+         }
+         program { name: "fade_previous_2";
+            action: STATE_SET "fade_prev_next" 0.0;
+            target: "image_1_whole";
+            target: "image_2_whole";
+            transition: SINUSOIDAL 1.5;
+            after: "end";
+         }
+         program { name: "black_fade_next";
+            signal: "black_fade,next";
+            source: "slideshow";
+            action: STATE_SET "black_fade_prev_next_init" 0.0;
+            target: "image_1_whole";
+            target: "image_2_whole";
+            after: "black_fade_next_2";
+         }
+         program { name: "black_fade_next_2";
+            action: STATE_SET "black_fade_prev_next" 0.0;
+            target: "image_1_whole";
+            transition: SINUSOIDAL 0.75;
+            after: "black_fade_next_3";
+         }
+         program { name: "black_fade_next_3";
+            action: STATE_SET "black_fade_prev_next" 0.0;
+            target: "image_2_whole";
+            transition: SINUSOIDAL 0.75;
+            after: "end";
+         }
+         program { name: "black_fade_previous";
+            signal: "black_fade,previous";
+            source: "slideshow";
+            action: STATE_SET "black_fade_prev_next_init" 0.0;
+            target: "image_1_whole";
+            target: "image_2_whole";
+            after: "black_fade_previous_2";
+         }
+         program { name: "black_fade_previous_2";
+            action: STATE_SET "black_fade_prev_next" 0.0;
+            target: "image_1_whole";
+            transition: SINUSOIDAL 0.75;
+            after: "black_fade_previous_3";
+         }
+         program { name: "black_fade_previous_3";
+            action: STATE_SET "black_fade_prev_next" 0.0;
+            target: "image_2_whole";
+            transition: SINUSOIDAL 0.75;
+            after: "end";
+         }
+         program { name: "horizontal_next";
+            signal: "horizontal,next";
+            source: "slideshow";
+            action: STATE_SET "horizontal_next_init" 0.0;
+            target: "image_1_whole";
+            target: "image_2_whole";
+            after: "horizontal_next_2";
+         }
+         program { name: "horizontal_next_2";
+            action: STATE_SET "horizontal_next" 0.0;
+            target: "image_1_whole";
+            target: "image_2_whole";
+            transition: SINUSOIDAL 1.5;
+            after: "end";
+         }
+         program { name: "horizontal_previous";
+            signal: "horizontal,previous";
+            source: "slideshow";
+            action: STATE_SET "horizontal_prev_init" 0.0;
+            target: "image_1_whole";
+            target: "image_2_whole";
+            after: "horizontal_previous_2";
+         }
+         program { name: "horizontal_previous_2";
+            action: STATE_SET "horizontal_prev" 0.0;
+            target: "image_1_whole";
+            target: "image_2_whole";
+            transition: SINUSOIDAL 1.5;
+            after: "end";
+         }
+         program { name: "vertical_next";
+            signal: "vertical,next";
+            source: "slideshow";
+            action: STATE_SET "vertical_next_init" 0.0;
+            target: "image_1_whole";
+            target: "image_2_whole";
+            after: "vertical_next_2";
+         }
+         program { name: "vertical_next_2";
+            action: STATE_SET "vertical_next" 0.0;
+            target: "image_1_whole";
+            target: "image_2_whole";
+            transition: SINUSOIDAL 1.5;
+            after: "end";
+         }
+         program { name: "vertical_previous";
+            signal: "vertical,previous";
+            source: "slideshow";
+            action: STATE_SET "vertical_prev_init" 0.0;
+            target: "image_1_whole";
+            target: "image_2_whole";
+            after: "vertical_previous_2";
+         }
+         program { name: "vertical_previous_2";
+            action: STATE_SET "vertical_prev" 0.0;
+            target: "image_1_whole";
+            target: "image_2_whole";
+            transition: SINUSOIDAL 1.5;
+            after: "end";
+         }
+         program { name: "square_next";
+            signal: "square,next";
+            source: "slideshow";
+            action: STATE_SET "square_prev_next_init" 0.0;
+            target: "image_2_whole";
+            after: "square_next_2";
+         }
+         program { name: "square_next_2";
+            action: STATE_SET "square_prev_next" 0.0;
+            target: "image_2_whole";
+            transition: SINUSOIDAL 1.5;
+            after: "end";
+         }
+         program { name: "square_previous";
+            signal: "square,previous";
+            source: "slideshow";
+            action: STATE_SET "square_prev_next_init" 0.0;
+            target: "image_2_whole";
+            after: "square_next_2";
+         }
+         program { name: "end";
+            action: STATE_SET "default" 0.0;
+            target: "image_1_whole";
+            target: "image_2_whole";
+            after: "end_signal";
+         }
+         program { name: "end_signal";
+            action: SIGNAL_EMIT "end" "slideshow";
+         }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/win/inwin/default";
+      images {
+        image: "shad_circ.png" COMP;
+        image: "bt_dis_base.png" COMP;
+        image: "bt_dis_hilight.png" COMP;
+      }
+      parts {
+        part { name: "base";
+           type: RECT;
+           mouse_events: 1;
+           description { state: "default" 0.0;
+              color: 0 0 0 0;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 1.0;
+              color: 0 0 0 64;
+           }
+        }
+         part { name: "shad";
+           mouse_events:  0;
+           description { state: "default" 0.0;
+              image.normal: "shad_circ.png";
+              rel1.to: "elm.swallow.content";
+              rel1.offset: -64 -64;
+              rel2.to: "elm.swallow.content";
+              rel2.offset: 63 63;
+               fill.smooth: 0;
+           }
+        }
+        part { name: "pop";
+           mouse_events: 1;
+           description { state: "default" 0.0;
+              rel1.to: "elm.swallow.content";
+               rel1.offset: -5 -5;
+              rel2.to: "elm.swallow.content";
+               rel2.offset: 4 4;
+               image {
+                 normal: "bt_dis_base.png";
+                 border: 4 4 4 4;
+              }
+               image.middle: SOLID;
+           }
+        }
+         part { name: "popover";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "pop";
+              rel2.to: "pop";
+              rel2.relative: 1.0 0.5;
+              image {
+                 normal: "bt_dis_hilight.png";
+                 border: 4 4 4 0;
+              }
+           }
+        }
+        part { name: "elm.swallow.content";
+            type: SWALLOW;
+           description { state: "default" 0.0;
+               rel1.relative: 0.1 0.1;
+               rel2.relative: 0.9 0.9;
+           }
+        }
+      }
+      programs {
+        program { name: "show";
+            signal: "elm,action,show";
+           source: "elm";
+           action: STATE_SET "visible" 0.0;
+//         transition: DECELERATE 0.5;
+           target: "base";
+        }
+        program { name: "hide";
+            signal: "elm,action,hide";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+//         transition: DECELERATE 0.5;
+           target: "base";
+        }
+      }
+   }
+
+   group { name: "elm/win/inwin/minimal";
+      images {
+        image: "shad_circ.png" COMP;
+        image: "bt_dis_base.png" COMP;
+        image: "bt_dis_hilight.png" COMP;
+      }
+      parts {
+        part { name: "base";
+           type: RECT;
+           mouse_events: 1;
+           description { state: "default" 0.0;
+              color: 0 0 0 0;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 1.0;
+              color: 0 0 0 64;
+           }
+        }
+         part { name: "shad";
+           mouse_events:  0;
+           description { state: "default" 0.0;
+              image.normal: "shad_circ.png";
+              rel1.to: "elm.swallow.content";
+              rel1.offset: -64 -64;
+              rel2.to: "elm.swallow.content";
+              rel2.offset: 63 63;
+               fill.smooth: 0;
+           }
+        }
+        part { name: "pop";
+           mouse_events: 1;
+           description { state: "default" 0.0;
+              rel1.to: "elm.swallow.content";
+               rel1.offset: -5 -5;
+              rel2.to: "elm.swallow.content";
+               rel2.offset: 4 4;
+               image {
+                 normal: "bt_dis_base.png";
+                 border: 4 4 4 4;
+              }
+               image.middle: SOLID;
+           }
+        }
+         part { name: "popover";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "pop";
+              rel2.to: "pop";
+              rel2.relative: 1.0 0.5;
+              image {
+                 normal: "bt_dis_hilight.png";
+                 border: 4 4 4 0;
+              }
+           }
+        }
+        part { name: "elm.swallow.content";
+            type: SWALLOW;
+           description { state: "default" 0.0;
+               fixed: 1 1;
+               rel1.relative: 0.5 0.5;
+               rel2.relative: 0.5 0.5;
+           }
+        }
+      }
+      programs {
+        program { name: "show";
+            signal: "elm,action,show";
+           source: "elm";
+           action: STATE_SET "visible" 0.0;
+//         transition: DECELERATE 0.5;
+           target: "base";
+        }
+        program { name: "hide";
+            signal: "elm,action,hide";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+//         transition: DECELERATE 0.5;
+           target: "base";
+        }
+      }
+   }
+
+   group { name: "elm/win/inwin/minimal_vertical";
+      images {
+        image: "shad_circ.png" COMP;
+        image: "bt_dis_base.png" COMP;
+        image: "bt_dis_hilight.png" COMP;
+      }
+      parts {
+        part { name: "base";
+           type: RECT;
+           mouse_events: 1;
+           description { state: "default" 0.0;
+              color: 0 0 0 0;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 1.0;
+              color: 0 0 0 64;
+           }
+        }
+         part { name: "shad";
+           mouse_events:  0;
+           description { state: "default" 0.0;
+              image.normal: "shad_circ.png";
+              rel1.to: "elm.swallow.content";
+              rel1.offset: -64 -64;
+              rel2.to: "elm.swallow.content";
+              rel2.offset: 63 63;
+               fill.smooth: 0;
+           }
+        }
+        part { name: "pop";
+           mouse_events: 1;
+           description { state: "default" 0.0;
+              rel1.to: "elm.swallow.content";
+               rel1.offset: -5 -5;
+              rel2.to: "elm.swallow.content";
+               rel2.offset: 4 4;
+               image {
+                 normal: "bt_dis_base.png";
+                 border: 4 4 4 4;
+              }
+               image.middle: SOLID;
+           }
+        }
+         part { name: "popover";
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1.to: "pop";
+              rel2.to: "pop";
+              rel2.relative: 1.0 0.5;
+              image {
+                 normal: "bt_dis_hilight.png";
+                 border: 4 4 4 0;
+              }
+           }
+        }
+        part { name: "elm.swallow.content";
+            type: SWALLOW;
+           description { state: "default" 0.0;
+               fixed: 1 1;
+               rel1.relative: 0.1 0.5;
+               rel2.relative: 0.9 0.5;
+           }
+        }
+      }
+      programs {
+        program { name: "show";
+            signal: "elm,action,show";
+           source: "elm";
+           action: STATE_SET "visible" 0.0;
+//         transition: DECELERATE 0.5;
+           target: "base";
+        }
+        program { name: "hide";
+            signal: "elm,action,hide";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+//         transition: DECELERATE 0.5;
+           target: "base";
+        }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+
+   ///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/list/item/default";
+      data.item: "stacking" "above";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_1.png" COMP;
+         image: "ilist_item_shadow.png" COMP;
+      }
+      parts {
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base_sh";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               align: 0.0 0.0;
+               min: 0 10;
+               fixed: 1 1;
+               rel1 {
+                  to: "base";
+                  relative: 0.0 1.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  to: "base";
+                  relative: 1.0 1.0;
+                  offset: -1 0;
+               }
+               image {
+                  normal: "ilist_item_shadow.png";
+               }
+               fill.smooth: 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_1.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.icon";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.end";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 1.0 0.5;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   4 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "fg1";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+      }
+      programs {
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            transition: LINEAR 0.1;
+         }
+      }
+   }
+   group { name: "elm/list/item_odd/default";
+      data.item: "stacking" "below";
+      data.item: "selectraise" "on";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_2.png" COMP;
+      }
+      parts {
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_2.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part {
+            name:          "elm.swallow.icon";
+            type:          SWALLOW;
+            description { state:    "default" 0.0;
+               fixed: 1 0;
+               align:    0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part {
+            name:          "elm.swallow.end";
+            type:          SWALLOW;
+            description { state:    "default" 0.0;
+               fixed: 1 0;
+               align: 1.0 0.5;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part {
+            name:           "elm.text";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min:      16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   4 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "fg1";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+      }
+      programs {
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            transition: LINEAR 0.1;
+         }
+      }
+   }
+   group { name: "elm/list/item_compress/default";
+      data.item: "stacking" "above";
+      data.item: "selectraise" "on";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_1.png" COMP;
+         image: "ilist_item_shadow.png" COMP;
+      }
+      parts {
+         part {
+            name: "base_sh";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               fixed: 1 1;
+               align: 0.0 0.0;
+               min: 0 10;
+               rel1 {
+                  to: "base";
+                  relative: 0.0 1.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  to: "base";
+                  relative: 1.0 1.0;
+                  offset: -1 0;
+               }
+               image {
+                  normal: "ilist_item_shadow.png";
+               }
+               fill.smooth: 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_1.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name:          "elm.swallow.icon";
+            type:          SWALLOW;
+            description { state:    "default" 0.0;
+               fixed: 1 0;
+               align:    0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name:          "elm.swallow.end";
+            type:          SWALLOW;
+            description { state:    "default" 0.0;
+               fixed: 1 0;
+               align:    1.0 0.5;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part {
+            name:           "elm.text";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description { state: "default" 0.0;
+//               min:      16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   4 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+//                  min: 1 1;
+                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "fg1";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+      }
+      programs {
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            transition: LINEAR 0.1;
+         }
+      }
+   }
+   group { name: "elm/list/item_compress_odd/default";
+      data.item: "stacking" "below";
+      data.item: "selectraise" "on";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_2.png" COMP;
+      }
+      parts {
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_2.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name:          "elm.swallow.icon";
+            type:          SWALLOW;
+            description { state:    "default" 0.0;
+               fixed: 1 0;
+               align:    0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name:          "elm.swallow.end";
+            type:          SWALLOW;
+            description { state:    "default" 0.0;
+               fixed: 1 0;
+               align:    1.0 0.5;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part {
+            name:           "elm.text";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min:      16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   4 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+//                  min: 1 1;
+                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "fg1";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+      }
+      programs {
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            transition: LINEAR 0.1;
+         }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/slider/horizontal/default";
+      images {
+        image: "sl_bg.png" COMP;
+        image: "sl_bg_over.png" COMP;
+        image: "sl_bt_0.png" COMP;
+        image: "sl_bt_1.png" COMP;
+        image: "sl_bt_2.png" COMP;
+        image: "sl_bt2_0_0.png" COMP;
+        image: "sl_bt2_0_1.png" COMP;
+        image: "sl_bt2_0_2.png" COMP;
+        image: "sl_bt2_1.png" COMP;
+        image: "sl_bt2_2.png" COMP;
+         image: "sl_units.png" COMP;
+      }
+      parts {
+         part { name: "base";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               max: 99999 6;
+               min: 0 6;
+               rel1 { to: "bg";
+                  offset: 1 0;
+               }
+               rel2 { to: "bg";
+                  offset: -2 -1;
+               }
+               image.normal: "sl_bg.png";
+               fill.smooth: 0;
+            }
+         }
+         part { name: "level";
+            type: RECT;
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               fixed: 1 1;
+               rel1.to: "base";
+               rel2 {
+                  to_y: "base";
+                  to_x: "elm.dragable.slider";
+                  relative: 0.5 1.0;
+               }
+               color: 255 0 0 200;
+            }
+            description { state: "inverted" 0.0;
+               inherit: "default" 0.0;
+               visible: 0;
+            }
+         }
+         part { name: "level2";
+            type: RECT;
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               fixed: 1 1;
+               visible: 0;
+               rel1 {
+                  to_y: "base";
+                  to_x: "elm.dragable.slider";
+                  relative: 0.5 0.0;
+               }
+               rel2.to: "base";
+               color: 255 0 0 200;
+            }
+            description { state: "inverted" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+            }
+         }
+         part {
+            name: "base_over";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               rel1.to: "base";
+               rel1.offset: -1 -1;
+               rel2.to: "base";
+               rel2.offset: 0 0;
+               image {
+                  normal: "sl_bg_over.png";
+                  border: 3 3 3 3;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+           type: RECT;
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+               visible: 0;
+              rel1.to: "elm.swallow.bar";
+              rel2.to: "elm.swallow.bar";
+              color: 0 0 0 0;
+           }
+        }
+        part { name: "elm.swallow.bar";
+           type: SWALLOW;
+            scale: 1;
+           description { state: "default" 0.0;
+              min: 48 24;
+              max: 99999 24;
+              align: 1.0 0.5;
+              rel1 {
+                  to_x: "elm.text";
+                  relative: 1.0 0.0;
+                  offset: 8 0;
+               }
+              rel2 {
+                  to_x: "elm.units";
+                  relative: 0.0 1.0;
+                  offset: -10 -1;
+               }
+           }
+        }
+        part { name: "elm.swallow.content";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              visible: 0;
+              align: 0.0 0.5;
+              rel1 {
+                  offset: 4 0;
+                  to_y: "elm.swallow.bar";
+               }
+              rel2 {
+                  offset: 3 -1;
+                  relative: 0.0 1.0;
+                  to_y: "elm.swallow.bar";
+               }
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              aspect: 1.0 1.0;
+              aspect_preference: VERTICAL;
+              rel2.offset: 4 -1;
+           }
+        }
+         part { name: "elm.text";
+           type: TEXT;
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              visible: 0;
+               fixed: 1 1;
+               align: 0.0 0.5;
+              rel1.to_x: "elm.swallow.content";
+              rel1.relative: 1.0 0.0;
+               rel1.offset: -1 4;
+              rel2.to_x: "elm.swallow.content";
+              rel2.relative: 1.0 1.0;
+              rel2.offset: -1 -5;
+              color: 0 0 0 255;
+              text {
+                 font: "Sans,Edje-Vera";
+                 size: 10;
+                 min: 0 0;
+                 align: 0.0 0.5;
+              }
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              text.min: 1 1;
+               rel1.offset: 0 4;
+               rel2.offset: 0 -5;
+           }
+        }
+         part { name: "units";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+              visible: 0;
+               rel1 {
+                  to_x: "elm.units";
+                  offset: 0 5;
+               }
+               image {
+                  normal: "sl_units.png";
+                  border: 0 5 3 8;
+               }
+               fill.smooth: 0;
+            }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+            }
+         }
+         part { name: "elm.units";
+           type: TEXT;
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              visible: 0;
+               fixed: 1 1;
+              align: 1.0 0.5;
+              rel1.relative: 1.0 0.0;
+              rel1.offset: 0 8;
+              rel2.relative: 1.0 1.0;
+              rel2.offset: 0 -9;
+              color: 0 0 0 255;
+              text {
+                 font: "Sans,Edje-Vera";
+                 size: 10;
+                 min: 0 0;
+                 align: 0.0 0.5;
+              }
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+               fixed: 1 1;
+              visible: 1;
+              text.min: 1 1;
+              rel1.offset: -5 0;
+              rel2.offset: -5 -1;
+           }
+        }
+         part { name: "elm.dragable.slider";
+            type: RECT;
+            mouse_events: 0;
+            scale: 1;
+            dragable {
+               x: 1 1 0;
+               y: 0 0 0;
+               confine: "bg";
+            }
+            description { state: "default" 0.0;
+               min: 0 24;
+               max: 0 24;
+               fixed: 1 1;
+               rel1 {
+                  relative: 0.5 0.0;
+                  to_x: "bg";
+               }
+               rel2 {
+                  relative: 0.5 1.0;
+                  to_x: "bg";
+               }
+               color: 255 0 0 100;
+            }
+         }
+         part { name: "button_events";
+           type: RECT;
+           dragable {
+              events: "elm.dragable.slider";
+           }
+            mouse_events: 1;
+           description { state: "default" 0.0;
+               fixed: 1 1;
+               min: 16 16;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+              rel1.to_x: "elm.dragable.slider";
+              rel2.to_x: "elm.dragable.slider";
+              color: 0 0 0 0;
+           }
+        }
+         part { name: "button0";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               fixed: 1 1;
+               max: 17 999;
+               min: 17 24;
+               rel1.to: "elm.dragable.slider";
+               rel2.to: "elm.dragable.slider";
+               image {
+                  normal: "sl_bt_0.png";
+                  border: 5 5 5 10;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "button1";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               rel1.to: "button0";
+               rel2 {
+                  to: "button0";
+                  relative: 1.0 0.5;
+                  offset: -1 -5;
+               }
+               image {
+                  normal: "sl_bt_1.png";
+                  border: 5 5 5 0;
+               }
+            }
+         }
+         part { name: "button2";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               rel1.to: "button0";
+               rel2.to: "button0";
+               image {
+                  normal: "sl_bt_2.png";
+                  border: 5 5 5 10;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "button3";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               fixed: 1 1;
+              visible: 0;
+               min: 8 32;
+               align: 1.0 0.5;
+               rel1 {
+                  to_x: "elm.indicator";
+                  to_y: "button4";
+                  relative: 0.0 0.0;
+                  offset: -7 0;
+               }
+               rel2 {
+                  to: "button4";
+                  relative: 0.0 1.0;
+                  offset: -1 -1;
+               }
+               image {
+                  normal: "sl_bt2_0_0.png";
+                  border: 6 0 6 12;
+               }
+               fill.smooth: 0;
+            }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+            }
+         }
+         part { name: "button4";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+              visible: 0;
+               max: 15 999;
+               min: 15 32;
+               rel1 {
+                  to_x: "button0";
+                  to_y: "elm.indicator";
+                  offset: 0 0;
+               }
+               rel2.to: "button0";
+               image {
+                  normal: "sl_bt2_0_1.png";
+                  border: 0 0 6 12;
+               }
+               fill.smooth: 0;
+            }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+            }
+         }
+         part { name: "button5";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               fixed: 1 1;
+              visible: 0;
+               min: 8 32;
+               align: 0.0 0.5;
+               rel1 {
+                  to: "button4";
+                  relative: 1.0 0.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  to_x: "elm.indicator";
+                  to_y: "button4";
+                  relative: 1.0 1.0;
+                  offset: 6 -1;
+               }
+               image {
+                  normal: "sl_bt2_0_2.png";
+                  border: 0 6 6 12;
+               }
+               fill.smooth: 0;
+            }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+            }
+         }
+         part { name: "elm.indicator";
+           type: TEXT;
+           mouse_events: 0;
+            effect: SOFT_SHADOW;
+           scale: 1;
+           description { state: "default" 0.0;
+              visible: 0;
+               fixed: 1 1;
+               align: 0.5 1.0;
+              rel1 {
+                  to: "button0";
+                  relative: 0.0 -0.25;
+                  offset: 0 0;
+               }
+              rel2 {
+                  to_x: "button0";
+                  relative: 1.0 -0.25;
+                  offset: -1 0;
+               }
+              color: 224 224 224 255;
+              color3: 0 0 0 64;
+              text {
+                 font:     "Sans,Edje-Vera";
+                 size:     10;
+                 min:      0 0;
+                 align:    0.5 0.5;
+              }
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              text.min: 1 1;
+               rel1.offset: 0 -1;
+               rel2.offset: -1 -1;
+           }
+        }
+         part { name: "button6";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+              visible: 0;
+               rel1.to: "button3";
+               rel2 {
+                  to: "button5";
+                  relative: 1.0 0.3;
+                  offset: -1 -1;
+               }
+               image {
+                  normal: "sl_bt2_1.png";
+                  border: 5 5 5 0;
+               }
+               fill.smooth: 0;
+            }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+            }
+         }
+         part { name: "button7";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+              visible: 0;
+               rel1.to: "button3";
+               rel2.to: "button5";
+               image {
+                  normal: "sl_bt2_2.png";
+                  border: 5 5 5 0;
+                  middle: 0;
+               }
+               fill.smooth: 0;
+            }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+            }
+         }
+      }
+      programs {
+        program { name: "text_show";
+           signal: "elm,state,text,visible";
+           source: "elm";
+           action:  STATE_SET "visible" 0.0;
+           target: "elm.text";
+        }
+        program { name: "text_hide";
+           signal: "elm,state,text,hidden";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "elm.text";
+        }
+        program { name: "icon_show";
+           signal: "elm,state,icon,visible";
+           source: "elm";
+           action:  STATE_SET "visible" 0.0;
+           target: "elm.swallow.content";
+        }
+        program { name: "icon_hide";
+           signal: "elm,state,icon,hidden";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "elm.swallow.content";
+        }
+        program { name: "units_show";
+           signal: "elm,state,units,visible";
+           source: "elm";
+           action:  STATE_SET "visible" 0.0;
+           target: "elm.units";
+           target: "units";
+        }
+        program { name: "units_hide";
+           signal: "elm,state,units,hidden";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "elm.units";
+           target: "units";
+        }
+        program { name: "invert_on";
+           signal: "elm,state,inverted,on";
+           source: "elm";
+           action:  STATE_SET "inverted" 0.0;
+           target: "level";
+           target: "level2";
+        }
+        program { name: "invert_off";
+           signal: "elm,state,inverted,off";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "level";
+           target: "level2";
+        }
+        program { name: "val_show";
+           signal: "mouse,down,*";
+           source: "elm.dragable.slider";
+           action:  STATE_SET "visible" 0.0;
+           target: "elm.indicator";
+           target: "button3";
+           target: "button4";
+           target: "button5";
+           target: "button6";
+           target: "button7";
+        }
+        program { name: "val_hide";
+           signal: "mouse,up,*";
+           source: "elm.dragable.slider";
+           action:  STATE_SET "default" 0.0;
+           target: "elm.indicator";
+           target: "button3";
+           target: "button4";
+           target: "button5";
+           target: "button6";
+           target: "button7";
+        }
+      }
+   }
+
+   group { name: "elm/slider/vertical/default";
+      images {
+        image: "slv_bg.png" COMP;
+        image: "slv_bg_over.png" COMP;
+
+        image: "sl_bt_0.png" COMP;
+        image: "sl_bt_1.png" COMP;
+        image: "sl_bt_2.png" COMP;
+        image: "sl_bt2_0_0.png" COMP;
+        image: "sl_bt2_0_1.png" COMP;
+        image: "sl_bt2_0_2.png" COMP;
+        image: "sl_bt2_1.png" COMP;
+        image: "sl_bt2_2.png" COMP;
+
+         image: "slv_units.png" COMP;
+      }
+      parts {
+         part { name: "base";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               max: 6 99999;
+               min: 6 0;
+               rel1 { to: "bg";
+                  offset: 1 0;
+               }
+               rel2 { to: "bg";
+                  offset: -2 -1;
+               }
+               image.normal: "slv_bg.png";
+               fill.smooth: 0;
+            }
+         }
+         part { name: "level";
+            type: RECT;
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               fixed: 1 1;
+               rel1.to: "base";
+               rel2 {
+                  to_x: "base";
+                  to_y: "elm.dragable.slider";
+                  relative: 1.0 0.5;
+               }
+               color: 255 0 0 200;
+            }
+            description { state: "inverted" 0.0;
+               inherit: "default" 0.0;
+               visible: 0;
+            }
+         }
+         part { name: "level2";
+            type: RECT;
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               fixed: 1 1;
+               visible: 0;
+               rel1 {
+                  to_x: "base";
+                  to_y: "elm.dragable.slider";
+                  relative: 0.0 0.5;
+               }
+               rel2.to: "base";
+               color: 255 0 0 200;
+            }
+            description { state: "inverted" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+            }
+         }
+         part {
+            name: "base_over";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               rel1.to: "base";
+               rel1.offset: -1 -1;
+               rel2.to: "base";
+               rel2.offset: 0 0;
+               image {
+                  normal: "slv_bg_over.png";
+                  border: 3 3 3 3;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+           type: RECT;
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+               visible: 0;
+              rel1.to: "elm.swallow.bar";
+              rel2.to: "elm.swallow.bar";
+              color: 0 0 0 0;
+           }
+        }
+        part { name: "elm.swallow.bar";
+           type: SWALLOW;
+            scale: 1;
+           description { state: "default" 0.0;
+              min: 24 48;
+              max: 24 9999;
+              align: 0.5 1.0;
+              rel1 {
+                  to_y: "elm.text";
+                  relative: 0.0 1.0;
+                  offset: 0 10;
+               }
+              rel2 {
+                  to_y: "elm.units";
+                  relative: 1.0 0.0;
+                  offset: -1 -8;
+               }
+           }
+        }
+        part { name: "elm.swallow.content";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              visible: 0;
+              align: 0.5 0.0;
+              rel1 {
+                  offset: 0 4;
+                  to_x: "elm.swallow.bar";
+               }
+              rel2 {
+                  offset: -1 3;
+                  relative: 1.0 0.0;
+                  to_x: "elm.swallow.bar";
+               }
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              aspect: 1.0 1.0;
+              aspect_preference: HORIZONTAL;
+              rel2.offset: -1 4;
+           }
+        }
+         part { name: "elm.text";
+           type: TEXT;
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              visible: 0;
+               fixed: 1 1;
+               align: 0.5 0.0;
+              rel1.to_y: "elm.swallow.content";
+              rel1.relative: 0.5 1.0;
+               rel1.offset: 0 -1;
+              rel2.to_y: "elm.swallow.content";
+              rel2.relative: 0.5 1.0;
+              rel2.offset: -1 -1;
+              color: 0 0 0 255;
+              text {
+                 font: "Sans,Edje-Vera";
+                 size: 10;
+                 min: 0 0;
+                 align: 0.5 0.0;
+              }
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              text.min: 1 1;
+               rel1.offset: 4 0;
+               rel2.offset: -5 0;
+           }
+        }
+         part { name: "units";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+              visible: 0;
+               rel1 {
+                  to: "elm.units";
+                  offset: -8 0;
+               }
+               rel2 {
+                  to: "elm.units";
+                  offset: 7 8;
+               }
+               image {
+                  normal: "slv_units.png";
+                  border: 8 8 0 9;
+               }
+               fill.smooth: 0;
+            }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+            }
+         }
+         part { name: "elm.units";
+           type: TEXT;
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              visible: 0;
+               fixed: 1 1;
+              align: 0.5 1.0;
+              rel1.relative: 0.0 1.0;
+              rel1.offset: 8 0;
+              rel2.relative: 1.0 1.0;
+              rel2.offset: -9 0;
+              color: 0 0 0 255;
+              text {
+                 font: "Sans,Edje-Vera";
+                 size: 10;
+                 min: 0 0;
+                 align: 0.5 0.0;
+              }
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+               fixed: 1 1;
+              visible: 1;
+              text.min: 1 1;
+              rel1.offset: 8 -9;
+              rel2.offset: -9 -9;
+           }
+        }
+         part { name: "elm.dragable.slider";
+            type: RECT;
+            mouse_events: 0;
+            scale: 1;
+            dragable {
+               x: 0 0 0;
+               y: 1 1 0;
+               confine: "bg";
+            }
+            description { state: "default" 0.0;
+               min: 24 0;
+               max: 24 0;
+               fixed: 1 1;
+               rel1 {
+                  relative: 0.5  0.0;
+                  to_y: "bg";
+               }
+               rel2 {
+                  relative: 0.5  1.0;
+                  to_y: "bg";
+               }
+               color: 0 0 0 0;
+            }
+         }
+         part { name: "button_events";
+           type: RECT;
+           dragable {
+              events: "elm.dragable.slider";
+           }
+            mouse_events: 1;
+           description { state: "default" 0.0;
+               fixed: 1 1;
+               min: 16 16;
+               aspect: 1.0 1.0;
+               aspect_preference: HORIZONTAL;
+              rel1.to_y: "elm.dragable.slider";
+              rel2.to_y: "elm.dragable.slider";
+              color: 0 0 0 0;
+           }
+        }
+         part { name: "button0";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               fixed: 1 1;
+               max: 17 999;
+               min: 17 24;
+               rel1.to: "elm.dragable.slider";
+               rel2.to: "elm.dragable.slider";
+               image {
+                  normal: "sl_bt_0.png";
+                  border: 5 5 5 10;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "button1";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               rel1.to: "button0";
+               rel2 {
+                  to: "button0";
+                  relative: 1.0 0.5;
+                  offset: -1 -5;
+               }
+               image {
+                  normal: "sl_bt_1.png";
+                  border: 5 5 5 0;
+               }
+            }
+         }
+         part { name: "button2";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               rel1.to: "button0";
+               rel2.to: "button0";
+               image {
+                  normal: "sl_bt_2.png";
+                  border: 5 5 5 10;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "button3";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+              visible: 0;
+               min: 8 32;
+               align: 1.0 0.5;
+               rel1 {
+                  to_x: "elm.indicator";
+                  to_y: "button4";
+                  relative: 0.0 0.0;
+                  offset: -7 0;
+               }
+               rel2 {
+                  to: "button4";
+                  relative: 0.0 1.0;
+                  offset: -1 -1;
+               }
+               image {
+                  normal: "sl_bt2_0_0.png";
+                  border: 6 0 6 12;
+               }
+               fill.smooth: 0;
+            }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+            }
+         }
+         part { name: "button4";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+              visible: 0;
+               max: 15 999;
+               min: 15 32;
+               fixed: 1 1;
+               rel1 {
+                  to_x: "button0";
+                  to_y: "elm.indicator";
+                  offset: 0 -7;
+               }
+               rel2.to: "button0";
+               image {
+                  normal: "sl_bt2_0_1.png";
+                  border: 0 0 6 12;
+               }
+               fill.smooth: 0;
+            }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+            }
+         }
+         part { name: "button5";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+              visible: 0;
+               min: 8 32;
+               align: 0.0 0.5;
+               rel1 {
+                  to: "button4";
+                  relative: 1.0 0.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  to_x: "elm.indicator";
+                  to_y: "button4";
+                  relative: 1.0 1.0;
+                  offset: 6 -1;
+               }
+               image {
+                  normal: "sl_bt2_0_2.png";
+                  border: 0 6 6 12;
+               }
+               fill.smooth: 0;
+            }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+            }
+         }
+         part { name: "elm.indicator";
+           type: TEXT;
+           mouse_events: 0;
+            effect: SOFT_SHADOW;
+           scale: 1;
+           description { state: "default" 0.0;
+              visible: 0;
+               fixed: 1 1;
+               align: 0.5 1.0;
+              rel1 {
+                  to: "button0";
+                  relative: 0.0 -1.0;
+                  offset: 0 0;
+               }
+              rel2 {
+                  to: "button0";
+                  relative: 1.0 -1.0;
+                  offset: -1 0;
+               }
+              color: 224 224 224 255;
+              color3: 0 0 0 64;
+              text {
+                 font:     "Sans,Edje-Vera";
+                 size:     10;
+                 min:      0 0;
+                 align:    0.5 0.5;
+              }
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              text.min: 1 1;
+               rel1.offset: 0 -1;
+               rel2.offset: -1 -1;
+           }
+        }
+         part { name: "button6";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+              visible: 0;
+               rel1.to: "button3";
+               rel2 {
+                  to: "button5";
+                  relative: 1.0 0.3;
+                  offset: -1 -1;
+               }
+               image {
+                  normal: "sl_bt2_1.png";
+                  border: 5 5 5 0;
+               }
+               fill.smooth: 0;
+            }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+            }
+         }
+         part { name: "button7";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+              visible: 0;
+               rel1.to: "button3";
+               rel2.to: "button5";
+               image {
+                  normal: "sl_bt2_2.png";
+                  border: 5 5 5 0;
+                  middle: 0;
+               }
+               fill.smooth: 0;
+            }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+            }
+         }
+      }
+      programs {
+        program { name: "text_show";
+           signal: "elm,state,text,visible";
+           source: "elm";
+           action:  STATE_SET "visible" 0.0;
+           target: "elm.text";
+        }
+        program { name: "text_hide";
+           signal: "elm,state,text,hidden";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "elm.text";
+        }
+        program { name: "icon_show";
+           signal: "elm,state,icon,visible";
+           source: "elm";
+           action:  STATE_SET "visible" 0.0;
+           target: "elm.swallow.content";
+        }
+        program { name: "icon_hide";
+           signal: "elm,state,icon,hidden";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "elm.swallow.content";
+        }
+        program { name: "units_show";
+           signal: "elm,state,units,visible";
+           source: "elm";
+           action:  STATE_SET "visible" 0.0;
+           target: "elm.units";
+           target: "units";
+        }
+        program { name: "units_hide";
+           signal: "elm,state,units,hidden";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "elm.units";
+           target: "units";
+        }
+        program { name: "invert_on";
+           signal: "elm,state,inverted,on";
+           source: "elm";
+           action:  STATE_SET "inverted" 0.0;
+           target: "level";
+           target: "level2";
+        }
+        program { name: "invert_off";
+           signal: "elm,state,inverted,off";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "level";
+           target: "level2";
+        }
+        program { name: "val_show";
+           signal: "mouse,down,*";
+           source: "elm.dragable.slider";
+           action:  STATE_SET "visible" 0.0;
+           target: "elm.indicator";
+           target: "button3";
+           target: "button4";
+           target: "button5";
+           target: "button6";
+           target: "button7";
+        }
+        program { name: "val_hide";
+           signal: "mouse,up,*";
+           source: "elm.dragable.slider";
+           action:  STATE_SET "default" 0.0;
+           target: "elm.indicator";
+           target: "button3";
+           target: "button4";
+           target: "button5";
+           target: "button6";
+           target: "button7";
+        }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/genlist/item/default/default";
+      data.item: "stacking" "above";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text";
+      data.item: "icons" "elm.swallow.icon elm.swallow.end";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_1.png" COMP;
+         image: "ilist_item_shadow.png" COMP;
+      }
+      parts {
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base_sh";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               align: 0.0 0.0;
+               min: 0 10;
+               fixed: 1 1;
+               rel1 {
+                  to: "base";
+                  relative: 0.0 1.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  to: "base";
+                  relative: 1.0 1.0;
+                  offset: -1 0;
+               }
+               image {
+                  normal: "ilist_item_shadow.png";
+               }
+               fill.smooth: 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_1.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.end";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 1.0 0.5;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+      }
+   }
+   group { name: "elm/genlist/item_compress/default/default";
+      data.item: "stacking" "above";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text";
+      data.item: "icons" "elm.swallow.icon elm.swallow.end";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_1.png" COMP;
+         image: "ilist_item_shadow.png" COMP;
+      }
+      parts {
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base_sh";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               align: 0.0 0.0;
+               min: 0 10;
+               fixed: 1 1;
+               rel1 {
+                  to: "base";
+                  relative: 0.0 1.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  to: "base";
+                  relative: 1.0 1.0;
+                  offset: -1 0;
+               }
+               image {
+                  normal: "ilist_item_shadow.png";
+               }
+               fill.smooth: 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_1.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.end";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 1.0 0.5;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+                  min: 0 1;
+//                  min: 1 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+      }
+   }
+   group { name: "elm/genlist/item_odd/default/default";
+      data.item: "stacking" "below";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text";
+      data.item: "icons" "elm.swallow.icon elm.swallow.end";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_2.png" COMP;
+      }
+      parts {
+         part { name: "event";
+            type: RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_2.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.end";
+            clip_to: "disclip";
+            type:          SWALLOW;
+            description { state:    "default" 0.0;
+               fixed: 1 0;
+               align:    1.0 0.5;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min:      16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+      }
+   }
+   group { name: "elm/genlist/item_compress_odd/default/default";
+      data.item: "stacking" "below";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text";
+      data.item: "icons" "elm.swallow.icon elm.swallow.end";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_2.png" COMP;
+      }
+      parts {
+         part { name: "event";
+            type: RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_2.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.end";
+            clip_to: "disclip";
+            type:          SWALLOW;
+            description { state:    "default" 0.0;
+               fixed: 1 0;
+               align:    1.0 0.5;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min:      16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+                  min: 0 1;
+//                  min: 1 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+      }
+   }
+
+   group { name: "elm/genlist/tree/default/default";
+      data.item: "stacking" "above";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text";
+      data.item: "icons" "elm.swallow.icon elm.swallow.end";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_1.png" COMP;
+         image: "ilist_item_shadow.png" COMP;
+         image: "icon_arrow_right.png" COMP;
+         image: "icon_arrow_down.png" COMP;
+      }
+      parts {
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base_sh";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               align: 0.0 0.0;
+               min: 0 10;
+               fixed: 1 1;
+               rel1 {
+                  to: "base";
+                  relative: 0.0 1.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  to: "base";
+                  relative: 1.0 1.0;
+                  offset: -1 0;
+               }
+               image {
+                  normal: "ilist_item_shadow.png";
+               }
+               fill.smooth: 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_1.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "arrow";
+            clip_to: "disclip";
+            ignore_flags: ON_HOLD;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               aspect: 1.0 1.0;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+               image.normal: "icon_arrow_right.png";
+            }
+            description { state: "active" 0.0;
+               inherit: "default" 0.0;
+               image.normal: "icon_arrow_down.png";
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  to_x: "arrow";
+                  relative: 1.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  to_x: "arrow";
+                  relative: 1.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.end";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 1.0 0.5;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "expand";
+            signal:  "mouse,up,1";
+            source:  "arrow";
+            action:  SIGNAL_EMIT "elm,action,expand,toggle" "elm";
+         }
+         program {
+            name:    "go_expanded";
+            signal:  "elm,state,expanded";
+            source:  "elm";
+            action:  STATE_SET "active" 0.0;
+            target:  "arrow";
+         }
+         program {
+            name:    "go_contracted";
+            signal:  "elm,state,contracted";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "arrow";
+         }
+      }
+   }
+   group { name: "elm/genlist/tree_compress/default/default";
+      data.item: "stacking" "above";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text";
+      data.item: "icons" "elm.swallow.icon elm.swallow.end";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_1.png" COMP;
+         image: "ilist_item_shadow.png" COMP;
+         image: "icon_arrow_right.png" COMP;
+         image: "icon_arrow_down.png" COMP;
+      }
+      parts {
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base_sh";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               align: 0.0 0.0;
+               min: 0 10;
+               fixed: 1 1;
+               rel1 {
+                  to: "base";
+                  relative: 0.0 1.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  to: "base";
+                  relative: 1.0 1.0;
+                  offset: -1 0;
+               }
+               image {
+                  normal: "ilist_item_shadow.png";
+               }
+               fill.smooth: 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_1.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "arrow";
+            clip_to: "disclip";
+            ignore_flags: ON_HOLD;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               aspect: 1.0 1.0;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+               image.normal: "icon_arrow_right.png";
+            }
+            description { state: "active" 0.0;
+               inherit: "default" 0.0;
+               image.normal: "icon_arrow_down.png";
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  to_x: "arrow";
+                  relative: 1.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  to_x: "arrow";
+                  relative: 1.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.end";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 1.0 0.5;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+//                  min: 1 1;
+                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "expand";
+            signal:  "mouse,up,1";
+            source:  "arrow";
+            action:  SIGNAL_EMIT "elm,action,expand,toggle" "elm";
+         }
+         program {
+            name:    "go_expanded";
+            signal:  "elm,state,expanded";
+            source:  "elm";
+            action:  STATE_SET "active" 0.0;
+            target:  "arrow";
+         }
+         program {
+            name:    "go_contracted";
+            signal:  "elm,state,contracted";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "arrow";
+         }
+      }
+   }
+   group { name: "elm/genlist/tree_odd/default/default";
+      data.item: "stacking" "below";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text";
+      data.item: "icons" "elm.swallow.icon elm.swallow.end";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_2.png" COMP;
+         image: "icon_arrow_right.png" COMP;
+         image: "icon_arrow_down.png" COMP;
+      }
+      parts {
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_2.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "arrow";
+            clip_to: "disclip";
+            ignore_flags: ON_HOLD;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               aspect: 1.0 1.0;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+               image.normal: "icon_arrow_right.png";
+            }
+            description { state: "active" 0.0;
+               inherit: "default" 0.0;
+               image.normal: "icon_arrow_down.png";
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  to_x: "arrow";
+                  relative: 1.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  to_x: "arrow";
+                  relative: 1.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.end";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 1.0 0.5;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "expand";
+            signal:  "mouse,up,1";
+            source:  "arrow";
+            action:  SIGNAL_EMIT "elm,action,expand,toggle" "elm";
+         }
+         program {
+            name:    "go_expanded";
+            signal:  "elm,state,expanded";
+            source:  "elm";
+            action:  STATE_SET "active" 0.0;
+            target:  "arrow";
+         }
+         program {
+            name:    "go_contracted";
+            signal:  "elm,state,contracted";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "arrow";
+         }
+      }
+   }
+   group { name: "elm/genlist/tree_compress_odd/default/default";
+      data.item: "stacking" "below";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text";
+      data.item: "icons" "elm.swallow.icon elm.swallow.end";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_2.png" COMP;
+         image: "icon_arrow_right.png" COMP;
+         image: "icon_arrow_down.png" COMP;
+      }
+      parts {
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_2.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "arrow";
+            clip_to: "disclip";
+            ignore_flags: ON_HOLD;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               aspect: 1.0 1.0;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+               image.normal: "icon_arrow_right.png";
+            }
+            description { state: "active" 0.0;
+               inherit: "default" 0.0;
+               image.normal: "icon_arrow_down.png";
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  to_x: "arrow";
+                  relative: 1.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  to_x: "arrow";
+                  relative: 1.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.end";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 1.0 0.5;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+//                  min: 1 1;
+                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "expand";
+            signal:  "mouse,up,1";
+            source:  "arrow";
+            action:  SIGNAL_EMIT "elm,action,expand,toggle" "elm";
+         }
+         program {
+            name:    "go_expanded";
+            signal:  "elm,state,expanded";
+            source:  "elm";
+            action:  STATE_SET "active" 0.0;
+            target:  "arrow";
+         }
+         program {
+            name:    "go_contracted";
+            signal:  "elm,state,contracted";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "arrow";
+         }
+      }
+   }
+
+   group { name: "elm/genlist/item/default_style/default";
+       styles
+       {
+           style { name: "genlist_style";
+               base: "font=Sans font_size=10 align=left valign=0.5 color=#000";
+               tag:  "br" "\n";
+               tag:  "hilight" "+ font=Sans:style=Bold";
+               tag:  "b" "+ font=Sans:style=Bold";
+               tag:  "tab" "\t";
+           }
+           style { name: "genlist_selected_style";
+               base: "font=Sans font_size=10 align=left valign=0.5 color=#fff";
+               tag:  "br" "\n";
+               tag:  "hilight" "+ font=Sans:style=Bold";
+               tag:  "b" "+ font=Sans:style=Bold";
+               tag:  "tab" "\t";
+           }
+       }
+       data.item: "stacking" "above";
+       data.item: "selectraise" "on";
+       data.item: "labels" "elm.text";
+       data.item: "icons" "elm.swallow.icon elm.swallow.end";
+       data.item: "treesize" "20";
+       images {
+           image: "bt_sm_base1.png" COMP;
+           image: "bt_sm_shine.png" COMP;
+           image: "bt_sm_hilight.png" COMP;
+           image: "ilist_1.png" COMP;
+           image: "ilist_item_shadow.png" COMP;
+       }
+       parts {
+           part {
+               name:           "event";
+               type:           RECT;
+               repeat_events: 1;
+               description {
+                   state: "default" 0.0;
+                   color: 0 0 0 0;
+               }
+           }
+           part {
+               name: "base_sh";
+               mouse_events: 0;
+               description {
+                   state: "default" 0.0;
+                   align: 0.0 0.0;
+                   min: 0 10;
+                   fixed: 1 1;
+                   rel1 {
+                       to: "base";
+                       relative: 0.0 1.0;
+                       offset: 0 0;
+                   }
+                   rel2 {
+                       to: "base";
+                       relative: 1.0 1.0;
+                       offset: -1 0;
+                   }
+                   image {
+                       normal: "ilist_item_shadow.png";
+                   }
+                   fill.smooth: 0;
+               }
+           }
+           part {
+               name: "base";
+               mouse_events: 0;
+               description {
+                   state: "default" 0.0;
+                   min: 16 28;
+                   image {
+                       normal: "ilist_1.png";
+                       border: 2 2 2 2;
+                   }
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "bg";
+               clip_to: "disclip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+                   rel1 {
+                       relative: 0.0 0.0;
+                       offset: -5 -5;
+                   }
+                   rel2 {
+                       relative: 1.0 1.0;
+                       offset: 4 4;
+                   }
+                   image {
+                       normal: "bt_sm_base1.png";
+                       border: 6 6 6 6;
+                   }
+                   image.middle: SOLID;
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+                   rel1 {
+                       relative: 0.0 0.0;
+                       offset: -2 -2;
+                   }
+                   rel2 {
+                       relative: 1.0 1.0;
+                       offset: 1 1;
+                   }
+               }
+           }
+           part { name: "elm.swallow.pad";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   fixed: 1 0;
+                   align: 0.0 0.5;
+                   rel1 {
+                       relative: 0.0  0.0;
+                       offset:   4    4;
+                   }
+                   rel2 {
+                       relative: 0.0  1.0;
+                       offset:   4   -5;
+                   }
+               }
+           }
+           part { name: "elm.swallow.icon";
+               clip_to: "disclip";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   fixed: 1 0;
+                   align: 0.0 0.5;
+                   rel1 {
+                       to_x: "elm.swallow.pad";
+                       relative: 1.0  0.0;
+                       offset:   -1    4;
+                   }
+                   rel2 {
+                       to_x: "elm.swallow.pad";
+                       relative: 1.0  1.0;
+                       offset:   -1   -5;
+                   }
+               }
+           }
+           part { name: "elm.swallow.end";
+               clip_to: "disclip";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   fixed: 1 0;
+                   align: 1.0 0.5;
+                   aspect: 1.0 1.0;
+                   aspect_preference: VERTICAL;
+                   rel1 {
+                       relative: 1.0  0.0;
+                       offset:   -5    4;
+                   }
+                   rel2 {
+                       relative: 1.0  1.0;
+                       offset:   -5   -5;
+                   }
+               }
+           }
+           part { name: "elm.text";
+               clip_to: "disclip";
+               type: TEXTBLOCK;
+               mouse_events: 0;
+               scale: 1;
+               description {
+                   state: "default" 0.0;
+                   align: 0.0 0.5;
+                   fixed: 0 1;
+                   rel1 {
+                       to_x: "elm.swallow.icon";
+                       to_y: "base";
+                       relative: 1.0  0.5;
+                       offset:   0 4;
+                   }
+                   rel2 {
+                       to_x: "elm.swallow.end";
+                       to_y: "base";
+                       relative: 0.0  0.5;
+                       offset:   -1 -5;
+                   }
+                   text {
+                       style: "genlist_style";
+                       min: 1 1;
+                   }
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   text {
+                       style: "genlist_selected_style";
+                   }
+               }
+           }
+           part { name: "fg1";
+               clip_to: "disclip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+                   rel1.to: "bg";
+                   rel2.relative: 1.0 0.5;
+                   rel2.to: "bg";
+                   image {
+                       normal: "bt_sm_hilight.png";
+                       border: 6 6 6 0;
+                   }
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "fg2";
+               clip_to: "disclip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+                   rel1.to: "bg";
+                   rel2.to: "bg";
+                   image {
+                       normal: "bt_sm_shine.png";
+                       border: 6 6 6 0;
+                   }
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "disclip";
+               type: RECT;
+               description { state: "default" 0.0;
+                   rel1.to: "bg";
+                   rel2.to: "bg";
+               }
+               description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   color: 255 255 255 64;
+               }
+           }
+       }
+       programs {
+           // signal: elm,state,%s,active
+           //   a "check" item named %s went active
+           // signal: elm,state,%s,passive
+           //   a "check" item named %s went passive
+           // default is passive
+           program {
+               name:    "go_active";
+               signal:  "elm,state,selected";
+               source:  "elm";
+               action:  STATE_SET "selected" 0.0;
+               target:  "bg";
+               target:  "fg1";
+               target:  "fg2";
+               target:  "elm.text";
+           }
+           program {
+               name:    "go_passive";
+               signal:  "elm,state,unselected";
+               source:  "elm";
+               action:  STATE_SET "default" 0.0;
+               target:  "bg";
+               target:  "fg1";
+               target:  "fg2";
+               target:  "elm.text";
+               transition: LINEAR 0.1;
+           }
+           program {
+               name:    "go_disabled";
+               signal:  "elm,state,disabled";
+               source:  "elm";
+               action:  STATE_SET "disabled" 0.0;
+               target:  "disclip";
+           }
+           program {
+               name:    "go_enabled";
+               signal:  "elm,state,enabled";
+               source:  "elm";
+               action:  STATE_SET "default" 0.0;
+               target:  "disclip";
+           }
+       }
+   }
+   group { name: "elm/genlist/item_odd/default_style/default";
+       data.item: "stacking" "below";
+       data.item: "selectraise" "on";
+       data.item: "labels" "elm.text";
+       data.item: "icons" "elm.swallow.icon elm.swallow.end";
+       data.item: "treesize" "20";
+       images {
+           image: "bt_sm_base1.png" COMP;
+           image: "bt_sm_shine.png" COMP;
+           image: "bt_sm_hilight.png" COMP;
+           image: "ilist_2.png" COMP;
+       }
+       parts {
+           part { name: "event";
+               type: RECT;
+               repeat_events: 1;
+               description {
+                   state: "default" 0.0;
+                   color: 0 0 0 0;
+               }
+           }
+           part {
+               name: "base";
+               mouse_events: 0;
+               description {
+                   state: "default" 0.0;
+                   min: 16 28;
+                   image {
+                       normal: "ilist_2.png";
+                       border: 2 2 2 2;
+                   }
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "bg";
+               clip_to: "disclip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+                   rel1 {
+                       relative: 0.0 0.0;
+                       offset: -5 -5;
+                   }
+                   rel2 {
+                       relative: 1.0 1.0;
+                       offset: 4 4;
+                   }
+                   image {
+                       normal: "bt_sm_base1.png";
+                       border: 6 6 6 6;
+                   }
+                   image.middle: SOLID;
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+                   rel1 {
+                       relative: 0.0 0.0;
+                       offset: -2 -2;
+                   }
+                   rel2 {
+                       relative: 1.0 1.0;
+                       offset: 1 1;
+                   }
+               }
+           }
+           part { name: "elm.swallow.pad";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   fixed: 1 0;
+                   align: 0.0 0.5;
+                   rel1 {
+                       relative: 0.0  0.0;
+                       offset:   4    4;
+                   }
+                   rel2 {
+                       relative: 0.0  1.0;
+                       offset:   4   -5;
+                   }
+               }
+           }
+           part { name: "elm.swallow.icon";
+               clip_to: "disclip";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   fixed: 1 0;
+                   align: 0.0 0.5;
+                   rel1 {
+                       to_x: "elm.swallow.pad";
+                       relative: 1.0  0.0;
+                       offset:   -1    4;
+                   }
+                   rel2 {
+                       to_x: "elm.swallow.pad";
+                       relative: 1.0  1.0;
+                       offset:   -1   -5;
+                   }
+               }
+           }
+           part { name: "elm.swallow.end";
+               clip_to: "disclip";
+               type:          SWALLOW;
+               description { state:    "default" 0.0;
+                   fixed: 1 0;
+                   align:    1.0 0.5;
+                   aspect: 1.0 1.0;
+                   aspect_preference: VERTICAL;
+                   rel1 {
+                       relative: 1.0  0.0;
+                       offset:   -5    4;
+                   }
+                   rel2 {
+                       relative: 1.0  1.0;
+                       offset:   -5   -5;
+                   }
+               }
+           }
+           part { name: "elm.text";
+               clip_to: "disclip";
+               type:           TEXTBLOCK;
+               mouse_events:   0;
+               scale: 1;
+               description {
+                   state: "default" 0.0;
+                   align: 0.0 0.5;
+                   fixed: 0 1;
+                   rel1 {
+                       to_x: "elm.swallow.icon";
+                       to_y: "base";
+                       relative: 1.0  0.5;
+                       offset:   0 4;
+                   }
+                   rel2 {
+                       to_x: "elm.swallow.end";
+                       to_y: "base";
+                       relative: 0.0  0.5;
+                       offset:   -1 -5;
+                   }
+                   text {
+                       style: "genlist_style";
+                       min: 1 1;
+                   }
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   text {
+                       style: "genlist_selected_style";
+                   }
+               }
+           }
+           part { name: "fg1";
+               clip_to: "disclip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+                   rel1.to: "bg";
+                   rel2.relative: 1.0 0.5;
+                   rel2.to: "bg";
+                   image {
+                       normal: "bt_sm_hilight.png";
+                       border: 6 6 6 0;
+                   }
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "fg2";
+               clip_to: "disclip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+                   rel1.to: "bg";
+                   rel2.to: "bg";
+                   image {
+                       normal: "bt_sm_shine.png";
+                       border: 6 6 6 0;
+                   }
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "disclip";
+               type: RECT;
+               description { state: "default" 0.0;
+                   rel1.to: "bg";
+                   rel2.to: "bg";
+               }
+               description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   color: 255 255 255 64;
+               }
+           }
+       }
+       programs {
+           // signal: elm,state,%s,active
+           //   a "check" item named %s went active
+           // signal: elm,state,%s,passive
+           //   a "check" item named %s went passive
+           // default is passive
+           program {
+               name:    "go_active";
+               signal:  "elm,state,selected";
+               source:  "elm";
+               action:  STATE_SET "selected" 0.0;
+               target:  "bg";
+               target:  "fg1";
+               target:  "fg2";
+               target:  "elm.text";
+           }
+           program {
+               name:    "go_passive";
+               signal:  "elm,state,unselected";
+               source:  "elm";
+               action:  STATE_SET "default" 0.0;
+               target:  "bg";
+               target:  "fg1";
+               target:  "fg2";
+               target:  "elm.text";
+               transition: LINEAR 0.1;
+           }
+           program {
+               name:    "go_disabled";
+               signal:  "elm,state,disabled";
+               source:  "elm";
+               action:  STATE_SET "disabled" 0.0;
+               target:  "disclip";
+           }
+           program {
+               name:    "go_enabled";
+               signal:  "elm,state,enabled";
+               source:  "elm";
+               action:  STATE_SET "default" 0.0;
+               target:  "disclip";
+           }
+       }
+   }
+
+   group { name: "elm/genlist/tree/default_style/default";
+       data.item: "stacking" "above";
+       data.item: "selectraise" "on";
+       data.item: "labels" "elm.text";
+       data.item: "icons" "elm.swallow.icon elm.swallow.end";
+       data.item: "treesize" "20";
+       images {
+           image: "bt_sm_base1.png" COMP;
+           image: "bt_sm_shine.png" COMP;
+           image: "bt_sm_hilight.png" COMP;
+           image: "ilist_1.png" COMP;
+           image: "ilist_item_shadow.png" COMP;
+           image: "icon_arrow_right.png" COMP;
+           image: "icon_arrow_down.png" COMP;
+       }
+       parts {
+           part {
+               name:           "event";
+               type:           RECT;
+               repeat_events: 1;
+               description {
+                   state: "default" 0.0;
+                   color: 0 0 0 0;
+               }
+           }
+           part {
+               name: "base_sh";
+               mouse_events: 0;
+               description {
+                   state: "default" 0.0;
+                   align: 0.0 0.0;
+                   min: 0 10;
+                   fixed: 1 1;
+                   rel1 {
+                       to: "base";
+                       relative: 0.0 1.0;
+                       offset: 0 0;
+                   }
+                   rel2 {
+                       to: "base";
+                       relative: 1.0 1.0;
+                       offset: -1 0;
+                   }
+                   image {
+                       normal: "ilist_item_shadow.png";
+                   }
+                   fill.smooth: 0;
+               }
+           }
+           part {
+               name: "base";
+               mouse_events: 0;
+               description {
+                   state: "default" 0.0;
+                   min: 16 28;
+                   image {
+                       normal: "ilist_1.png";
+                       border: 2 2 2 2;
+                   }
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "bg";
+               clip_to: "disclip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+                   rel1 {
+                       relative: 0.0 0.0;
+                       offset: -5 -5;
+                   }
+                   rel2 {
+                       relative: 1.0 1.0;
+                       offset: 4 4;
+                   }
+                   image {
+                       normal: "bt_sm_base1.png";
+                       border: 6 6 6 6;
+                   }
+                   image.middle: SOLID;
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+                   rel1 {
+                       relative: 0.0 0.0;
+                       offset: -2 -2;
+                   }
+                   rel2 {
+                       relative: 1.0 1.0;
+                       offset: 1 1;
+                   }
+               }
+           }
+           part { name: "elm.swallow.pad";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   fixed: 1 0;
+                   align: 0.0 0.5;
+                   rel1 {
+                       relative: 0.0  0.0;
+                       offset:   4    4;
+                   }
+                   rel2 {
+                       relative: 0.0  1.0;
+                       offset:   4   -5;
+                   }
+               }
+           }
+           part { name: "arrow";
+               clip_to: "disclip";
+               ignore_flags: ON_HOLD;
+               description { state: "default" 0.0;
+                   fixed: 1 0;
+                   align: 0.0 0.5;
+                   aspect: 1.0 1.0;
+                   rel1 {
+                       to_x: "elm.swallow.pad";
+                       relative: 1.0  0.0;
+                       offset:   -1    4;
+                   }
+                   rel2 {
+                       to_x: "elm.swallow.pad";
+                       relative: 1.0  1.0;
+                       offset:   -1   -5;
+                   }
+                   image.normal: "icon_arrow_right.png";
+               }
+               description { state: "active" 0.0;
+                   inherit: "default" 0.0;
+                   image.normal: "icon_arrow_down.png";
+               }
+           }
+           part { name: "elm.swallow.icon";
+               clip_to: "disclip";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   fixed: 1 0;
+                   align: 0.0 0.5;
+                   rel1 {
+                       to_x: "arrow";
+                       relative: 1.0  0.0;
+                       offset:   4    4;
+                   }
+                   rel2 {
+                       to_x: "arrow";
+                       relative: 1.0  1.0;
+                       offset:   4   -5;
+                   }
+               }
+           }
+           part { name: "elm.swallow.end";
+               clip_to: "disclip";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   fixed: 1 0;
+                   align: 1.0 0.5;
+                   aspect: 1.0 1.0;
+                   aspect_preference: VERTICAL;
+                   rel1 {
+                       relative: 1.0  0.0;
+                       offset:   -5    4;
+                   }
+                   rel2 {
+                       relative: 1.0  1.0;
+                       offset:   -5   -5;
+                   }
+               }
+           }
+           part { name: "elm.text";
+               clip_to: "disclip";
+               type:           TEXTBLOCK;
+               effect:         SOFT_SHADOW;
+               mouse_events:   0;
+               scale: 1;
+               description {
+                   state: "default" 0.0;
+                   align: 0.0 0.5;
+                   fixed: 0 1;
+                   rel1 {
+                       to_x:     "elm.swallow.icon";
+                       to_y: "base";
+                       relative: 1.0  0.5;
+                       offset:   0 4;
+                   }
+                   rel2 {
+                       to_x:     "elm.swallow.end";
+                       to_y: "base";
+                       relative: 0.0  0.5;
+                       offset:   -1 -5;
+                   }
+                   text {
+                       style: "genlist_style";
+                       min: 1 1;
+                   }
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   text {
+                       style: "genlist_selected_style";
+                   }
+               }
+           }
+           part { name: "fg1";
+               clip_to: "disclip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+                   rel1.to: "bg";
+                   rel2.relative: 1.0 0.5;
+                   rel2.to: "bg";
+                   image {
+                       normal: "bt_sm_hilight.png";
+                       border: 6 6 6 0;
+                   }
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "fg2";
+               clip_to: "disclip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+                   rel1.to: "bg";
+                   rel2.to: "bg";
+                   image {
+                       normal: "bt_sm_shine.png";
+                       border: 6 6 6 0;
+                   }
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "disclip";
+               type: RECT;
+               description { state: "default" 0.0;
+                   rel1.to: "bg";
+                   rel2.to: "bg";
+               }
+               description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   color: 255 255 255 64;
+               }
+           }
+       }
+       programs {
+           // signal: elm,state,%s,active
+           //   a "check" item named %s went active
+           // signal: elm,state,%s,passive
+           //   a "check" item named %s went passive
+           // default is passive
+           program {
+               name:    "go_active";
+               signal:  "elm,state,selected";
+               source:  "elm";
+               action:  STATE_SET "selected" 0.0;
+               target:  "bg";
+               target:  "fg1";
+               target:  "fg2";
+               target:  "elm.text";
+           }
+           program {
+               name:    "go_passive";
+               signal:  "elm,state,unselected";
+               source:  "elm";
+               action:  STATE_SET "default" 0.0;
+               target:  "bg";
+               target:  "fg1";
+               target:  "fg2";
+               target:  "elm.text";
+               transition: LINEAR 0.1;
+           }
+           program {
+               name:    "go_disabled";
+               signal:  "elm,state,disabled";
+               source:  "elm";
+               action:  STATE_SET "disabled" 0.0;
+               target:  "disclip";
+           }
+           program {
+               name:    "go_enabled";
+               signal:  "elm,state,enabled";
+               source:  "elm";
+               action:  STATE_SET "default" 0.0;
+               target:  "disclip";
+           }
+           program {
+               name:    "expand";
+               signal:  "mouse,up,1";
+               source:  "arrow";
+               action:  SIGNAL_EMIT "elm,action,expand,toggle" "elm";
+           }
+           program {
+               name:    "go_expanded";
+               signal:  "elm,state,expanded";
+               source:  "elm";
+               action:  STATE_SET "active" 0.0;
+               target:  "arrow";
+           }
+           program {
+               name:    "go_contracted";
+               signal:  "elm,state,contracted";
+               source:  "elm";
+               action:  STATE_SET "default" 0.0;
+               target:  "arrow";
+           }
+       }
+   }
+   group { name: "elm/genlist/tree_odd/default_style/default";
+       data.item: "stacking" "below";
+       data.item: "selectraise" "on";
+       data.item: "labels" "elm.text";
+       data.item: "icons" "elm.swallow.icon elm.swallow.end";
+       data.item: "treesize" "20";
+       images {
+           image: "bt_sm_base1.png" COMP;
+           image: "bt_sm_shine.png" COMP;
+           image: "bt_sm_hilight.png" COMP;
+           image: "ilist_2.png" COMP;
+           image: "icon_arrow_right.png" COMP;
+           image: "icon_arrow_down.png" COMP;
+       }
+       parts {
+           part {
+               name:           "event";
+               type:           RECT;
+               repeat_events: 1;
+               description {
+                   state: "default" 0.0;
+                   color: 0 0 0 0;
+               }
+           }
+           part {
+               name: "base";
+               mouse_events: 0;
+               description {
+                   state: "default" 0.0;
+                   min: 16 28;
+                   image {
+                       normal: "ilist_2.png";
+                       border: 2 2 2 2;
+                   }
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "bg";
+               clip_to: "disclip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+                   rel1 {
+                       relative: 0.0 0.0;
+                       offset: -5 -5;
+                   }
+                   rel2 {
+                       relative: 1.0 1.0;
+                       offset: 4 4;
+                   }
+                   image {
+                       normal: "bt_sm_base1.png";
+                       border: 6 6 6 6;
+                   }
+                   image.middle: SOLID;
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+                   rel1 {
+                       relative: 0.0 0.0;
+                       offset: -2 -2;
+                   }
+                   rel2 {
+                       relative: 1.0 1.0;
+                       offset: 1 1;
+                   }
+               }
+           }
+           part { name: "elm.swallow.pad";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   fixed: 1 0;
+                   align: 0.0 0.5;
+                   rel1 {
+                       relative: 0.0  0.0;
+                       offset:   4    4;
+                   }
+                   rel2 {
+                       relative: 0.0  1.0;
+                       offset:   4   -5;
+                   }
+               }
+           }
+           part { name: "arrow";
+               clip_to: "disclip";
+               ignore_flags: ON_HOLD;
+               description { state: "default" 0.0;
+                   fixed: 1 0;
+                   align: 0.0 0.5;
+                   aspect: 1.0 1.0;
+                   rel1 {
+                       to_x: "elm.swallow.pad";
+                       relative: 1.0  0.0;
+                       offset:   -1    4;
+                   }
+                   rel2 {
+                       to_x: "elm.swallow.pad";
+                       relative: 1.0  1.0;
+                       offset:   -1   -5;
+                   }
+                   image.normal: "icon_arrow_right.png";
+               }
+               description { state: "active" 0.0;
+                   inherit: "default" 0.0;
+                   image.normal: "icon_arrow_down.png";
+               }
+           }
+           part { name: "elm.swallow.icon";
+               clip_to: "disclip";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   fixed: 1 0;
+                   align: 0.0 0.5;
+                   rel1 {
+                       to_x: "arrow";
+                       relative: 1.0  0.0;
+                       offset:   4    4;
+                   }
+                   rel2 {
+                       to_x: "arrow";
+                       relative: 1.0  1.0;
+                       offset:   4   -5;
+                   }
+               }
+           }
+           part { name: "elm.swallow.end";
+               clip_to: "disclip";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   fixed: 1 0;
+                   align: 1.0 0.5;
+                   aspect: 1.0 1.0;
+                   aspect_preference: VERTICAL;
+                   rel1 {
+                       relative: 1.0  0.0;
+                       offset:   -5    4;
+                   }
+                   rel2 {
+                       relative: 1.0  1.0;
+                       offset:   -5   -5;
+                   }
+               }
+           }
+           part { name: "elm.text";
+               clip_to: "disclip";
+               type:           TEXTBLOCK;
+               effect:         SOFT_SHADOW;
+               mouse_events:   0;
+               scale: 1;
+               description {
+                   state: "default" 0.0;
+                   align: 0.0 0.5;
+                   fixed: 0 1;
+                   rel1 {
+                       to_x:     "elm.swallow.icon";
+                       to_y: "base";
+                       relative: 1.0  0.5;
+                       offset:   0 4;
+                   }
+                   rel2 {
+                       to_x:     "elm.swallow.end";
+                       to_y: "base";
+                       relative: 0.0  0.5;
+                       offset:   -1 -5;
+                   }
+                   text {
+                       style: "genlist_style";
+                       min: 1 1;
+                   }
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   text {
+                       style: "genlist_selected_style";
+                   }
+               }
+           }
+           part { name: "fg1";
+               clip_to: "disclip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+                   rel1.to: "bg";
+                   rel2.relative: 1.0 0.5;
+                   rel2.to: "bg";
+                   image {
+                       normal: "bt_sm_hilight.png";
+                       border: 6 6 6 0;
+                   }
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "fg2";
+               clip_to: "disclip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+                   rel1.to: "bg";
+                   rel2.to: "bg";
+                   image {
+                       normal: "bt_sm_shine.png";
+                       border: 6 6 6 0;
+                   }
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "disclip";
+               type: RECT;
+               description { state: "default" 0.0;
+                   rel1.to: "bg";
+                   rel2.to: "bg";
+               }
+               description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   color: 255 255 255 64;
+               }
+           }
+       }
+       programs {
+           // signal: elm,state,%s,active
+           //   a "check" item named %s went active
+           // signal: elm,state,%s,passive
+           //   a "check" item named %s went passive
+           // default is passive
+           program {
+               name:    "go_active";
+               signal:  "elm,state,selected";
+               source:  "elm";
+               action:  STATE_SET "selected" 0.0;
+               target:  "bg";
+               target:  "fg1";
+               target:  "fg2";
+               target:  "elm.text";
+           }
+           program {
+               name:    "go_passive";
+               signal:  "elm,state,unselected";
+               source:  "elm";
+               action:  STATE_SET "default" 0.0;
+               target:  "bg";
+               target:  "fg1";
+               target:  "fg2";
+               target:  "elm.text";
+               transition: LINEAR 0.1;
+           }
+           program {
+               name:    "go_disabled";
+               signal:  "elm,state,disabled";
+               source:  "elm";
+               action:  STATE_SET "disabled" 0.0;
+               target:  "disclip";
+           }
+           program {
+               name:    "go_enabled";
+               signal:  "elm,state,enabled";
+               source:  "elm";
+               action:  STATE_SET "default" 0.0;
+               target:  "disclip";
+           }
+           program {
+               name:    "expand";
+               signal:  "mouse,up,1";
+               source:  "arrow";
+               action:  SIGNAL_EMIT "elm,action,expand,toggle" "elm";
+           }
+           program {
+               name:    "go_expanded";
+               signal:  "elm,state,expanded";
+               source:  "elm";
+               action:  STATE_SET "active" 0.0;
+               target:  "arrow";
+           }
+           program {
+               name:    "go_contracted";
+               signal:  "elm,state,contracted";
+               source:  "elm";
+               action:  STATE_SET "default" 0.0;
+               target:  "arrow";
+           }
+       }
+   }
+
+
+   group { name: "elm/genlist/item/double_label/default";
+      data.item: "stacking" "above";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text elm.text.sub";
+      data.item: "icons" "elm.swallow.icon elm.swallow.end";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_1.png" COMP;
+         image: "ilist_item_shadow.png" COMP;
+      }
+      parts {
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base_sh";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               align: 0.0 0.0;
+               min: 0 10;
+               fixed: 1 1;
+               rel1 {
+                  to: "base";
+                  relative: 0.0 1.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  to: "base";
+                  relative: 1.0 1.0;
+                  offset: -1 0;
+               }
+               image {
+                  normal: "ilist_item_shadow.png";
+               }
+               fill.smooth: 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_1.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.end";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 1.0 0.5;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  0.5;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "elm.text.sub";
+            clip_to: "disclip";
+            type:           TEXT;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.5;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 128;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 8;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 128 128 128 255;
+               color3: 0 0 0 32;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            target:  "elm.text.sub";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            target:  "elm.text.sub";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+      }
+   }
+   group { name: "elm/genlist/item_compress/double_label/default";
+      data.item: "stacking" "above";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text elm.text.sub";
+      data.item: "icons" "elm.swallow.icon elm.swallow.end";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_1.png" COMP;
+         image: "ilist_item_shadow.png" COMP;
+      }
+      parts {
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base_sh";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               align: 0.0 0.0;
+               min: 0 10;
+               fixed: 1 1;
+               rel1 {
+                  to: "base";
+                  relative: 0.0 1.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  to: "base";
+                  relative: 1.0 1.0;
+                  offset: -1 0;
+               }
+               image {
+                  normal: "ilist_item_shadow.png";
+               }
+               fill.smooth: 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_1.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.end";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 1.0 0.5;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  0.5;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+//                  min: 1 1;
+                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "elm.text.sub";
+            clip_to: "disclip";
+            type:           TEXT;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.5;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 128;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 8;
+//                  min: 1 1;
+                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 128 128 128 255;
+               color3: 0 0 0 32;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            target:  "elm.text.sub";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            target:  "elm.text.sub";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+      }
+   }
+   group { name: "elm/genlist/item_odd/double_label/default";
+      data.item: "stacking" "below";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text elm.text.sub";
+      data.item: "icons" "elm.swallow.icon elm.swallow.end";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_2.png" COMP;
+      }
+      parts {
+         part { name: "event";
+            type: RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_2.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.end";
+            clip_to: "disclip";
+            type:          SWALLOW;
+            description { state:    "default" 0.0;
+               fixed: 1 0;
+               align:    1.0 0.5;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  0.5;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "elm.text.sub";
+            clip_to: "disclip";
+            type:           TEXT;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.5;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 128;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 8;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 128 128 128 255;
+               color3: 0 0 0 32;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            target:  "elm.text.sub";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            target:  "elm.text.sub";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+      }
+   }
+   group { name: "elm/genlist/item_compress_odd/double_label/default";
+      data.item: "stacking" "below";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text elm.text.sub";
+      data.item: "icons" "elm.swallow.icon elm.swallow.end";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_2.png" COMP;
+      }
+      parts {
+         part { name: "event";
+            type: RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_2.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.end";
+            clip_to: "disclip";
+            type:          SWALLOW;
+            description { state:    "default" 0.0;
+               fixed: 1 0;
+               align:    1.0 0.5;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  0.5;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+//                  min: 1 1;
+                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "elm.text.sub";
+            clip_to: "disclip";
+            type:           TEXT;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.5;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 128;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 8;
+//                  min: 1 1;
+                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 128 128 128 255;
+               color3: 0 0 0 32;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            target:  "elm.text.sub";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            target:  "elm.text.sub";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+      }
+   }
+
+   group { name: "elm/genlist/tree/double_label/default";
+      data.item: "stacking" "above";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text elm.text.sub";
+      data.item: "icons" "elm.swallow.icon elm.swallow.end";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_1.png" COMP;
+         image: "ilist_item_shadow.png" COMP;
+         image: "icon_arrow_right.png" COMP;
+         image: "icon_arrow_down.png" COMP;
+      }
+      parts {
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base_sh";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               align: 0.0 0.0;
+               min: 0 10;
+               fixed: 1 1;
+               rel1 {
+                  to: "base";
+                  relative: 0.0 1.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  to: "base";
+                  relative: 1.0 1.0;
+                  offset: -1 0;
+               }
+               image {
+                  normal: "ilist_item_shadow.png";
+               }
+               fill.smooth: 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_1.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "arrow";
+            clip_to: "disclip";
+            ignore_flags: ON_HOLD;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               aspect: 1.0 1.0;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+               image.normal: "icon_arrow_right.png";
+            }
+            description { state: "active" 0.0;
+               inherit: "default" 0.0;
+               image.normal: "icon_arrow_down.png";
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  to_x: "arrow";
+                  relative: 1.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  to_x: "arrow";
+                  relative: 1.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.end";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 1.0 0.5;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  0.5;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "elm.text.sub";
+            clip_to: "disclip";
+            type:           TEXT;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.5;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 128;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 8;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 128 128 128 255;
+               color3: 0 0 0 32;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            target:  "elm.text.sub";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            target:  "elm.text.sub";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "expand";
+            signal:  "mouse,up,1";
+            source:  "arrow";
+            action:  SIGNAL_EMIT "elm,action,expand,toggle" "elm";
+         }
+         program {
+            name:    "go_expanded";
+            signal:  "elm,state,expanded";
+            source:  "elm";
+            action:  STATE_SET "active" 0.0;
+            target:  "arrow";
+         }
+         program {
+            name:    "go_contracted";
+            signal:  "elm,state,contracted";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "arrow";
+         }
+      }
+   }
+   group { name: "elm/genlist/tree_compress/double_label/default";
+      data.item: "stacking" "above";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text elm.text.sub";
+      data.item: "icons" "elm.swallow.icon elm.swallow.end";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_1.png" COMP;
+         image: "ilist_item_shadow.png" COMP;
+         image: "icon_arrow_right.png" COMP;
+         image: "icon_arrow_down.png" COMP;
+      }
+      parts {
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base_sh";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               align: 0.0 0.0;
+               min: 0 10;
+               fixed: 1 1;
+               rel1 {
+                  to: "base";
+                  relative: 0.0 1.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  to: "base";
+                  relative: 1.0 1.0;
+                  offset: -1 0;
+               }
+               image {
+                  normal: "ilist_item_shadow.png";
+               }
+               fill.smooth: 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_1.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "arrow";
+            clip_to: "disclip";
+            ignore_flags: ON_HOLD;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               aspect: 1.0 1.0;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+               image.normal: "icon_arrow_right.png";
+            }
+            description { state: "active" 0.0;
+               inherit: "default" 0.0;
+               image.normal: "icon_arrow_down.png";
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  to_x: "arrow";
+                  relative: 1.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  to_x: "arrow";
+                  relative: 1.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.end";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 1.0 0.5;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  0.5;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+//                  min: 1 1;
+                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "elm.text.sub";
+            clip_to: "disclip";
+            type:           TEXT;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.5;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 128;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 8;
+//                  min: 1 1;
+                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 128 128 128 255;
+               color3: 0 0 0 32;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            target:  "elm.text.sub";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            target:  "elm.text.sub";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "expand";
+            signal:  "mouse,up,1";
+            source:  "arrow";
+            action:  SIGNAL_EMIT "elm,action,expand,toggle" "elm";
+         }
+         program {
+            name:    "go_expanded";
+            signal:  "elm,state,expanded";
+            source:  "elm";
+            action:  STATE_SET "active" 0.0;
+            target:  "arrow";
+         }
+         program {
+            name:    "go_contracted";
+            signal:  "elm,state,contracted";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "arrow";
+         }
+      }
+   }
+   group { name: "elm/genlist/tree_odd/double_label/default";
+      data.item: "stacking" "below";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text elm.text.sub";
+      data.item: "icons" "elm.swallow.icon elm.swallow.end";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_2.png" COMP;
+         image: "icon_arrow_right.png" COMP;
+         image: "icon_arrow_down.png" COMP;
+      }
+      parts {
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_2.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "arrow";
+            clip_to: "disclip";
+            ignore_flags: ON_HOLD;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               aspect: 1.0 1.0;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+               image.normal: "icon_arrow_right.png";
+            }
+            description { state: "active" 0.0;
+               inherit: "default" 0.0;
+               image.normal: "icon_arrow_down.png";
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  to_x: "arrow";
+                  relative: 1.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  to_x: "arrow";
+                  relative: 1.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.end";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 1.0 0.5;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  0.5;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "elm.text.sub";
+            clip_to: "disclip";
+            type:           TEXT;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.5;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 128;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 8;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 128 128 128 255;
+               color3: 0 0 0 32;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            target:  "elm.text.sub";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            target:  "elm.text.sub";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "expand";
+            signal:  "mouse,up,1";
+            source:  "arrow";
+            action:  SIGNAL_EMIT "elm,action,expand,toggle" "elm";
+         }
+         program {
+            name:    "go_expanded";
+            signal:  "elm,state,expanded";
+            source:  "elm";
+            action:  STATE_SET "active" 0.0;
+            target:  "arrow";
+         }
+         program {
+            name:    "go_contracted";
+            signal:  "elm,state,contracted";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "arrow";
+         }
+      }
+   }
+
+   group { name: "elm/genlist/item/icon_top_text_bottom/default";
+      data.item: "stacking" "above";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text";
+      data.item: "icons" "elm.swallow.icon";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_1.png" COMP;
+         image: "ilist_item_shadow.png" COMP;
+      }
+      parts {
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base_sh";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               align: 0.0 0.0;
+               min: 0 10;
+               fixed: 1 1;
+               rel1 {
+                  to: "base";
+                  relative: 0.0 1.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  to: "base";
+                  relative: 1.0 1.0;
+                  offset: -1 0;
+               }
+               image {
+                  normal: "ilist_item_shadow.png";
+               }
+               fill.smooth: 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_1.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.5 0.5;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 0.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_y:     "elm.swallow.icon";
+                  relative: 0.0  1.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.5 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+      }
+   }
+   group { name: "elm/genlist/item_odd/icon_top_text_bottom/default";
+      data.item: "stacking" "below";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text";
+      data.item: "icons" "elm.swallow.icon";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_2.png" COMP;
+      }
+      parts {
+         part { name: "event";
+            type: RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_2.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.5 0.5;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 0.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min:      16 16;
+               rel1 {
+                  to_y:     "elm.swallow.icon";
+                  relative: 0.0  1.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.5 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+      }
+   }
+
+   group { name: "elm/genlist/tree/icon_top_text_bottom/default";
+      data.item: "stacking" "above";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text";
+      data.item: "icons" "elm.swallow.icon";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_1.png" COMP;
+         image: "ilist_item_shadow.png" COMP;
+         image: "icon_arrow_right.png" COMP;
+         image: "icon_arrow_down.png" COMP;
+      }
+      parts {
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base_sh";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               align: 0.0 0.0;
+               min: 0 10;
+               fixed: 1 1;
+               rel1 {
+                  to: "base";
+                  relative: 0.0 1.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  to: "base";
+                  relative: 1.0 1.0;
+                  offset: -1 0;
+               }
+               image {
+                  normal: "ilist_item_shadow.png";
+               }
+               fill.smooth: 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_1.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "arrow";
+            clip_to: "disclip";
+            ignore_flags: ON_HOLD;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               aspect: 1.0 1.0;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+               image.normal: "icon_arrow_right.png";
+            }
+            description { state: "active" 0.0;
+               inherit: "default" 0.0;
+               image.normal: "icon_arrow_down.png";
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.5 0.5;
+               rel1 {
+                  to_x: "arrow";
+                  relative: 1.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -4   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_y:     "elm.swallow.icon";
+                  relative: 0.0  1.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.5 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "expand";
+            signal:  "mouse,up,1";
+            source:  "arrow";
+            action:  SIGNAL_EMIT "elm,action,expand,toggle" "elm";
+         }
+         program {
+            name:    "go_expanded";
+            signal:  "elm,state,expanded";
+            source:  "elm";
+            action:  STATE_SET "active" 0.0;
+            target:  "arrow";
+         }
+         program {
+            name:    "go_contracted";
+            signal:  "elm,state,contracted";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "arrow";
+         }
+      }
+   }
+   group { name: "elm/genlist/tree_odd/icon_top_text_bottom/default";
+      data.item: "stacking" "below";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text";
+      data.item: "icons" "elm.swallow.icon";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_2.png" COMP;
+         image: "icon_arrow_right.png" COMP;
+         image: "icon_arrow_down.png" COMP;
+      }
+      parts {
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_2.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "arrow";
+            clip_to: "disclip";
+            ignore_flags: ON_HOLD;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               aspect: 1.0 1.0;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+               image.normal: "icon_arrow_right.png";
+            }
+            description { state: "active" 0.0;
+               inherit: "default" 0.0;
+               image.normal: "icon_arrow_down.png";
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.5 0.5;
+               rel1 {
+                  to_x: "arrow";
+                  relative: 1.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -4   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_y:     "elm.swallow.icon";
+                  relative: 0.0  1.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+                  min: 1 1;
+//                  min: 0 1;
+                  align: 0.5 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "expand";
+            signal:  "mouse,up,1";
+            source:  "arrow";
+            action:  SIGNAL_EMIT "elm,action,expand,toggle" "elm";
+         }
+         program {
+            name:    "go_expanded";
+            signal:  "elm,state,expanded";
+            source:  "elm";
+            action:  STATE_SET "active" 0.0;
+            target:  "arrow";
+         }
+         program {
+            name:    "go_contracted";
+            signal:  "elm,state,contracted";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "arrow";
+         }
+      }
+   }
+
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/check/base/default";
+      images {
+         image: "check_base.png" COMP;
+        image: "check.png" COMP;
+        image: "check2.png" COMP;
+      }
+      parts {
+         part { name: "bg";
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              rel1.offset: 1 1;
+              rel2.relative: 0.0 1.0;
+              rel2.offset: 1 -2;
+              align: 0.0 0.5;
+              min: 16 16;
+              max: 16 16;
+              aspect: 1.0 1.0;
+              aspect_preference: VERTICAL;
+               image {
+                  normal: "check_base.png";
+                  border: 5 5 5 5;
+                  middle: 0;
+               }
+               fill.smooth : 0;
+           }
+        }
+         part { name: "check";
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+               rel1 {
+                  to: "bg";
+                  offset: 1 1;
+               }
+               rel2 {
+                  to: "bg";
+                  offset: -2 -2;
+               }
+               visible: 0;
+               color: 255 255 255 255;
+               image.normal: "check.png";
+           }
+           description { state: "visible" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+            }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+               visible: 0;
+              color: 128 128 128 128;
+           }
+           description { state: "disabled_visible" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 128;
+              visible: 1;
+           }
+        }
+        part { name: "elm.swallow.content";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+               fixed: 1 0;
+              visible: 0;
+               color: 255 255 255 255;
+              align: 0.0 0.5;
+               rel1.to_x: "bg";
+               rel1.relative: 1.0 0.0;
+              rel1.offset: 1 1;
+               rel2.to_x: "bg";
+              rel2.relative: 1.0 1.0;
+              rel2.offset: 2 -2;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+               fixed: 1 1;
+              visible: 1;
+              aspect: 1.0 1.0;
+              aspect_preference: VERTICAL;
+           }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 128;
+           }
+           description { state: "disabled_visible" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 128;
+               fixed: 1 1;
+              visible: 1;
+              aspect: 1.0 1.0;
+           }
+        }
+         part { name: "elm.text";
+           type: TEXT;
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              visible: 0;
+              rel1.to_x: "elm.swallow.content";
+              rel1.relative: 1.0 0.0;
+               rel1.offset: 1 1;
+              rel2.relative: 1.0 1.0;
+              rel2.offset: -2 -2;
+              color: 0 0 0 255;
+              text {
+                 font: "Sans,Edje-Vera";
+                 size: 10;
+                 min: 0 0;
+                 align: 0.0 0.5;
+              }
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              text.min: 1 1;
+           }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+              color: 0 0 0 128;
+              color3: 0 0 0 0;
+           }
+           description { state: "disabled_visible" 0.0;
+              inherit: "default" 0.0;
+              color: 0 0 0 128;
+              color3: 0 0 0 0;
+              visible: 1;
+              text.min: 1 1;
+           }
+        }
+         part { name: "events";
+           type: RECT;
+            ignore_flags: ON_HOLD;
+           description { state: "default" 0.0;
+              color: 0 0 0 0;
+           }
+        }
+        part { name: "disabler";
+           type: RECT;
+           description { state: "default" 0.0;
+              color: 0 0 0 0;
+              visible: 0;
+           }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+           }
+        }
+      }
+      programs {
+        program { name: "click";
+           signal: "mouse,up,1";
+           source: "events";
+            action: SIGNAL_EMIT "elm,action,check,toggle" "";
+        }
+        program { name: "check_on";
+           signal: "elm,state,check,on";
+           source: "elm";
+           action:  STATE_SET "visible" 0.0;
+           target: "check";
+        }
+        program { name: "check_off";
+           signal: "elm,state,check,off";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "check";
+        }
+        program { name: "text_show";
+           signal: "elm,state,text,visible";
+           source: "elm";
+           action:  STATE_SET "visible" 0.0;
+           target: "elm.text";
+        }
+        program { name: "text_hide";
+           signal: "elm,state,text,hidden";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "elm.text";
+        }
+        program { name: "icon_show";
+           signal: "elm,state,icon,visible";
+           source: "elm";
+           action:  STATE_SET "visible" 0.0;
+           target: "elm.swallow.content";
+        }
+        program { name: "icon_hide";
+           signal: "elm,state,icon,hidden";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "elm.swallow.content";
+        }
+        program { name: "disable";
+           signal: "elm,state,disabled";
+           source: "elm";
+           action: STATE_SET "disabled" 0.0;
+           target: "disabler";
+            after: "disable_text";
+        }
+         program { name: "disable_text";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.text", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.text", "disabled_visible", 0.0);
+              else
+                set_state(PART:"elm.text", "disabled", 0.0);
+
+               get_state(PART:"elm.swallow.content", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.swallow.content", "disabled_visible", 0.0);
+              else
+                set_state(PART:"elm.swallow.content", "disabled", 0.0);
+
+               get_state(PART:"check", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"check", "disabled_visible", 0.0);
+              else
+                set_state(PART:"check", "disabled", 0.0);
+           }
+         }
+        program { name: "enable";
+           signal: "elm,state,enabled";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "disabler";
+            after: "enable_text";
+        }
+         program { name: "enable_text";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.text", st, 30, vl);
+              if (!strcmp(st, "disabled_visible"))
+                set_state(PART:"elm.text", "visible", 0.0);
+              else
+                set_state(PART:"elm.text", "default", 0.0);
+
+               get_state(PART:"elm.swallow.content", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.swallow.content", "visible", 0.0);
+              else
+                set_state(PART:"elm.swallow.content", "default", 0.0);
+
+               get_state(PART:"check", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"check", "visible", 0.0);
+              else
+                set_state(PART:"check", "default", 0.0);
+           }
+         }
+      }
+   }
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/radio/base/default";
+      images {
+         image: "radio_base.png" COMP;
+        image: "radio.png" COMP;
+        image: "radio2.png" COMP;
+      }
+      parts {
+         part { name: "bg";
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              rel1.offset: 1 1;
+              rel2.relative: 0.0 1.0;
+              rel2.offset: 1 -2;
+              align: 0.0 0.5;
+              min: 16 16;
+              max: 16 16;
+              aspect: 1.0 1.0;
+              aspect_preference: VERTICAL;
+               image.normal: "radio_base.png";
+           }
+        }
+         part { name: "radio";
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               visible: 0;
+               image.normal: "radio.png";
+           }
+           description { state: "visible" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+            }
+        }
+        part { name: "elm.swallow.content";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+               fixed: 1 0;
+              visible: 0;
+              align: 0.0 0.5;
+               color: 0 0 0 0;
+               rel1.to_x: "bg";
+               rel1.relative: 1.0 0.0;
+              rel1.offset: 1 1;
+               rel2.to_x: "bg";
+              rel2.relative: 1.0 1.0;
+              rel2.offset: 2 -2;
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+               fixed: 1 1;
+              visible: 1;
+               color: 255 255 255 255;
+              aspect: 1.0 1.0;
+              aspect_preference: VERTICAL;
+           }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 128;
+           }
+           description { state: "disabled_visible" 0.0;
+              inherit: "default" 0.0;
+              color: 128 128 128 128;
+              visible: 1;
+           }
+        }
+         part { name: "elm.text";
+           type: TEXT;
+           mouse_events: 0;
+           scale: 1;
+           description { state: "default" 0.0;
+              visible: 0;
+              rel1.to_x: "elm.swallow.content";
+              rel1.relative: 1.0 0.0;
+               rel1.offset: 1 1;
+              rel2.relative: 1.0 1.0;
+              rel2.offset: -2 -2;
+              color: 0 0 0 255;
+              text {
+                 font: "Sans,Edje-Vera";
+                 size: 10;
+                 min: 0 0;
+                 align: 0.0 0.5;
+              }
+           }
+           description { state: "visible" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+              text.min: 1 1;
+           }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+              color: 0 0 0 128;
+              color3: 0 0 0 0;
+           }
+           description { state: "disabled_visible" 0.0;
+              inherit: "default" 0.0;
+              color: 0 0 0 128;
+              color3: 0 0 0 0;
+              visible: 1;
+              text.min: 1 1;
+           }
+        }
+         part { name: "events";
+           type: RECT;
+            ignore_flags: ON_HOLD;
+           description { state: "default" 0.0;
+              color: 0 0 0 0;
+           }
+        }
+        part { name: "disabler";
+           type: RECT;
+           description { state: "default" 0.0;
+              color: 0 0 0 0;
+              visible: 0;
+           }
+           description { state: "disabled" 0.0;
+              inherit: "default" 0.0;
+              visible: 1;
+           }
+        }
+      }
+      programs {
+        program { name: "click";
+           signal: "mouse,up,1";
+           source: "events";
+            action: SIGNAL_EMIT "elm,action,radio,toggle" "";
+        }
+        program { name: "radio_on";
+           signal: "elm,state,radio,on";
+           source: "elm";
+           action:  STATE_SET "visible" 0.0;
+           target: "radio";
+        }
+        program { name: "radio_off";
+           signal: "elm,state,radio,off";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "radio";
+        }
+        program { name: "text_show";
+           signal: "elm,state,text,visible";
+           source: "elm";
+           action:  STATE_SET "visible" 0.0;
+           target: "elm.text";
+        }
+        program { name: "text_hide";
+           signal: "elm,state,text,hidden";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "elm.text";
+        }
+        program { name: "icon_show";
+           signal: "elm,state,icon,visible";
+           source: "elm";
+           action:  STATE_SET "visible" 0.0;
+           target: "elm.swallow.content";
+        }
+        program { name: "icon_hide";
+           signal: "elm,state,icon,hidden";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "elm.swallow.content";
+        }
+        program { name: "disable";
+           signal: "elm,state,disabled";
+           source: "elm";
+           action: STATE_SET "disabled" 0.0;
+           target: "disabler";
+            after: "disable_text";
+        }
+         program { name: "disable_text";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.text", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.text", "disabled_visible", 0.0);
+              else
+                set_state(PART:"elm.text", "disabled", 0.0);
+
+               get_state(PART:"elm.swallow.content", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.swallow.content", "disabled_visible", 0.0);
+              else
+                set_state(PART:"elm.swallow.content", "disabled", 0.0);
+           }
+         }
+        program { name: "enable";
+           signal: "elm,state,enabled";
+           source: "elm";
+           action: STATE_SET "default" 0.0;
+           target: "disabler";
+            after: "enable_text";
+        }
+         program { name: "enable_text";
+           script {
+              new st[31];
+              new Float:vl;
+              get_state(PART:"elm.text", st, 30, vl);
+              if (!strcmp(st, "disabled_visible"))
+                set_state(PART:"elm.text", "visible", 0.0);
+              else
+                set_state(PART:"elm.text", "default", 0.0);
+
+               get_state(PART:"elm.swallow.content", st, 30, vl);
+              if (!strcmp(st, "visible"))
+                set_state(PART:"elm.swallow.content", "visible", 0.0);
+              else
+                set_state(PART:"elm.swallow.content", "default", 0.0);
+           }
+         }
+      }
+   }
+   group { name: "elm/genlist/tree_compress_odd/double_label/default";
+      data.item: "stacking" "below";
+      data.item: "selectraise" "on";
+      data.item: "labels" "elm.text elm.text.sub";
+      data.item: "icons" "elm.swallow.icon elm.swallow.end";
+      data.item: "treesize" "20";
+//      data.item: "states" "";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_2.png" COMP;
+         image: "icon_arrow_right.png" COMP;
+         image: "icon_arrow_down.png" COMP;
+      }
+      parts {
+         part {
+            name:           "event";
+            type:           RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_2.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  relative: 0.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "arrow";
+            clip_to: "disclip";
+            ignore_flags: ON_HOLD;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               aspect: 1.0 1.0;
+               rel1 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_x: "elm.swallow.pad";
+                  relative: 1.0  1.0;
+                  offset:   -1   -5;
+               }
+               image.normal: "icon_arrow_right.png";
+            }
+            description { state: "active" 0.0;
+               inherit: "default" 0.0;
+               image.normal: "icon_arrow_down.png";
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  to_x: "arrow";
+                  relative: 1.0  0.0;
+                  offset:   4    4;
+               }
+               rel2 {
+                  to_x: "arrow";
+                  relative: 1.0  1.0;
+                  offset:   4   -5;
+               }
+            }
+         }
+         part { name: "elm.swallow.end";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 1.0 0.5;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               rel1 {
+                  relative: 1.0  0.0;
+                  offset:   -5    4;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset:   -5   -5;
+               }
+            }
+         }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type:           TEXT;
+            effect:         SOFT_SHADOW;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.0;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  0.5;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+//                  min: 1 1;
+                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "elm.text.sub";
+            clip_to: "disclip";
+            type:           TEXT;
+            mouse_events:   0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+//               min: 16 16;
+               rel1 {
+                  to_x:     "elm.swallow.icon";
+                  relative: 1.0  0.5;
+                  offset:   0 4;
+               }
+               rel2 {
+                  to_x:     "elm.swallow.end";
+                  relative: 0.0  1.0;
+                  offset:   -1 -5;
+               }
+               color: 0 0 0 128;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 8;
+//                  min: 1 1;
+                  min: 0 1;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 128 128 128 255;
+               color3: 0 0 0 32;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            target:  "elm.text.sub";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            target:  "elm.text.sub";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "expand";
+            signal:  "mouse,up,1";
+            source:  "arrow";
+            action:  SIGNAL_EMIT "elm,action,expand,toggle" "elm";
+         }
+         program {
+            name:    "go_expanded";
+            signal:  "elm,state,expanded";
+            source:  "elm";
+            action:  STATE_SET "active" 0.0;
+            target:  "arrow";
+         }
+         program {
+            name:    "go_contracted";
+            signal:  "elm,state,contracted";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "arrow";
+         }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/pager/base/default";
+      data.item: "onshow" "raise";
+// other options
+//      data.item: "onhide" "lower";
+//      data.item: "onshow" "lower";
+      images {
+        image: "frame_1.png" COMP;
+        image: "frame_2.png" COMP;
+         image: "dia_grad.png" COMP;
+      }
+      parts {
+         part { name: "clip";
+            type: RECT;
+           mouse_events: 0;
+           description { state: "default" 0.0;
+              rel1 {
+                  to: "base";
+                  offset: -9999 -9999;
+               }
+              rel2 {
+                  to: "base";
+                  offset: 9999 9999;
+               }
+               color: 255 255 255 255;
+           }
+           description { state: "visible" 0.0;
+               inherit: "default" 0.0;
+           }
+           description { state: "hidden" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 0;
+               visible: 0;
+           }
+        }
+         part { name: "base0";
+           mouse_events:  0;
+            clip_to: "clip";
+           description { state: "default" 0.0;
+              image.normal: "dia_grad.png";
+              rel1.to: "over";
+              rel2.to: "over";
+               fill {
+                 smooth: 0;
+                 size {
+                    relative: 0.0 1.0;
+                     offset: 64 0;
+                 }
+              }
+           }
+        }
+        part { name: "base";
+           mouse_events:  0;
+            clip_to: "clip";
+           description { state: "default" 0.0;
+              image {
+                 normal: "frame_2.png";
+                 border: 5 5 32 26;
+                 middle: 0;
+              }
+              fill.smooth : 0;
+           }
+           description { state: "hidden" 0.0;
+               inherit: "default" 0.0;
+               rel1.relative: -1.0 0.0;
+               rel2.relative: 0.0 1.0;
+           }
+           description { state: "visible" 0.0;
+               inherit: "default" 0.0;
+               rel1.relative: 0.0 0.0;
+               rel2.relative: 1.0 1.0;
+           }
+        }
+         part { name: "over";
+           mouse_events:  0;
+            clip_to: "clip";
+           description { state:    "default" 0.0;
+              rel1 {
+                  to: "base";
+                  offset: 4 4;
+               }
+              rel2 {
+                  to: "base";
+                  offset: -5 -5;
+               }
+              image {
+                 normal: "frame_1.png";
+                 border: 2 2 28 22;
+                 middle: 0;
+              }
+              fill.smooth : 0;
+           }
+        }
+        part { name: "elm.swallow.content";
+           type: SWALLOW;
+            clip_to: "clip";
+           description { state: "default" 0.0;
+              rel1 {
+                  to: "base";
+                  offset: 8 8;
+               }
+              rel2 {
+                  to: "base";
+                  offset: -9 -9;
+               }
+           }
+        }
+      }
+      programs {
+         program { name: "show_start";
+           signal: "elm,action,show";
+           source: "elm";
+           action:  STATE_SET "hidden" 0.0;
+           target: "base";
+           target: "clip";
+            after: "show_start2";
+        }
+         program { name: "show_start2";
+           action:  STATE_SET "visible" 0.0;
+            transition: DECELERATE 0.5;
+           target: "base";
+           target: "clip";
+            after: "show_end";
+        }
+         program { name: "show_end";
+            action: SIGNAL_EMIT "elm,action,show,finished" "";
+        }
+         program { name: "hide_start";
+           signal: "elm,action,hide";
+           source: "elm";
+           action:  STATE_SET "visible" 0.0;
+           target: "base";
+           target: "clip";
+            after: "hide_start2";
+        }
+         program { name: "hide_start2";
+           action:  STATE_SET "hidden" 0.0;
+            transition: DECELERATE 0.5;
+           target: "base";
+           target: "clip";
+            after: "hide_end";
+        }
+         program { name: "hide_end";
+            action: SIGNAL_EMIT "elm,action,hide,finished" "";
+        }
+         program { name: "reset";
+           signal: "elm,action,reset";
+           source: "elm";
+           action:  STATE_SET "default" 0.0;
+           target: "base";
+           target: "clip";
+        }
+      }
+   }
+
+   group { name: "elm/pager/base/fade";
+       data.item: "onshow" "raise";
+       // other options
+       //      data.item: "onhide" "lower";
+       //      data.item: "onshow" "lower";
+       images {
+           image: "frame_1.png" COMP;
+           image: "frame_2.png" COMP;
+           image: "dia_grad.png" COMP;
+       }
+       parts {
+           part { name: "clip_base";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1 {
+                       to: "base";
+                       offset: -9999 -9999;
+                   }
+                   rel2 {
+                       to: "base";
+                       offset: 9999 9999;
+                   }
+                   color: 255 255 255 120;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+               }
+               description { state: "hidden" 0.0;
+                   inherit: "default" 0.0;
+                   color: 255 255 255 0;
+                   visible: 0;
+               }
+           }
+           part { name: "clip";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1 {
+                       to: "base";
+                       offset: -9999 -9999;
+                   }
+                   rel2 {
+                       to: "base";
+                       offset: 9999 9999;
+                   }
+                   color: 255 255 255 255;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+               }
+               description { state: "hidden" 0.0;
+                   inherit: "default" 0.0;
+                   color: 255 255 255 0;
+                   visible: 0;
+               }
+           }
+           part { name: "base0";
+               mouse_events:  0;
+               clip_to: "clip_base";
+               description { state: "default" 0.0;
+                   image.normal: "dia_grad.png";
+                   rel1.to: "over";
+                   rel2.to: "over";
+                   fill {
+                       smooth: 0;
+                       size {
+                           relative: 0.0 1.0;
+                           offset: 64 0;
+                       }
+                   }
+               }
+           }
+           part { name: "base";
+               mouse_events:  0;
+               clip_to: "clip_base";
+               description { state: "default" 0.0;
+                   image {
+                       normal: "frame_2.png";
+                       border: 5 5 32 26;
+                       middle: 0;
+                   }
+                   fill.smooth : 0;
+               }
+           }
+           part { name: "over";
+               mouse_events:  0;
+               clip_to: "clip";
+               description { state:    "default" 0.0;
+                   rel1 {
+                       to: "base";
+                       offset: 4 4;
+                   }
+                   rel2 {
+                       to: "base";
+                       offset: -5 -5;
+                   }
+                   image {
+                       normal: "frame_1.png";
+                       border: 2 2 28 22;
+                       middle: 0;
+                   }
+                   fill.smooth : 0;
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               clip_to: "clip";
+               description { state: "default" 0.0;
+                   rel1 {
+                       to: "base";
+                       offset: 8 8;
+                   }
+                   rel2 {
+                       to: "base";
+                       offset: -9 -9;
+                   }
+               }
+           }
+       }
+       programs {
+           program { name: "show_start";
+               signal: "elm,action,show";
+               source: "elm";
+               action:  STATE_SET "hidden" 0.0;
+               target: "clip";
+               target: "clip_base";
+               after: "show_start2";
+           }
+           program { name: "show_start2";
+               action:  STATE_SET "visible" 0.0;
+               transition: DECELERATE 0.5;
+               target: "clip";
+               target: "clip_base";
+               after: "show_end";
+           }
+           program { name: "show_end";
+               action: SIGNAL_EMIT "elm,action,show,finished" "";
+           }
+           program { name: "hide_start";
+               signal: "elm,action,hide";
+               source: "elm";
+               action:  STATE_SET "visible" 0.0;
+               target: "clip";
+               target: "clip_base";
+               after: "hide_start2";
+           }
+           program { name: "hide_start2";
+               action:  STATE_SET "hidden" 0.0;
+               transition: DECELERATE 0.5;
+               target: "clip";
+               target: "clip_base";
+               after: "hide_end";
+           }
+           program { name: "hide_end";
+               action: SIGNAL_EMIT "elm,action,hide,finished" "";
+           }
+           program { name: "reset";
+               signal: "elm,action,reset";
+               source: "elm";
+               action:  STATE_SET "default" 0.0;
+               target: "clip_base";
+               target: "clip";
+           }
+       }
+   }
+   group { name: "elm/pager/base/fade_translucide";
+       data.item: "onshow" "raise";
+       // other options
+       //      data.item: "onhide" "lower";
+       //      data.item: "onshow" "lower";
+       images {
+           image: "frame_1.png" COMP;
+           image: "frame_2.png" COMP;
+           image: "dia_grad.png" COMP;
+       }
+       parts {
+           part { name: "clip_base";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1 {
+                       to: "base";
+                       offset: -9999 -9999;
+                   }
+                   rel2 {
+                       to: "base";
+                       offset: 9999 9999;
+                   }
+                   color: 255 255 255 120;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+               }
+               description { state: "hidden" 0.0;
+                   inherit: "default" 0.0;
+                   color: 255 255 255 0;
+                   visible: 0;
+               }
+           }
+           part { name: "clip";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1 {
+                       to: "base";
+                       offset: -9999 -9999;
+                   }
+                   rel2 {
+                       to: "base";
+                       offset: 9999 9999;
+                   }
+                   color: 255 255 255 255;
+               }
+               description { state: "visible" 0.0;
+                   inherit: "default" 0.0;
+               }
+               description { state: "hidden" 0.0;
+                   inherit: "default" 0.0;
+                   color: 255 255 255 0;
+                   visible: 0;
+               }
+           }
+           part { name: "base0";
+               mouse_events:  0;
+               clip_to: "clip_base";
+               description { state: "default" 0.0;
+                   image.normal: "dia_grad.png";
+                   rel1.to: "over";
+                   rel2.to: "over";
+                   fill {
+                       smooth: 0;
+                       size {
+                           relative: 0.0 1.0;
+                           offset: 64 0;
+                       }
+                   }
+               }
+           }
+           part { name: "base";
+               mouse_events:  0;
+               clip_to: "clip_base";
+               description { state: "default" 0.0;
+                   image {
+                       normal: "frame_2.png";
+                       border: 5 5 32 26;
+                       middle: 0;
+                   }
+                   fill.smooth : 0;
+               }
+           }
+           part { name: "over";
+               mouse_events:  0;
+               clip_to: "clip";
+               description { state:    "default" 0.0;
+                   rel1 {
+                       to: "base";
+                       offset: 4 4;
+                   }
+                   rel2 {
+                       to: "base";
+                       offset: -5 -5;
+                   }
+                   image {
+                       normal: "frame_1.png";
+                       border: 2 2 28 22;
+                       middle: 0;
+                   }
+                   fill.smooth : 0;
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               clip_to: "clip";
+               description { state: "default" 0.0;
+                   rel1 {
+                       to: "base";
+                       offset: 8 8;
+                   }
+                   rel2 {
+                       to: "base";
+                       offset: -9 -9;
+                   }
+               }
+           }
+       }
+       programs {
+           program { name: "show_start";
+               signal: "elm,action,show";
+               source: "elm";
+               action:  STATE_SET "hidden" 0.0;
+               target: "clip";
+               target: "clip_base";
+               after: "show_start2";
+           }
+           program { name: "show_start2";
+               action:  STATE_SET "visible" 0.0;
+               transition: DECELERATE 0.5;
+               target: "clip";
+               target: "clip_base";
+               after: "show_end";
+           }
+           program { name: "show_end";
+               action: SIGNAL_EMIT "elm,action,show,finished" "";
+           }
+           program { name: "hide_start";
+               signal: "elm,action,hide";
+               source: "elm";
+               action:  STATE_SET "visible" 0.0;
+               target: "clip";
+               target: "clip_base";
+               after: "hide_start2";
+           }
+           program { name: "hide_start2";
+               action:  STATE_SET "hidden" 0.0;
+               transition: DECELERATE 0.5;
+               target: "clip";
+               target: "clip_base";
+               after: "hide_end";
+           }
+           program { name: "hide_end";
+               action: SIGNAL_EMIT "elm,action,hide,finished" "";
+           }
+           program { name: "reset";
+               signal: "elm,action,reset";
+               source: "elm";
+               action:  STATE_SET "default" 0.0;
+               target: "clip_base";
+               target: "clip";
+           }
+       }
+   }
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// FIXME: this doesn't look too hot. need to fix it up
+   group { name: "elm/progressbar/horizontal/default";
+      images {
+         image: "shelf_inset.png" COMP;
+         image: "bt_sm_base2.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+      }
+      parts {
+         part { name: "elm.background.progressbar";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+               }
+            }
+         }
+         part { name: "elm.swallow.bar";
+            mouse_events: 0;
+            type: SWALLOW;
+            description {
+               min: 48 28;
+               max: 99999 28;
+               state: "default" 0.0;
+               rel1 {
+                  to_x: "elm.text";
+                  to_y: "elm.background.progressbar";
+                  relative: 1.0 0.0;
+               }
+               rel2 {
+                  to: "elm.background.progressbar";
+                  relative: 1.0 1.0;
+               }
+            }
+         }
+         part { name: "elm.swallow.content";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               visible: 0;
+               align: 0.0 0.5;
+               rel1 {
+                  offset: 4 0;
+                  to_y: "elm.background.progressbar";
+               }
+               rel2 {
+                  offset: 3 -1;
+                  relative: 0.0 1.0;
+                  to_y: "elm.background.progressbar";
+               }
+            }
+            description { state: "visible" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+               rel2.offset: 4 -1;
+            }
+         }
+         part { name: "elm.text";
+            type: TEXT;
+            mouse_events: 0;
+            scale: 1;
+            description { state: "default" 0.0;
+               visible: 0;
+               fixed: 1 1;
+               align: 0.0 0.5;
+               rel1.to_x: "elm.swallow.content";
+               rel1.relative: 1.0 0.0;
+               rel1.offset: -1 4;
+               rel2.to_x: "elm.swallow.content";
+               rel2.relative: 1.0 1.0;
+               rel2.offset: -1 -5;
+               color: 0 0 0 255;
+               text {
+                  font: "Sans,Edje-Vera";
+                  size: 10;
+                  min: 0 0;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "visible" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               text.min: 1 1;
+               rel1.offset: 0 4;
+               rel2.offset: 0 -5;
+            }
+         }
+
+         part { name: "background";
+            mouse_events: 0;
+            clip_to: "elm.background.progressbar";
+            description {
+               state: "default" 0.0;
+               rel1 {
+                  to: "elm.swallow.bar";
+                  relative: 0.0 0.0;
+               }
+               rel2 {
+                  to: "elm.swallow.bar";
+                  relative: 1.0 1.0;
+                  offset: -1 -1;
+               }
+               image {
+                  normal: "shelf_inset.png";
+                  border: 7 7 7 7;
+               }
+            }
+         }
+
+         part { name: "elm.text.status";
+            type: TEXT;
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               fixed: 1 1;
+               visible: 1;
+               rel1 {
+                  to: "background";
+                  relative: 0.5 0.5;
+               }
+               rel2 {
+                  to: "background";
+                  relative: 0.5 0.5;
+               }
+               text {
+                  font: "Sans:style=Bold,Edje-Vera-Bold";
+                  size: 10;
+                  min: 1 1;
+                  align: 0.5 0.0;
+               }
+               color: 0 0 0 255;
+            }
+            description { state: "hidden" 0.0;
+               inherit: "default" 0.0;
+               visible: 0;
+               text.min: 0 0;
+            }
+         }
+
+         part { name: "elm.progress.progressbar";
+            mouse_events: 0;
+            clip_to: "elm.background.progressbar";
+            description {
+               state: "default" 0.0;
+               min: 14 28;
+               fixed: 1 1;
+               rel1 {
+                  to: "elm.swallow.bar";
+                  relative: 0.0 0.0;
+               }
+               rel2 {
+                  to_y: "elm.swallow.bar";
+                  to_x: "elm.cur.progressbar";
+                  offset: -1 -1;
+               }
+               image {
+                  normal: "bt_sm_base2.png";
+                  border: 6 6 6 6;
+               }
+            }
+            description {
+               state: "invert" 0.0;
+               inherit: "default" 0.0;
+               rel1 {
+                  to_y: "elm.swallow.bar";
+                  to_x: "elm.cur.progressbar";
+               }
+               rel2 {
+                  to: "elm.swallow.bar";
+                  relative: 1.0 1.0;
+               }
+            }
+            description {
+               state: "state_begin" 0.0;
+               inherit: "default" 0.0;
+               rel1 {
+                  to: "elm.swallow.bar";
+                  relative: 0.0 0.0;
+               }
+               rel2 {
+                  to: "elm.swallow.bar";
+                  relative: 0.1 1.0;
+               }
+            }
+            description {
+               state: "state_end" 0.0;
+               inherit: "default" 0.0;
+               rel1 {
+                  to: "elm.swallow.bar";
+                  relative: 0.9 0.0;
+               }
+               rel2 {
+                  to: "elm.swallow.bar";
+                  relative: 1.0 1.0;
+               }
+            }
+         }
+         part { name: "text-bar";
+            type: TEXT;
+            mouse_events: 0;
+            clip_to: "progress-rect";
+            effect: SOFT_SHADOW;
+            scale: 1;
+            description { state: "default" 0.0;
+               align: 0.0 0.0;
+               fixed: 1 1;
+               visible: 1;
+               rel1.to: "elm.text.status";
+               rel1.offset: -1 -1;
+               rel2.to: "elm.text.status";
+               text {
+                  text_source: "elm.text.status";
+                  font: "Sans:style=Bold,Edje-Vera-Bold";
+                  size: 10;
+                  min: 1 1;
+                  align: 0.0 0.0;
+               }
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+            description { state: "hidden" 0.0;
+               inherit: "default" 0.0;
+               visible: 0;
+               text.min: 0 0;
+            }
+         }
+
+         part { name: "over1";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               rel1.to: "elm.progress.progressbar";
+               rel2.to: "elm.progress.progressbar";
+               rel2.relative: 1.0 0.5;
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+         }
+
+         part { name: "over2";
+            mouse_events: 1;
+            repeat_events: 1;
+            description { state: "default" 0.0;
+               rel1.to: "elm.progress.progressbar";
+               rel2.to: "elm.progress.progressbar";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+         }
+
+         part { name: "elm.cur.progressbar";
+            mouse_events: 0;
+            dragable {
+               confine: "background";
+               x: 1 1 1;
+               y: 0 0 0;
+            }
+            description { state: "default" 0.0;
+               min: 14 28;
+               fixed: 1 1;
+               visible: 0;
+               rel1 {
+                  to: "background";
+                  relative: 0 0;
+               }
+               rel2.to: "background";
+           }
+         }
+         part { name: "progress-rect";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               rel1.to: "elm.progress.progressbar";
+               rel2.to: "elm.progress.progressbar";
+            }
+         }
+      }
+      programs {
+         program { name: "label_show";
+            signal: "elm,state,text,visible";
+            source: "elm";
+            action:  STATE_SET "visible" 0.0;
+            target: "elm.text";
+         }
+         program { name: "label_hide";
+            signal: "elm,state,text,hidden";
+            source: "elm";
+            action:  STATE_SET "default" 0.0;
+            target: "elm.text";
+         }
+         program { name: "icon_show";
+            signal: "elm,state,icon,visible";
+            source: "elm";
+            action:  STATE_SET "visible" 0.0;
+            target: "elm.swallow.content";
+         }
+         program { name: "icon_hide";
+            signal: "elm,state,icon,hidden";
+            source: "elm";
+            action:  STATE_SET "default" 0.0;
+            target: "elm.swallow.content";
+         }
+         program { name: "units_show";
+            signal: "elm,state,units,visible";
+            source: "elm";
+            action:  STATE_SET "default" 0.0;
+            target: "text-bar";
+            target: "elm.text.status";
+         }
+         program { name: "units_hide";
+            signal: "elm,state,units,hidden";
+            source: "elm";
+            action:  STATE_SET "hidden" 0.0;
+            target: "text-bar";
+            target: "elm.text.status";
+         }
+         program { name: "slide_to_end";
+            action:  STATE_SET "state_end" 0.0;
+            transition: LINEAR 0.5;
+            target: "elm.progress.progressbar";
+            after: "slide_to_begin";
+         }
+         program { name: "slide_to_begin";
+            signal: "elm,state,slide,begin";
+            action: STATE_SET "state_begin" 0.0;
+            target: "elm.progress.progressbar";
+            transition: LINEAR 0.5;
+            after: "slide_to_end";
+         }
+         program { name: "start_pulse";
+            signal: "elm,state,pulse,start";
+            source: "elm";
+            after: "slide_to_end";
+         }
+         program { name: "stop_pulse";
+            signal: "elm,state,pulse,stop";
+            source: "elm";
+            action: ACTION_STOP;
+            target: "slide_to_begin";
+            target: "slide_to_end";
+            target: "start_pulse";
+            after: "state_pulse";
+         }
+         program { name: "state_pulse";
+            signal: "elm,state,pulse";
+            source: "elm";
+            action: STATE_SET "state_begin" 0.0;
+            target: "elm.progress.progressbar";
+            after: "units_hide";
+         }
+         program { name: "state_fraction";
+            signal: "elm,state,fraction";
+            source: "elm";
+            action: ACTION_STOP;
+            target: "slide_to_begin";
+            target: "slide_to_end";
+            target: "start_pulse";
+            action: STATE_SET "default" 0.0;
+            target: "elm.progress.progressbar";
+         }
+         program { name: "set_invert_on";
+            signal: "elm,state,inverted,on";
+            source: "elm";
+            action:  STATE_SET "invert" 0.0;
+            target: "elm.progress.progressbar";
+         }
+         program { name: "set_invert_off";
+            signal: "elm,state,inverted,off";
+            source: "elm";
+            action:  STATE_SET "default" 0.0;
+            target: "elm.progress.progressbar";
+         }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/progressbar/vertical/default";
+      images {
+         image: "shelf_inset.png" COMP;
+         image: "bt_sm_base2.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+      }
+      parts {
+         part { name: "elm.background.progressbar";
+            type: RECT;
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: -1 -1;
+               }
+            }
+         }
+         part { name: "elm.swallow.bar";
+            type: SWALLOW;
+            scale: 1;
+            description { state: "default" 0.0;
+               min: 28 48;
+               max: 28 9999;
+               align: 0.5 1.0;
+               rel1 {
+                  to_y: "elm.text";
+                  relative: 0.0 1.0;
+                  offset: 0 2;
+               }
+               rel2 {
+                  to_y: "elm.text.box";
+                  relative: 1.0 0.0;
+                  offset: -1 -3;
+               }
+            }
+         }
+         part { name: "elm.swallow.content";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               visible: 0;
+               align: 0.5 0.0;
+               rel1 {
+                  offset: 0 4;
+                  to_x: "elm.swallow.bar";
+               }
+               rel2 {
+                  offset: -1 3;
+                  relative: 1.0 0.0;
+                  to_x: "elm.swallow.bar";
+               }
+            }
+            description { state: "visible" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               aspect: 1.0 1.0;
+               aspect_preference: HORIZONTAL;
+               rel2.offset: -1 4;
+            }
+         }
+         part { name: "elm.text";
+            type: TEXT;
+            mouse_events: 0;
+            scale: 1;
+            description { state: "default" 0.0;
+               visible: 0;
+               fixed: 1 1;
+               align: 0.5 0.0;
+               rel1.to_y: "elm.swallow.content";
+               rel1.relative: 0.5 1.0;
+               rel1.offset: 0 -1;
+               rel2.to_y: "elm.swallow.content";
+               rel2.relative: 0.5 1.0;
+               rel2.offset: -1 -1;
+               color: 0 0 0 255;
+               text {
+                  font: "Sans,Edje-Vera";
+                  size: 10;
+                  min: 0 0;
+                  align: 0.5 0.0;
+               }
+            }
+            description { state: "visible" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               text.min: 1 1;
+               rel1.offset: 4 0;
+               rel2.offset: -5 0;
+            }
+         }
+
+         part { name: "background";
+            mouse_events: 0;
+            clip_to: "elm.background.progressbar";
+            description {
+               state: "default" 0.0;
+               rel1 {
+                  to: "elm.swallow.bar";
+                  relative: 0.0 0.0;
+               }
+               rel2 {
+                  to: "elm.swallow.bar";
+                  relative: 1.0 1.0;
+                  offset: -1 -1;
+               }
+               image {
+                  normal: "shelf_inset.png";
+                  border: 7 7 7 7;
+               }
+            }
+         }
+
+         part { name: "elm.progress.progressbar";
+            mouse_events: 0;
+            clip_to: "elm.background.progressbar";
+            description {
+               state: "default" 0.0;
+               min: 28 14;
+               fixed: 1 1;
+               rel1 {
+                  to: "elm.swallow.bar";
+                  relative: 0.0 0.0;
+               }
+               rel2 {
+                  to_x: "elm.swallow.bar";
+                  to_y: "elm.cur.progressbar";
+                  offset: -1 -1;
+               }
+               image {
+                  normal: "bt_sm_base2.png";
+                  border: 6 6 6 6;
+               }
+            }
+            description {
+               state: "invert" 0.0;
+               inherit: "default" 0.0;
+               rel1 {
+                  to_x: "elm.swallow.bar";
+                  to_y: "elm.cur.progressbar";
+               }
+               rel2 {
+                  to: "elm.swallow.bar";
+                  relative: 1.0 1.0;
+               }
+            }
+            description {
+               state: "state_begin" 0.0;
+               inherit: "default" 0.0;
+               rel1 {
+                  to: "elm.swallow.bar";
+                  relative: 0.0 0.0;
+               }
+               rel2 {
+                  to: "elm.swallow.bar";
+                  relative: 1.0 0.1;
+               }
+            }
+            description {
+               state: "state_end" 0.0;
+               inherit: "default" 0.0;
+               rel1 {
+                  to: "elm.swallow.bar";
+                  relative: 0.0 0.9;
+               }
+               rel2 {
+                  to: "elm.swallow.bar";
+                  relative: 1.0 1.0;
+               }
+            }
+         }
+
+         part { name: "over1";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               rel1.to: "elm.progress.progressbar";
+               rel2.to: "elm.progress.progressbar";
+               rel2.relative: 1.0 0.5;
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+         }
+
+         part { name: "over2";
+            mouse_events: 1;
+            repeat_events: 1;
+            description { state: "default" 0.0;
+               rel1.to: "elm.progress.progressbar";
+               rel2.to: "elm.progress.progressbar";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+         }
+
+         part { name: "elm.cur.progressbar";
+            mouse_events: 0;
+            dragable {
+               confine: "background";
+               x: 0 0 0;
+               y: 1 1 1;
+            }
+            description { state: "default" 0.0;
+               min: 28 14;
+               fixed: 1 1;
+               visible: 0;
+               rel1 {
+                  to: "background";
+                  relative: 0 0;
+               }
+               rel2.to: "background";
+           }
+         }
+
+         part { name: "elm.text.box";
+            mouse_events: 0;
+            type: RECT;
+            description { state: "default" 0.0;
+               visible: 0;
+               rel1 {
+                  to: "elm.text.status";
+                  offset: -2 -2;
+               }
+               rel2 {
+                  to: "elm.text.status";
+                  offset: 2 2;
+               }
+               color: 255 255 255 0;
+            }
+            description { state: "visible" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+            }
+         }
+         part { name: "elm.text.status";
+            type: TEXT;
+            mouse_events: 0;
+            scale: 1;
+            description { state: "default" 0.0;
+               visible: 0;
+               fixed: 1 1;
+               align: 0.5 1.0;
+               rel1.relative: 0.0 1.0;
+               rel1.offset: 2 0;
+               rel2.relative: 1.0 1.0;
+               rel2.offset: -2 0;
+               color: 0 0 0 255;
+               text {
+                  font: "Sans:style=Bold,Edje-Vera-Bold";
+                  size: 10;
+                  min: 0 0;
+                  align: 0.5 0.0;
+               }
+            }
+            description { state: "visible" 0.0;
+               inherit: "default" 0.0;
+               fixed: 1 1;
+               visible: 1;
+               text.min: 1 1;
+               rel1.offset: 8 -9;
+               rel2.offset: -9 -9;
+            }
+         }
+      }
+      programs {
+         program { name: "label_show";
+            signal: "elm,state,text,visible";
+            source: "elm";
+            action:  STATE_SET "visible" 0.0;
+            target: "elm.text";
+         }
+         program { name: "label_hide";
+            signal: "elm,state,text,hidden";
+            source: "elm";
+            action:  STATE_SET "default" 0.0;
+            target: "elm.text";
+         }
+         program { name: "icon_show";
+            signal: "elm,state,icon,visible";
+            source: "elm";
+            action:  STATE_SET "visible" 0.0;
+            target: "elm.swallow.content";
+         }
+         program { name: "icon_hide";
+            signal: "elm,state,icon,hidden";
+            source: "elm";
+            action:  STATE_SET "default" 0.0;
+            target: "elm.swallow.content";
+         }
+         program { name: "units_show";
+            signal: "elm,state,units,visible";
+            source: "elm";
+            action:  STATE_SET "visible" 0.0;
+            target: "elm.text.status";
+            target: "elm.text.box";
+         }
+         program { name: "units_hide";
+            signal: "elm,state,units,hidden";
+            source: "elm";
+            action:  STATE_SET "default" 0.0;
+            target: "elm.text.status";
+            target: "elm.text.box";
+         }
+         program { name: "slide_to_end";
+            action:  STATE_SET "state_end" 0.0;
+            transition: LINEAR 0.5;
+            target: "elm.progress.progressbar";
+            after: "slide_to_begin";
+         }
+         program { name: "slide_to_begin";
+            action:  STATE_SET "state_begin" 0.0;
+            target: "elm.progress.progressbar";
+            transition: LINEAR 0.5;
+            after: "slide_to_end";
+         }
+         program { name: "start_pulse";
+            signal: "elm,state,pulse,start";
+            source: "elm";
+            action: STATE_SET "state_begin" 0.0;
+            target: "elm.progress.progressbar";
+            after: "slide_to_end";
+         }
+         program { name: "stop_pulse";
+            signal: "elm,state,pulse,stop";
+            source: "elm";
+            action: ACTION_STOP;
+            target: "slide_to_begin";
+            target: "slide_to_end";
+            target: "start_pulse";
+            after: "state_pulse";
+         }
+         program { name: "state_pulse";
+            signal: "elm,state,pulse";
+            source: "elm";
+            action: STATE_SET "state_begin" 0.0;
+            target: "elm.progress.progressbar";
+            after: "units_hide";
+         }
+         program { name: "state_fraction";
+            signal: "elm,state,fraction";
+            source: "elm";
+            action: ACTION_STOP;
+            target: "slide_to_begin";
+            target: "slide_to_end";
+            target: "start_pulse";
+            action: STATE_SET "default" 0.0;
+            target: "elm.progress.progressbar";
+         }
+         program { name: "set_invert_on";
+            signal: "elm,state,inverted,on";
+            source: "elm";
+            action:  STATE_SET "invert" 0.0;
+            target: "elm.progress.progressbar";
+            target: "elm.cur.progressbar";
+         }
+         program { name: "set_invert_off";
+            signal: "elm,state,inverted,off";
+            source: "elm";
+            action:  STATE_SET "default" 0.0;
+            target: "elm.progress.progressbar";
+            target: "elm.cur.progressbar";
+         }
+      }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/separator/horizontal/default";
+       images {
+           image: "separator_h.png" COMP;
+       }
+       parts {
+           part { name: "separator"; // separator group
+               description { state: "default" 0.0;
+                   min: 2 2;
+                   rel1.offset: 4 4;
+                   rel2.offset: -5 -5;
+                   image {
+                       normal: "separator_h.png";
+                   }
+                   fill {
+                       smooth: 0;
+                   }
+               }
+           }
+       }
+   }
+
+   ///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/separator/vertical/default";
+       images {
+           image: "separator_v.png" COMP;
+       }
+       parts {
+           part { name: "separator"; // separator group
+               description { state: "default" 0.0;
+                   min: 2 2;
+                   rel1.offset: 4 4;
+                   rel2.offset: -5 -5;
+                   image {
+                       normal: "separator_v.png";
+                   }
+                   fill {
+                       smooth: 0;
+                   }
+               }
+           }
+       }
+   }
+
+   group { name: "elm/progressbar/horizontal/wheel";
+       images {
+           image: "busy-1.png" COMP;
+           image: "busy-2.png" COMP;
+           image: "busy-3.png" COMP;
+           image: "busy-4.png" COMP;
+           image: "busy-5.png" COMP;
+           image: "busy-6.png" COMP;
+           image: "busy-7.png" COMP;
+           image: "busy-8.png" COMP;
+           image: "busy-9.png" COMP;
+       }
+       parts {
+           part { name: "elm.background.progressbar";
+               mouse_events: 0;
+               type: RECT;
+               description {
+                   state: "default" 0.0;
+               }
+           }
+           part { name: "elm.swallow.bar";
+               mouse_events: 0;
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   min: 0 0;
+                   max: 0 0;
+                   visible: 0;
+               }
+           }
+           part { name: "elm.swallow.content";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   min: 0 0;
+                   max: 0 0;
+                   visible: 0;
+               }
+           }
+           part { name: "background";
+               mouse_events: 0;
+               clip_to: "elm.background.progressbar";
+               description {
+                   state: "default" 0.0;
+                   min: 32 32;
+                   max: 32 32;
+                   visible: 1;
+                   aspect: 1.0 1.0;
+                   aspect_preference: BOTH;
+                   image {
+                       normal: "busy-9.png";
+                       border: 7 7 7 7;
+                   }
+               }
+               description {
+                   state: "pulse" 0.0;
+                   inherit: "default" 0.0;
+                   image {
+                       normal: "busy-9.png";
+                       tween:  "busy-1.png";
+                       tween:  "busy-2.png";
+                       tween:  "busy-3.png";
+                       tween:  "busy-4.png";
+                       tween:  "busy-5.png";
+                       tween:  "busy-6.png";
+                       tween:  "busy-7.png";
+                       tween:  "busy-8.png";
+                       border: 7 7 7 7;
+                   }
+               }
+           }
+       }
+       programs {
+           program { name: "start_pulse";
+               signal: "elm,state,pulse,start";
+               source: "elm";
+               action: STATE_SET "pulse" 0.0;
+               target: "background";
+               transition: LINEAR 0.5;
+               after: "start_pulse";
+           }
+           program { name: "stop_pulse";
+               signal: "elm,state,pulse,stop";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "background";
+           }
+       }
+   }
+
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/spinner/base/default";
+       images {
+           image: "shelf_inset.png" COMP;
+           image: "bt_base1.png" COMP;
+           image: "bt_hilight.png" COMP;
+           image: "bt_shine.png" COMP;
+           image: "bt_glow.png" COMP;
+           image: "bt_dis_base.png" COMP;
+           image: "bt_dis_hilight.png" COMP;
+           image: "sp_bt_l.png" COMP;
+           image: "sp_bt_r.png" COMP;
+       }
+       parts {
+           part { name: "bg";
+               type: RECT;
+               description { state: "default" 0.0;
+                   max: 99999 30;
+                   min: 0 30;
+                   rel1.offset: 1 1;
+                   rel2.offset: -2 -2;
+                   color: 255 255 255 0;
+               }
+           }
+           part { name: "conf_over";
+               mouse_events:  0;
+               description { state: "default" 0.0;
+                   rel1.to: "bg";
+                   rel2.to: "bg";
+                   image {
+                       normal: "shelf_inset.png";
+                       border: 7 7 7 7;
+                       middle: 0;
+                   }
+                   fill.smooth : 0;
+               }
+           }
+           part { name: "left_bt";
+               mouse_events:  1;
+               description { state: "default" 0.0;
+                   rel1 { to: "bg";
+                       offset: 2 2;
+                   }
+                   rel2 { to: "bg";
+                       offset: -3 -3;
+                   }
+                   align: 0.0 0.5;
+                   min: 24 24;
+                   max: 24 24;
+                   image {
+                       normal: "bt_base1.png";
+                       border: 6 6 6 6;
+                   }
+                   fill.smooth : 0;
+               }
+               description { state: "clicked" 0.0;
+                   inherit: "default" 0.0;
+                   image.normal: "bt_base1.png";
+                   image.middle: SOLID;
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+                   image {
+                       normal: "bt_dis_base.png";
+                       border: 4 4 4 4;
+                   }
+               }
+           }
+           part {        name: "left_over1";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "left_bt";
+                   rel2 { to: "left_bt";
+                       relative: 1.0 0.5;
+                   }
+                   image {
+                       normal: "bt_hilight.png";
+                       border: 7 7 7 0;
+                   }
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+                   image {
+                       normal: "bt_dis_hilight.png";
+                       border: 4 4 4 0;
+                   }
+               }
+           }
+           part { name: "left_over2";
+               mouse_events: 1;
+               repeat_events: 1;
+               ignore_flags: ON_HOLD;
+               description { state: "default" 0.0;
+                   rel1.to: "left_bt";
+                   rel2.to: "left_bt";
+                   image {
+                       normal: "bt_shine.png";
+                       border: 7 7 7 7;
+                   }
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+                   visible: 0;
+               }
+           }
+           part { name: "left_over3";
+               mouse_events: 1;
+               repeat_events: 1;
+               description { state: "default" 0.0;
+                   color: 255 255 255 0;
+                   rel1.to: "left_bt";
+                   rel2.to: "left_bt";
+                   image {
+                       normal: "bt_glow.png";
+                       border: 12 12 12 12;
+                   }
+                   fill.smooth : 0;
+               }
+               description { state: "clicked" 0.0;
+                   inherit:  "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "right_bt";
+               mouse_events:  1;
+               description { state: "default" 0.0;
+                   rel1 { to: "bg";
+                       offset: -27 3;
+                   }
+                   rel2 { to: "bg";
+                       offset: -3 -3;
+                   }
+                   align: 1.0 0.5;
+                   min: 24 24;
+                   max: 24 24;
+                   image {
+                       normal: "bt_base1.png";
+                       border: 5 5 4 12;
+                   }
+                   fill.smooth : 0;
+               }
+               description { state: "clicked" 0.0;
+                   inherit: "default" 0.0;
+                   image.normal: "bt_base1.png";
+                   image.middle: SOLID;
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+                   image {
+                       normal: "bt_dis_base.png";
+                       border: 4 4 4 4;
+                   }
+               }
+           }
+           part { name: "right_over1";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "right_bt";
+                   rel2 { to: "right_bt";
+                       relative: 1.0 0.5;
+                   }
+                   image {
+                       normal: "bt_hilight.png";
+                       border: 7 7 7 0;
+                   }
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+                   image {
+                       normal: "bt_dis_hilight.png";
+                       border: 4 4 4 0;
+                   }
+               }
+           }
+           part { name: "right_over2";
+               mouse_events: 1;
+               repeat_events: 1;
+               ignore_flags: ON_HOLD;
+               description { state: "default" 0.0;
+                   rel1.to: "right_bt";
+                   rel2.to: "right_bt";
+                   image {
+                       normal: "bt_shine.png";
+                       border: 7 7 7 7;
+                   }
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+                   visible: 0;
+               }
+           }
+           part { name: "right_over3";
+               mouse_events: 1;
+               repeat_events: 1;
+               description { state: "default" 0.0;
+                   color: 255 255 255 0;
+                   rel1.to: "right_bt";
+                   rel2.to: "right_bt";
+                   image {
+                       normal: "bt_glow.png";
+                       border: 12 12 12 12;
+                   }
+                   fill.smooth : 0;
+               }
+               description { state: "clicked" 0.0;
+                   inherit:  "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "left_bt_icon";
+               repeat_events: 1;
+               description { state: "default" 0.0;
+                   rel1.to: "left_bt";
+                   rel2.to: "left_bt";
+                   align: 0.5 0.5;
+                   min: 16 16;
+                   max: 16 16;
+                   image.normal: "sp_bt_l.png";
+               }
+           }
+           part { name: "right_bt_icon";
+               repeat_events: 1;
+               description { state: "default" 0.0;
+                   rel1.to: "right_bt";
+                   rel2.to: "right_bt";
+                   align: 0.5 0.5;
+                   min: 16 16;
+                   max: 16 16;
+                   image.normal: "sp_bt_r.png";
+               }
+           }
+           part { name: "elm.text";
+               type: TEXT;
+               mouse_events: 0;
+               scale: 1;
+               description { state: "default" 0.0;
+                   visible: 1;
+                   align: 0.0 0.5;
+                   rel1 { relative: 1.0 0.0;
+                       offset: 3 2;
+                       to_x: "left_bt";
+                       to_y: "bg";
+                   }
+                   rel2 { relative: 0.0 1.0;
+                       offset: -3 -2;
+                       to_x: "right_bt";
+                       to_y: "bg";
+                   }
+                   color: 0 0 0 255;
+                   text {
+                       font: "Sans,Edje-Vera";
+                       size: 10;
+                       min: 1 1;
+                       align: 0.5 0.5;
+                   }
+               }
+               description { state: "active" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 0;
+               }
+               description { state: "disabled_active" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 128;
+                   color3: 0 0 0 0;
+               }
+               description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 128;
+                   color3: 0 0 0 0;
+               }
+           }
+           part { name: "elm.dragable.slider";
+               type: RECT;
+               mouse_events: 0;
+               scale: 1;
+               dragable {
+                   x: 1 1 0;
+                   y: 0 0 0;
+               }
+               description { state: "default" 0.0;
+                   rel1.to: "bg";
+                   rel2.to: "bg";
+                   fixed: 1 1;
+                   color: 0 0 0 0;
+               }
+           }
+           part { name: "button_events";
+               type: RECT;
+               dragable {
+                   events: "elm.dragable.slider";
+               }
+               mouse_events: 1;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.text";
+                   rel2.to: "elm.text";
+                   color: 0 0 0 0;
+               }
+           }
+           part { name: "elm.swallow.entry";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   align: 0.5 0.5;
+                   rel1 { relative: 1.0 0.5;
+                       offset: 3 2;
+                       to_x: "left_bt";
+                       to_y: "bg";
+                   }
+                   rel2 { relative: 0.0 0.5;
+                       offset: -3 -2;
+                       to_x: "right_bt";
+                       to_y: "bg";
+                   }
+                   fixed: 1 1;
+                   color: 0 0 0 0;
+               }
+               description { state: "active" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+               description { state: "disabled_active" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 0;
+               }
+               description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 0;
+               }
+           }
+           part { name: "disabler";
+               type: RECT;
+               description { state: "default" 0.0;
+                   color: 0 0 0 0;
+                   visible: 0;
+               }
+               description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+               }
+           }
+       }
+       programs {
+           program { name: "text_show";
+               signal: "elm,state,text,visible";
+               source: "elm";
+               action:  STATE_SET "visible" 0.0;
+               target: "elm.text";
+           }
+           program { name: "text_hide";
+               signal: "elm,state,text,hidden";
+               source: "elm";
+               action:  STATE_SET "default" 0.0;
+               target: "elm.text";
+           }
+           program { name: "dec";
+               signal: "mouse,down,1";
+               source: "left_bt";
+               action: SIGNAL_EMIT "elm,action,decrement,start" "";
+           }
+           program { name: "dec2";
+               signal: "mouse,up,1";
+               source: "left_bt";
+               action: SIGNAL_EMIT "elm,action,decrement,stop" "";
+           }
+           program { name: "inc";
+               signal: "mouse,down,1";
+               source: "right_bt";
+               action: SIGNAL_EMIT "elm,action,increment,start" "";
+           }
+           program { name: "inc2";
+               signal: "mouse,up,1";
+               source: "right_bt";
+               action: SIGNAL_EMIT "elm,action,increment,stop" "";
+           }
+           program {
+               name:   "left_bt_click";
+               signal: "mouse,down,1";
+               source: "left_over2";
+               action: STATE_SET "clicked" 0.0;
+               target: "left_bt";
+           }
+           program {
+               name:   "left_bt_unclick";
+               signal: "mouse,up,1";
+               source: "left_over2";
+               action: STATE_SET "default" 0.0;
+               target: "left_bt";
+           }
+           program {
+               name:   "left_bt_click2";
+               signal: "mouse,down,1";
+               source: "left_over3";
+               action: STATE_SET "clicked" 0.0;
+               target: "left_over3";
+           }
+           program {
+               name:   "left_bt_unclick2";
+               signal: "mouse,up,1";
+               source: "left_over3";
+               action: STATE_SET "default" 0.0;
+               transition: DECELERATE 0.5;
+               target: "left_over3";
+           }
+           program {
+               name:   "left_bt_unclick3";
+               signal: "mouse,up,1";
+               source: "left_over2";
+               action: SIGNAL_EMIT "elm,action,click" "";
+           }
+
+           program {
+               name:   "right_bt_click";
+               signal: "mouse,down,1";
+               source: "right_over2";
+               action: STATE_SET "clicked" 0.0;
+               target: "right_bt";
+           }
+           program {
+               name:   "right_bt_unclick";
+               signal: "mouse,up,1";
+               source: "right_over2";
+               action: STATE_SET "default" 0.0;
+               target: "right_bt";
+           }
+           program {
+               name:   "right_bt_click2";
+               signal: "mouse,down,1";
+               source: "right_over3";
+               action: STATE_SET "clicked" 0.0;
+               target: "right_over3";
+           }
+           program {
+               name:   "right_bt_unclick2";
+               signal: "mouse,up,1";
+               source: "right_over3";
+               action: STATE_SET "default" 0.0;
+               transition: DECELERATE 0.5;
+               target: "right_over3";
+           }
+           program {
+               name:   "right_bt_unclick3";
+               signal: "mouse,up,1";
+               source: "right_over2";
+               action: SIGNAL_EMIT "elm,action,click" "";
+           }
+           program { name: "disable";
+               signal: "elm,state,disabled";
+               source: "elm";
+               action: STATE_SET "disabled" 0.0;
+               target: "left_bt";
+               target: "left_over1";
+               target: "left_over2";
+               target: "right_bt";
+               target: "right_over1";
+               target: "right_over2";
+               target: "disabler";
+               after: "disable_text";
+           }
+           program { name: "disable_text";
+               script {
+                   new st[31];
+                   new Float:vl;
+                   get_state(PART:"elm.text", st, 30, vl);
+                   if (!strcmp(st, "active"))
+                   set_state(PART:"elm.text", "disabled_active", 0.0);
+                   else
+                   set_state(PART:"elm.text", "disabled", 0.0);
+
+                   get_state(PART:"elm.swallow.entry", st, 30, vl);
+                   if (!strcmp(st, "active"))
+                   set_state(PART:"elm.swallow.entry", "disabled_active", 0.0);
+                   else
+                   set_state(PART:"elm.swallow.entry", "disabled", 0.0);
+               }
+           }
+           program { name: "enable";
+               signal: "elm,state,enabled";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "left_bt";
+               target: "left_over1";
+               target: "left_over2";
+               target: "right_bt";
+               target: "right_over1";
+               target: "right_over2";
+               target: "disabler";
+               after: "enable_text";
+           }
+           program { name: "enable_text";
+               script {
+                   new st[31];
+                   new Float:vl;
+                   get_state(PART:"elm.text", st, 30, vl);
+                   if (!strcmp(st, "disabled_active"))
+                   set_state(PART:"elm.text", "active", 0.0);
+                   else
+                   set_state(PART:"elm.text", "default", 0.0);
+
+                   get_state(PART:"elm.swallow.entry", st, 30, vl);
+                   if (!strcmp(st, "disabled_active"))
+                   set_state(PART:"elm.swallow.entry", "active", 0.0);
+                   else
+                   set_state(PART:"elm.swallow.entry", "default", 0.0);
+               }
+           }
+           program { name: "active";
+               signal: "elm,state,active";
+               source: "elm";
+               action: STATE_SET "active" 0.0;
+               target: "elm.text";
+               target: "elm.swallow.entry";
+           }
+           program { name: "inactive";
+               signal: "elm,state,inactive";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "elm.text";
+               target: "elm.swallow.entry";
+           }
+           program { name: "toggle_text";
+               signal: "mouse,up,1";
+               source: "button_events";
+               action: SIGNAL_EMIT "elm,action,entry,toggle" "";
+           }
+       }
+   }
+
+///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/spinner/base/vertical";
+       images {
+           image: "shelf_inset.png" COMP;
+           image: "bt_hilight.png" COMP;
+           image: "bt_shine.png" COMP;
+           image: "bt_glow.png" COMP;
+           image: "bt_dis_base.png" COMP;
+           image: "bt_dis_hilight.png" COMP;
+           image: "up.png" COMP;
+           image: "down.png" COMP;
+           image: "bt_spinner_up.png" COMP;
+           image: "bt_spinner_down.png" COMP;
+           image: "bt_spinner_hilight.png" COMP;
+       }
+       parts {
+           part { name: "bg";
+               type: RECT;
+               description { state: "default" 0.0;
+                   max: 99999 30;
+                   min: 0 30;
+                   rel1.offset: 1 1;
+                   rel2.offset: -2 -2;
+                   color: 255 255 255 0;
+               }
+           }
+           part { name: "conf_over";
+               mouse_events:  0;
+               description { state: "default" 0.0;
+                   rel1 {
+                     to: "bg";
+                     relative: 0.0 0.0;
+                   }
+                   rel2 {
+                      to_x: "down_bt";
+                      offset: -22 -1;
+                   }
+                   rel2 {
+                      to_y: "bg";
+                   }
+                   image {
+                       normal: "shelf_inset.png";
+                       border: 7 7 7 7;
+                       middle: 0;
+                   }
+                   fill.smooth : 0;
+               }
+           }
+           part { name: "down_bt";
+               mouse_events:  1;
+               description { state: "default" 0.0;
+                   rel1 {
+                       to_x: "bg";
+                       to_y: "up_bt";
+                       relative: 1 1;
+                       offset: 0 1;
+                   }
+                   rel2 { to: "bg";
+                       relative: 1 1;
+                       offset: -1 -1;
+                   }
+                   align: 1.0 0.5;
+                   min: 24 16;
+                   max: 24 16;
+                   image {
+                       normal: "bt_spinner_down.png";
+                       border: 6 6 6 6;
+                   }
+                   fill.smooth : 0;
+               }
+               description { state: "clicked" 0.0;
+                   inherit: "default" 0.0;
+                   image.normal: "bt_spinner_down.png";
+                   image.middle: SOLID;
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+                   image {
+                       normal: "bt_dis_base.png";
+                       border: 4 4 4 4;
+                   }
+               }
+           }
+           part { name: "down_over3";
+               mouse_events: 1;
+               repeat_events: 1;
+               description { state: "default" 0.0;
+                   color: 255 255 255 0;
+                   rel1.to: "down_bt";
+                   rel2.to: "down_bt";
+                   image {
+                       normal: "bt_glow.png";
+                       border: 12 12 12 12;
+                   }
+                   fill.smooth : 0;
+               }
+               description { state: "clicked" 0.0;
+                   inherit:  "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "up_bt";
+               mouse_events:  1;
+               description { state: "default" 0.0;
+                   rel1 { to: "bg";
+                       relative: 0 0;
+                       offset: 0 0;
+                   }
+                   rel2 { to: "bg";
+                       relative: 1 0.5;
+                       offset: -1 -1;
+                   }
+                   align: 1.0 0.5;
+                   min: 24 16;
+                   max: 24 16;
+                   image {
+                       normal: "bt_spinner_up.png";
+                       border: 6 6 6 6;
+                   }
+                   fill.smooth : 0;
+               }
+               description { state: "clicked" 0.0;
+                   inherit: "default" 0.0;
+                   image.normal: "bt_spinner_up.png";
+                   image.middle: SOLID;
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+                   image {
+                       normal: "bt_dis_base.png";
+                       border: 4 4 4 4;
+                   }
+               }
+           }
+           part { name: "up_over1";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "up_bt";
+                   rel2 { to: "up_bt";
+                       relative: 1.0 0.5;
+                   }
+                   image {
+                       normal: "bt_spinner_hilight.png";
+                       border: 7 7 7 0;
+                   }
+               }
+               description { state: "disabled" 0.0;
+                   inherit:  "default" 0.0;
+                   image {
+                       normal: "bt_dis_hilight.png";
+                       border: 4 4 4 0;
+                   }
+               }
+           }
+           part { name: "up_over3";
+               mouse_events: 1;
+               repeat_events: 1;
+               description { state: "default" 0.0;
+                   color: 255 255 255 0;
+                   rel1.to: "up_bt";
+                   rel2.to: "up_bt";
+                   image {
+                       normal: "bt_glow.png";
+                       border: 12 12 12 12;
+                   }
+                   fill.smooth : 0;
+               }
+               description { state: "clicked" 0.0;
+                   inherit:  "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "down_bt_icon";
+               repeat_events: 1;
+               description { state: "default" 0.0;
+                   rel1.to: "down_bt";
+                   rel2.to: "down_bt";
+                   align: 0.5 0.5;
+                   min: 14 12;
+                   max: 14 12;
+                   image.normal: "down.png";
+               }
+           }
+           part { name: "up_bt_icon";
+               repeat_events: 1;
+               description { state: "default" 0.0;
+                   rel1.to: "up_bt";
+                   rel2.to: "up_bt";
+                   align: 0.5 0.5;
+                   min: 14 12;
+                   max: 14 12;
+                   image.normal: "up.png";
+               }
+           }
+           part { name: "elm.text";
+               type: TEXT;
+               mouse_events: 0;
+               scale: 1;
+               description { state: "default" 0.0;
+                   visible: 1;
+                   align: 0.0 0.5;
+                   rel1 { relative: 0.0 0.0;
+                       offset: 3 2;
+                       to_x: "bg";
+                       to_y: "bg";
+                   }
+                   rel2 { relative: 0.0 1.0;
+                       offset: -3 -2;
+                       to_x: "bg";
+                       to_y: "bg";
+                   }
+                   color: 0 0 0 255;
+                   text {
+                       font: "Sans,Edje-Vera";
+                       size: 10;
+                       min: 1 1;
+                       align: 0.5 0.5;
+                   }
+               }
+               description { state: "active" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 0;
+               }
+               description { state: "disabled_active" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 128;
+                   color3: 0 0 0 0;
+               }
+               description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 128;
+                   color3: 0 0 0 0;
+               }
+           }
+           part { name: "elm.dragable.slider";
+               type: RECT;
+               mouse_events: 0;
+               scale: 1;
+               dragable {
+                   x: 1 1 0;
+                   y: 0 0 0;
+               }
+               description { state: "default" 0.0;
+                   rel1.to: "bg";
+                   rel2.to: "bg";
+                   fixed: 1 1;
+                   color: 0 0 0 0;
+               }
+           }
+           part { name: "button_events";
+               type: RECT;
+               dragable {
+                   events: "elm.dragable.slider";
+               }
+               mouse_events: 1;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.text";
+                   rel2.to: "elm.text";
+                   color: 0 0 0 0;
+               }
+           }
+           part { name: "elm.swallow.entry";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   align: 0.5 0.5;
+                   rel1 { relative: 0.0 0.5;
+                       offset: 3 2;
+                       to: "bg";
+                   }
+                   rel2 { relative: 1.0 0.5;
+                       offset: -3 -2;
+                       to: "bg";
+                   }
+                   fixed: 1 1;
+                   color: 0 0 0 0;
+               }
+               description { state: "active" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+               description { state: "disabled_active" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 0;
+               }
+               description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 0;
+               }
+           }
+           part { name: "disabler";
+               type: RECT;
+               description { state: "default" 0.0;
+                   color: 0 0 0 0;
+                   visible: 0;
+               }
+               description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+               }
+           }
+       }
+       programs {
+           program { name: "text_show";
+               signal: "elm,state,text,visible";
+               source: "elm";
+               action:  STATE_SET "visible" 0.0;
+               target: "elm.text";
+           }
+           program { name: "text_hide";
+               signal: "elm,state,text,hidden";
+               source: "elm";
+               action:  STATE_SET "default" 0.0;
+               target: "elm.text";
+           }
+           program { name: "dec";
+               signal: "mouse,down,1";
+               source: "down_bt";
+               action: SIGNAL_EMIT "elm,action,decrement,start" "";
+           }
+           program { name: "dec2";
+               signal: "mouse,up,1";
+               source: "down_bt";
+               action: SIGNAL_EMIT "elm,action,decrement,stop" "";
+           }
+           program { name: "inc";
+               signal: "mouse,down,1";
+               source: "up_bt";
+               action: SIGNAL_EMIT "elm,action,increment,start" "";
+           }
+           program { name: "inc2";
+               signal: "mouse,up,1";
+               source: "up_bt";
+               action: SIGNAL_EMIT "elm,action,increment,stop" "";
+           }
+           program {
+               name:   "down_bt_click2";
+               signal: "mouse,down,1";
+               source: "down_over3";
+               action: STATE_SET "clicked" 0.0;
+               target: "down_over3";
+           }
+           program {
+               name:   "down_bt_unclick2";
+               signal: "mouse,up,1";
+               source: "down_over3";
+               action: STATE_SET "default" 0.0;
+               transition: DECELERATE 0.5;
+               target: "down_over3";
+           }
+           program {
+               name:   "up_bt_click2";
+               signal: "mouse,down,1";
+               source: "up_over3";
+               action: STATE_SET "clicked" 0.0;
+               target: "up_over3";
+           }
+           program {
+               name:   "up_bt_unclick2";
+               signal: "mouse,up,1";
+               source: "up_over3";
+               action: STATE_SET "default" 0.0;
+               transition: DECELERATE 0.5;
+               target: "up_over3";
+           }
+           program { name: "disable";
+               signal: "elm,state,disabled";
+               source: "elm";
+               action: STATE_SET "disabled" 0.0;
+               target: "down_bt";
+               target: "up_bt";
+               target: "disabler";
+               after: "disable_text";
+           }
+           program { name: "disable_text";
+               script {
+                   new st[31];
+                   new Float:vl;
+                   get_state(PART:"elm.text", st, 30, vl);
+                   if (!strcmp(st, "active"))
+                   set_state(PART:"elm.text", "disabled_active", 0.0);
+                   else
+                   set_state(PART:"elm.text", "disabled", 0.0);
+
+                   get_state(PART:"elm.swallow.entry", st, 30, vl);
+                   if (!strcmp(st, "active"))
+                   set_state(PART:"elm.swallow.entry", "disabled_active", 0.0);
+                   else
+                   set_state(PART:"elm.swallow.entry", "disabled", 0.0);
+               }
+           }
+           program { name: "enable";
+               signal: "elm,state,enabled";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "down_bt";
+               target: "up_bt";
+               target: "disabler";
+               after: "enable_text";
+           }
+           program { name: "enable_text";
+               script {
+                   new st[31];
+                   new Float:vl;
+                   get_state(PART:"elm.text", st, 30, vl);
+                   if (!strcmp(st, "disabled_active"))
+                   set_state(PART:"elm.text", "active", 0.0);
+                   else
+                   set_state(PART:"elm.text", "default", 0.0);
+
+                   get_state(PART:"elm.swallow.entry", st, 30, vl);
+                   if (!strcmp(st, "disabled_active"))
+                   set_state(PART:"elm.swallow.entry", "active", 0.0);
+                   else
+                   set_state(PART:"elm.swallow.entry", "default", 0.0);
+               }
+           }
+           program { name: "active";
+               signal: "elm,state,active";
+               source: "elm";
+               action: STATE_SET "active" 0.0;
+               target: "elm.text";
+               target: "elm.swallow.entry";
+           }
+           program { name: "inactive";
+               signal: "elm,state,inactive";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "elm.text";
+               target: "elm.swallow.entry";
+           }
+           program { name: "toggle_text";
+               signal: "mouse,up,1";
+               source: "button_events";
+               action: SIGNAL_EMIT "elm,action,entry,toggle" "";
+           }
+       }
+   }
+
+
+   ///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/index/base/vertical/default";
+       images {
+           image: "bt_base1.png" COMP;
+           image: "bt_base2.png" COMP;
+           image: "bt_hilight.png" COMP;
+           image: "bt_shine.png" COMP;
+       }
+       parts {
+           part { name: "clip";
+               type: RECT;
+               mouse_events:  0;
+               description { state: "default" 0.0;
+                   visible:  0;
+                   color: 255 255 255 0;
+               }
+               description { state: "active" 0.0;
+                   visible:  1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "clip2";
+               type: RECT;
+               mouse_events:  0;
+               clip_to: "clip";
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+               }
+               description { state: "active" 0.0;
+                   visible:  1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "elm.swallow.index.0";
+               type: SWALLOW;
+               clip_to: "clip";
+               description { state: "default" 0.0;
+                   align: 1.0 0.5;
+                   rel1 {
+                       relative: 1.0 0.5;
+                       offset: -1 5;
+                   }
+                   rel2 {
+                       relative: 1.0 0.5;
+                       offset: -1 -6;
+                   }
+               }
+           }
+           part { name: "button_image";
+               mouse_events: 1;
+               clip_to: "clip";
+               description { state: "default" 0.0;
+                   rel1 {
+                       to: "elm.text.body";
+                       offset: -5 -5;
+                   }
+                   rel2 {
+                       to: "elm.text";
+                       offset: 4 4;
+                   }
+                   image {
+                       normal: "bt_base2.png";
+                       border: 7 7 7 7;
+                   }
+                   image.middle: SOLID;
+               }
+           }
+           part { name: "elm.text.body";
+               type: TEXT;
+               effect: SOFT_SHADOW;
+               mouse_events: 0;
+               scale: 1;
+               clip_to: "clip";
+               description { state: "default" 0.0;
+                   align: 1.0 0.5;
+                   rel1 {
+                       to: "elm.text";
+                       relative: 0.0 0.0;
+                       offset: 5 0;
+                   }
+                   rel2 {
+                       to: "elm.text";
+                       relative: 0.0 1.0;
+                       offset: 5 -1;
+                   }
+                   color: 224 224 224 255;
+                   color3: 0 0 0 64;
+                   text {
+                       font:     "Sans,Edje-Vera";
+                       size:     20;
+                       min:      1 1;
+                       align:    1.0 0.5;
+                   }
+               }
+           }
+           part { name: "elm.text";
+               type: TEXT;
+               effect: SOFT_SHADOW;
+               mouse_events: 0;
+               scale: 1;
+               clip_to: "clip";
+               description { state: "default" 0.0;
+                   align: 1.0 0.5;
+                   rel1 {
+                       to_x: "elm.swallow.event.0";
+                       to_y: "elm.dragable.pointer";
+                       relative: 0.0 0.5;
+                       offset: -16 0;
+                   }
+                   rel2 {
+                       to_x: "elm.swallow.event.0";
+                       to_y: "elm.dragable.pointer";
+                       relative: 0.0 0.5;
+                       offset: -16 -1;
+                   }
+                   color: 255 0 0 255;
+                   color3: 0 0 0 64;
+                   text {
+                       font:     "Sans,Edje-Vera";
+                       size:     20;
+                       min:      1 1;
+                       align:    1.0 0.5;
+                   }
+               }
+           }
+           part {      name: "over1";
+               mouse_events: 0;
+               clip_to: "clip";
+               description { state: "default" 0.0;
+                   rel1 {
+                       to: "button_image";
+                   }
+                   rel2 {
+                       to: "button_image";
+                       relative: 1.0 0.5;
+                   }
+                   image {
+                       normal: "bt_hilight.png";
+                       border: 7 7 7 0;
+                   }
+               }
+           }
+           part { name: "over2";
+               mouse_events: 1;
+               repeat_events: 1;
+               ignore_flags: ON_HOLD;
+               clip_to: "clip";
+               description { state: "default" 0.0;
+                   rel1 {
+                       to: "button_image";
+                   }
+                   rel2 {
+                       to: "button_image";
+                   }
+                   image {
+                       normal: "bt_shine.png";
+                       border: 7 7 7 7;
+                   }
+               }
+           }
+           part { name: "elm.dragable.pointer";
+               type: RECT;
+               mouse_events: 0;
+               dragable {
+                   x: 1 1 0;
+                   y: 1 1 0;
+               }
+               clip_to: "clip";
+               description { state: "default" 0.0;
+                   fixed: 1 1;
+                   min: 8 8;
+                   max: 8 8;
+                   rel1 {
+                       relative: 0.0 0.0;
+                       offset:   0 0;
+                   }
+                   rel2 {
+                       relative: 0.0 0.0;
+                       offset:   0 0;
+                   }
+                   color: 0 0 255 128;
+               }
+           }
+           part { name: "elm.swallow.event.0";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   align: 1.0 0.5;
+                   rel1 {
+                       relative: 1.0 0.0;
+                       offset: -1 0;
+                   }
+                   rel2 {
+                       relative: 1.0 1.0;
+                       offset: -1 -1;
+                   }
+               }
+           }
+       }
+       programs {
+           program { name: "active";
+               signal: "elm,state,active";
+               source: "elm";
+               action: STATE_SET "active" 0.0;
+               transition: DECELERATE 0.5;
+               target: "clip";
+           }
+           program { name: "inactive";
+               signal: "elm,state,inactive";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               transition: DECELERATE 0.5;
+               target: "clip";
+           }
+       }
+   }
+
+   group { name: "elm/index/item/vertical/default";
+       data.item: "stacking" "above";
+       data.item: "selectraise" "on";
+       images {
+           image: "ilist_1.png" COMP;
+           image: "ilist_item_shadow.png" COMP;
+       }
+       parts {
+           part {
+               name: "base_sh";
+               mouse_events: 0;
+               description {
+                   state: "default" 0.0;
+                   align: 0.0 0.0;
+                   min: 0 10;
+                   fixed: 1 1;
+                   rel1 {
+                       to: "base";
+                       relative: 0.0 1.0;
+                       offset: 0 0;
+                   }
+                   rel2 {
+                       to: "base";
+                       relative: 1.0 1.0;
+                       offset: -1 0;
+                   }
+                   image {
+                       normal: "ilist_item_shadow.png";
+                   }
+                   fill.smooth: 0;
+               }
+           }
+           part {
+               name: "base";
+               mouse_events: 0;
+               description {
+                   state: "default" 0.0;
+                   image {
+                       normal: "ilist_1.png";
+                       border: 2 2 2 2;
+                   }
+                   fill.smooth: 0;
+               }
+               description { state: "active" 0.0;
+                   inherit: "default" 0.0;
+                   rel1 {
+                       offset: -16 0;
+                   }
+               }
+           }
+           part { name: "elm.text";
+               type:           TEXT;
+               mouse_events:   0;
+               scale: 1;
+               description {
+                   state: "default" 0.0;
+                          //               min: 16 16;
+                   rel1 {
+                       to: "base";
+                       relative: 0.0  0.0;
+                       offset:   4 4;
+                   }
+                   rel2 {
+                       to: "base";
+                       relative: 1.0  1.0;
+                       offset:   -5 -5;
+                   }
+                   color: 0 0 0 128;
+                   text {
+                       font: "Sans";
+                       size: 10;
+                       min: 1 1;
+                            //                  min: 0 1;
+                       align: 0.0 0.5;
+                   }
+               }
+               description { state: "active" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 255;
+               }
+           }
+       }
+       programs {
+           program { name: "active";
+               signal: "elm,state,active";
+               source: "elm";
+               action: STATE_SET "active" 0.0;
+               transition: DECELERATE 0.5;
+               target: "elm.text";
+               target: "base";
+           }
+           program { name: "inactive";
+               signal: "elm,state,inactive";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               transition: DECELERATE 0.5;
+               target: "elm.text";
+               target: "base";
+           }
+       }
+   }
+
+   group { name: "elm/index/item_odd/vertical/default";
+       data.item: "stacking" "below";
+       images {
+           image: "ilist_2.png" COMP;
+       }
+       parts {
+           part {
+               name: "base";
+               mouse_events: 0;
+               description {
+                   state: "default" 0.0;
+                   image {
+                       normal: "ilist_2.png";
+                       border: 2 2 2 2;
+                   }
+                   fill.smooth: 0;
+               }
+               description { state: "active" 0.0;
+                   inherit: "default" 0.0;
+                   rel1 {
+                       offset: -16 0;
+                   }
+               }
+           }
+           part { name: "elm.text";
+               type:           TEXT;
+               mouse_events:   0;
+               scale: 1;
+               description {
+                   state: "default" 0.0;
+                          //               min: 16 16;
+                   rel1 {
+                       to: "base";
+                       relative: 0.0  0.0;
+                       offset:   4 4;
+                   }
+                   rel2 {
+                       to: "base";
+                       relative: 1.0  1.0;
+                       offset:   -5 -5;
+                   }
+                   color: 0 0 0 128;
+                   text {
+                       font: "Sans";
+                       size: 10;
+                       min: 1 1;
+                            //                  min: 0 1;
+                       align: 0.0 0.5;
+                   }
+               }
+               description { state: "active" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 255;
+               }
+           }
+       }
+       programs {
+           program { name: "active";
+               signal: "elm,state,active";
+               source: "elm";
+               action: STATE_SET "active" 0.0;
+               transition: DECELERATE 0.5;
+               target: "elm.text";
+               target: "base";
+           }
+           program { name: "inactive";
+               signal: "elm,state,inactive";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               transition: DECELERATE 0.5;
+               target: "elm.text";
+               target: "base";
+           }
+       }
+   }
+
+   ///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/grid/cell/default/default";
+      data.item: "labels" "elm.text";
+      data.item: "icons" "elm.swallow.icon elm.swallow.end";
+      images {
+         image: "bt_sm_base1.png" COMP;
+         image: "bt_sm_shine.png" COMP;
+         image: "bt_sm_hilight.png" COMP;
+         image: "ilist_1.png" COMP;
+         image: "ilist_item_shadow.png" COMP;
+      }
+      parts {
+         part {
+            name: "event";
+            type: RECT;
+            repeat_events: 1;
+            description {
+               state: "default" 0.0;
+               color: 0 0 0 0;
+            }
+         }
+         part {
+            name: "base_sh";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               align: 0.0 0.0;
+               min: 0 10;
+               fixed: 1 1;
+               rel1 {
+                  to: "base";
+                  relative: 0.0 1.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  to: "base";
+                  relative: 1.0 1.0;
+                  offset: -1 0;
+               }
+               image {
+                  normal: "ilist_item_shadow.png";
+               }
+               fill.smooth: 0;
+            }
+         }
+         part {
+            name: "base";
+            mouse_events: 0;
+            description {
+               state: "default" 0.0;
+               image {
+                  normal: "ilist_1.png";
+                  border: 2 2 2 2;
+               }
+               fill.smooth: 0;
+            }
+         }
+         part { name: "bg";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -5 -5;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 4 4;
+               }
+               image {
+                  normal: "bt_sm_base1.png";
+                  border: 6 6 6 6;
+               }
+               image.middle: SOLID;
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+               rel1 {
+                  relative: 0.0 0.0;
+                  offset: -2 -2;
+               }
+               rel2 {
+                  relative: 1.0 1.0;
+                  offset: 1 1;
+               }
+            }
+         }
+         part { name: "elm.swallow.pad";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 0.0  1.0;
+                  offset:   0    -10;
+               }
+               rel2 {
+                 to_y: "elm.text";
+                  relative: 0.0  0.0;
+                  offset:   -1   -1;
+               }
+            }
+         }
+         part { name: "elm.swallow.icon";
+            clip_to: "disclip";
+            type: SWALLOW;
+            description { state: "default" 0.0;
+               fixed: 1 0;
+               align: 0.5 0.5;
+               rel1 {
+                  relative: 0.0  0.0;
+                  offset:   -1    4;
+               }
+               rel2 {
+                  to_y: "elm.swallow.pad";
+                  relative: 1.0  0.0;
+                  offset:   -1   -5;
+               }
+            }
+         }
+        part { name: "elm.swallow.end";
+           clip_to: "disclip";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              fixed: 1 0;
+              align: 1.0 0.0;
+              aspect: 1.0 1.0;
+              aspect_preference: HORIZONTAL;
+              rel1 {
+                 relative: 1.0 0.0;
+                 offset: -5 -5;
+              }
+              rel2 {
+                 relative: 1.0 1.0;
+                 offset: 5 5;
+              }
+           }
+        }
+         part { name: "elm.text";
+            clip_to: "disclip";
+            type: TEXT;
+            effect: SOFT_SHADOW;
+            mouse_events: 0;
+            scale: 1;
+            description {
+               state: "default" 0.0;
+               rel1 {
+                  relative: 0.0  1.0;
+                  offset: 0 0;
+               }
+               rel2 {
+                  relative: 1.0  1.0;
+                  offset: -5 -5;
+               }
+               color: 0 0 0 255;
+               color3: 0 0 0 0;
+               text {
+                  font: "Sans";
+                  size: 10;
+                  min: 0 1;
+                  align: 0.5 0.0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               color: 224 224 224 255;
+               color3: 0 0 0 64;
+            }
+         }
+         part { name: "fg1";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.relative: 1.0 0.5;
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_hilight.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "fg2";
+            clip_to: "disclip";
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               visible: 0;
+               color: 255 255 255 0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+               image {
+                  normal: "bt_sm_shine.png";
+                  border: 6 6 6 0;
+               }
+            }
+            description { state: "selected" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               color: 255 255 255 255;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               rel1.to: "bg";
+               rel2.to: "bg";
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 255 255 255 64;
+            }
+         }
+      }
+      programs {
+         // signal: elm,state,%s,active
+         //   a "check" item named %s went active
+         // signal: elm,state,%s,passive
+         //   a "check" item named %s went passive
+         // default is passive
+         program {
+            name:    "go_active";
+            signal:  "elm,state,selected";
+            source:  "elm";
+            action:  STATE_SET "selected" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+         }
+         program {
+            name:    "go_passive";
+            signal:  "elm,state,unselected";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "bg";
+            target:  "fg1";
+            target:  "fg2";
+            target:  "elm.text";
+            transition: LINEAR 0.1;
+         }
+         program {
+            name:    "go_disabled";
+            signal:  "elm,state,disabled";
+            source:  "elm";
+            action:  STATE_SET "disabled" 0.0;
+            target:  "disclip";
+         }
+         program {
+            name:    "go_enabled";
+            signal:  "elm,state,enabled";
+            source:  "elm";
+            action:  STATE_SET "default" 0.0;
+            target:  "disclip";
+         }
+      }
+   }
+   group { name: "elm/grid/cell/default_style/default";
+       styles
+       {
+           style { name: "grid_style";
+               base: "font=Sans font_size=10 align=left valign=0.5 color=#000";
+               tag:  "br" "\n";
+               tag:  "hilight" "+ font=Sans:style=Bold";
+               tag:  "b" "+ font=Sans:style=Bold";
+               tag:  "tab" "\t";
+           }
+           style { name: "grid_selected_style";
+               base: "font=Sans font_size=10 align=left valign=0.5 color=#fff";
+               tag:  "br" "\n";
+               tag:  "hilight" "+ font=Sans:style=Bold";
+               tag:  "b" "+ font=Sans:style=Bold";
+               tag:  "tab" "\t";
+           }
+       }
+       data.item: "labels" "elm.text";
+       data.item: "icons" "elm.swallow.icon elm.swallow.end";
+       images {
+           image: "bt_sm_base1.png" COMP;
+           image: "bt_sm_shine.png" COMP;
+           image: "bt_sm_hilight.png" COMP;
+           image: "ilist_1.png" COMP;
+           image: "ilist_item_shadow.png" COMP;
+       }
+       parts {
+           part {
+               name: "event";
+               type: RECT;
+               repeat_events: 1;
+               description {
+                   state: "default" 0.0;
+                   color: 0 0 0 0;
+               }
+           }
+           part {
+               name: "base_sh";
+               mouse_events: 0;
+               description {
+                   state: "default" 0.0;
+                   align: 0.0 0.0;
+                   min: 0 10;
+                   fixed: 1 1;
+                   rel1 {
+                       to: "base";
+                       relative: 0.0 1.0;
+                       offset: 0 0;
+                   }
+                   rel2 {
+                       to: "base";
+                       relative: 1.0 1.0;
+                       offset: -1 0;
+                   }
+                   image {
+                       normal: "ilist_item_shadow.png";
+                   }
+                   fill.smooth: 0;
+               }
+           }
+           part {
+               name: "base";
+               mouse_events: 0;
+               description {
+                   state: "default" 0.0;
+                   min: 16 28;
+                   image {
+                       normal: "ilist_1.png";
+                       border: 2 2 2 2;
+                   }
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "bg";
+               clip_to: "disclip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+                   rel1 {
+                       relative: 0.0 0.0;
+                       offset: -5 -5;
+                   }
+                   rel2 {
+                       relative: 1.0 1.0;
+                       offset: 4 4;
+                   }
+                   image {
+                       normal: "bt_sm_base1.png";
+                       border: 6 6 6 6;
+                   }
+                   image.middle: SOLID;
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+                   rel1 {
+                       relative: 0.0 0.0;
+                       offset: -2 -2;
+                   }
+                   rel2 {
+                       relative: 1.0 1.0;
+                       offset: 1 1;
+                   }
+               }
+           }
+           part { name: "elm.swallow.pad";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   fixed: 1 0;
+                   align: 0.0 0.5;
+                   rel1 {
+                       relative: 0.0  0.0;
+                       offset:   4    4;
+                   }
+                   rel2 {
+                       relative: 0.0  1.0;
+                       offset:   4   -5;
+                   }
+               }
+           }
+           part { name: "elm.swallow.icon";
+               clip_to: "disclip";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   fixed: 1 0;
+                   align: 0.0 0.5;
+                   rel1 {
+                       to_x: "elm.swallow.pad";
+                       relative: 1.0  0.0;
+                       offset:   -1    4;
+                   }
+                   rel2 {
+                       to_x: "elm.swallow.pad";
+                       relative: 1.0  1.0;
+                       offset:   -1   -5;
+                   }
+               }
+           }
+           part { name: "elm.swallow.end";
+               clip_to: "disclip";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   fixed: 1 0;
+                   align: 1.0 0.5;
+                   aspect: 1.0 1.0;
+                   aspect_preference: VERTICAL;
+                   rel1 {
+                       relative: 1.0  0.0;
+                       offset:   -5    4;
+                   }
+                   rel2 {
+                       relative: 1.0  1.0;
+                       offset:   -5   -5;
+                   }
+               }
+           }
+           part { name: "elm.text";
+               clip_to: "disclip";
+               type: TEXTBLOCK;
+               mouse_events: 0;
+               scale: 1;
+               description {
+                   state: "default" 0.0;
+                   align: 0.0 0.5;
+                   fixed: 0 1;
+                   rel1 {
+                       to_x: "elm.swallow.icon";
+                       to_y: "base";
+                       relative: 1.0  0.5;
+                       offset:   0 4;
+                   }
+                   rel2 {
+                       to_x: "elm.swallow.end";
+                       to_y: "base";
+                       relative: 0.0  0.5;
+                       offset:   -1 -5;
+                   }
+                   text {
+                       style: "grid_style";
+                       min: 1 1;
+                   }
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   text {
+                       style: "grid_selected_style";
+                   }
+               }
+           }
+           part { name: "fg1";
+               clip_to: "disclip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+                   rel1.to: "bg";
+                   rel2.relative: 1.0 0.5;
+                   rel2.to: "bg";
+                   image {
+                       normal: "bt_sm_hilight.png";
+                       border: 6 6 6 0;
+                   }
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "fg2";
+               clip_to: "disclip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+                   rel1.to: "bg";
+                   rel2.to: "bg";
+                   image {
+                       normal: "bt_sm_shine.png";
+                       border: 6 6 6 0;
+                   }
+               }
+               description { state: "selected" 0.0;
+                   inherit: "default" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "disclip";
+               type: RECT;
+               description { state: "default" 0.0;
+                   rel1.to: "bg";
+                   rel2.to: "bg";
+               }
+               description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   color: 255 255 255 64;
+               }
+           }
+       }
+       programs {
+           // signal: elm,state,%s,active
+           //   a "check" item named %s went active
+           // signal: elm,state,%s,passive
+           //   a "check" item named %s went passive
+           // default is passive
+           program {
+               name:    "go_active";
+               signal:  "elm,state,selected";
+               source:  "elm";
+               action:  STATE_SET "selected" 0.0;
+               target:  "bg";
+               target:  "fg1";
+               target:  "fg2";
+               target:  "elm.text";
+           }
+           program {
+               name:    "go_passive";
+               signal:  "elm,state,unselected";
+               source:  "elm";
+               action:  STATE_SET "default" 0.0;
+               target:  "bg";
+               target:  "fg1";
+               target:  "fg2";
+               target:  "elm.text";
+               transition: LINEAR 0.1;
+           }
+           program {
+               name:    "go_disabled";
+               signal:  "elm,state,disabled";
+               source:  "elm";
+               action:  STATE_SET "disabled" 0.0;
+               target:  "disclip";
+           }
+           program {
+               name:    "go_enabled";
+               signal:  "elm,state,enabled";
+               source:  "elm";
+               action:  STATE_SET "default" 0.0;
+               target:  "disclip";
+           }
+       }
+   }
+
+   ///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/photocam/base/default";
+       script {
+           public sbvis_v, sbvis_h, sbalways_v, sbalways_h, sbvis_timer;
+           public timer0(val) {
+               new v;
+               v = get_int(sbvis_v);
+               if (v) {
+                   v = get_int(sbalways_v);
+                   if (!v) {
+                       emit("do-hide-vbar", "");
+                       set_int(sbvis_v, 0);
+                   }
+               }
+               v = get_int(sbvis_h);
+               if (v) {
+                   v = get_int(sbalways_h);
+                   if (!v) {
+                       emit("do-hide-hbar", "");
+                       set_int(sbvis_h, 0);
+                   }
+               }
+               set_int(sbvis_timer, 0);
+               return 0;
+           }
+       }
+       images {
+           image: "shelf_inset.png" COMP;
+           image: "bt_sm_base2.png" COMP;
+           image: "bt_sm_shine.png" COMP;
+           image: "bt_sm_hilight.png" COMP;
+           image: "sb_runnerh.png" COMP;
+           image: "sb_runnerv.png" COMP;
+           image: "busy-1.png" COMP;
+           image: "busy-2.png" COMP;
+           image: "busy-3.png" COMP;
+           image: "busy-4.png" COMP;
+           image: "busy-5.png" COMP;
+           image: "busy-6.png" COMP;
+           image: "busy-7.png" COMP;
+           image: "busy-8.png" COMP;
+           image: "busy-9.png" COMP;
+       }
+       parts {
+           part { name: "bg";
+               type: RECT;
+               description { state: "default" 0.0;
+                   rel1.offset: 1 1;
+                   rel2.offset: -2 -2;
+                   color: 255 255 255 0;
+               }
+           }
+           part { name: "clipper";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "bg";
+                   rel2.to: "bg";
+               }
+           }
+           part { name: "elm.swallow.content";
+               clip_to: "clipper";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   rel1.offset: 1 1;
+                   rel2.offset: -2 -2;
+               }
+           }
+           part { name: "busy_clip";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+               }
+               description { state: "active" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "busy";
+               clip_to: "busy_clip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   fixed: 1 1;
+                   min: 32 32;
+                   aspect: 1.0 1.0;
+                   align: 1.0 1.0;
+                   aspect_preference: BOTH;
+                   rel1 {
+                       relative: 0.9 0.9;
+                       offset:   -9 -9;
+                   }
+                   rel2 {
+                       relative: 0.9 0.9;
+                       offset:   -9 -9;
+                   }
+                   image {
+                       normal: "busy-9.png";
+                       tween:  "busy-1.png";
+                       tween:  "busy-2.png";
+                       tween:  "busy-3.png";
+                       tween:  "busy-4.png";
+                       tween:  "busy-5.png";
+                       tween:  "busy-6.png";
+                       tween:  "busy-7.png";
+                       tween:  "busy-8.png";
+                   }
+               }
+           }
+           part { name: "conf_over";
+               mouse_events:  0;
+               description { state: "default" 0.0;
+                   rel1.offset: 0 0;
+                   rel2.offset: -1 -1;
+                   image {
+                       normal: "shelf_inset.png";
+                       border: 7 7 7 7;
+                       middle: 0;
+                   }
+                   fill.smooth : 0;
+               }
+           }
+           part { name: "sb_vbar_clip_master";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+               }
+               description { state: "hidden" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+               }
+           }
+           part { name: "sb_vbar_clip";
+               clip_to: "sb_vbar_clip_master";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+               }
+               description { state: "hidden" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+               }
+           }
+           part { name: "sb_vbar";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   fixed: 1 1;
+                   visible: 0;
+                   min: 17 17;
+                   align: 1.0 0.0;
+                   rel1 {
+                       relative: 1.0 0.0;
+                       offset:   -2 0;
+                   }
+                   rel2 {
+                       relative: 1.0 0.0;
+                       offset:   -2 -1;
+                       to_y:     "sb_hbar";
+                   }
+               }
+           }
+           part { name: "sb_vbar_runner";
+               clip_to: "sb_vbar_clip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   min: 3 3;
+                   max: 3 99999;
+                   rel1.to:       "sb_vbar";
+                   rel2.to:       "sb_vbar";
+                   image {
+                       normal: "sb_runnerv.png";
+                       border: 0 0 4 4;
+                   }
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "elm.dragable.vbar";
+               clip_to: "sb_vbar_clip";
+               mouse_events: 0;
+               dragable {
+                   x: 0 0 0;
+                   y: 1 1 0;
+                   confine: "sb_vbar";
+               }
+               description { state: "default" 0.0;
+                   fixed: 1 1;
+                   min: 17 17;
+                   rel1 {
+                       relative: 0.5  0.5;
+                       offset:   0    0;
+                       to: "sb_vbar";
+                   }
+                   rel2 {
+                       relative: 0.5  0.5;
+                       offset:   0    0;
+                       to: "sb_vbar";
+                   }
+                   image {
+                       normal: "bt_sm_base2.png";
+                       border: 6 6 6 6;
+                   }
+                   image.middle: SOLID;
+               }
+           }
+           part { name: "sb_vbar_over1";
+               clip_to: "sb_vbar_clip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.dragable.vbar";
+                   rel2.relative: 1.0 0.5;
+                   rel2.to: "elm.dragable.vbar";
+                   image {
+                       normal: "bt_sm_hilight.png";
+                       border: 6 6 6 0;
+                   }
+               }
+           }
+           part { name: "sb_vbar_over2";
+               clip_to: "sb_vbar_clip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.dragable.vbar";
+                   rel2.to: "elm.dragable.vbar";
+                   image {
+                       normal: "bt_sm_shine.png";
+                       border: 6 6 6 0;
+                   }
+               }
+           }
+
+           part { name: "sb_hbar_clip_master";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+               }
+               description { state: "hidden" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+               }
+           }
+           part { name: "sb_hbar_clip";
+               clip_to: "sb_hbar_clip_master";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+               }
+               description { state: "hidden" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+               }
+           }
+           part { name: "sb_hbar";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   fixed: 1 1;
+                   visible: 0;
+                   min: 17 17;
+                   align: 0.0 1.0;
+                   rel1 {
+                       relative: 0.0 1.0;
+                       offset:   0 -2;
+                   }
+                   rel2 {
+                       relative: 0.0 1.0;
+                       offset:   -1 -2;
+                       to_x:     "sb_vbar";
+                   }
+               }
+           }
+           part { name: "sb_hbar_runner";
+               clip_to: "sb_hbar_clip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   min: 3 3;
+                   max: 99999 3;
+                   rel1.to:       "sb_hbar";
+                   rel2.to:       "sb_hbar";
+                   image {
+                       normal: "sb_runnerh.png";
+                       border: 4 4 0 0;
+                   }
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "elm.dragable.hbar";
+               clip_to: "sb_hbar_clip";
+               mouse_events: 0;
+               dragable {
+                   x: 1 1 0;
+                   y: 0 0 0;
+                   confine: "sb_hbar";
+               }
+               description { state: "default" 0.0;
+                   fixed: 1 1;
+                   min: 17 17;
+                   rel1 {
+                       relative: 0.5  0.5;
+                       offset:   0    0;
+                       to: "sb_hbar";
+                   }
+                   rel2 {
+                       relative: 0.5  0.5;
+                       offset:   0    0;
+                       to: "sb_hbar";
+                   }
+                   image {
+                       normal: "bt_sm_base2.png";
+                       border: 6 6 6 6;
+                   }
+                   image.middle: SOLID;
+               }
+           }
+           part { name: "sb_hbar_over1";
+               clip_to: "sb_hbar_clip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.dragable.hbar";
+                   rel2.relative: 1.0 0.5;
+                   rel2.to: "elm.dragable.hbar";
+                   image {
+                       normal: "bt_sm_hilight.png";
+                       border: 6 6 6 0;
+                   }
+               }
+           }
+           part { name: "sb_hbar_over2";
+               clip_to: "sb_hbar_clip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.dragable.hbar";
+                   rel2.to: "elm.dragable.hbar";
+                   image {
+                       normal: "bt_sm_shine.png";
+                       border: 6 6 6 0;
+                   }
+               }
+           }
+       }
+       programs {
+           program { name: "load";
+               signal: "load";
+               source: "";
+               script {
+                   set_state(PART:"sb_hbar_clip", "hidden", 0.0);
+                   set_state(PART:"sb_vbar_clip", "hidden", 0.0);
+                   set_int(sbvis_h, 0);
+                   set_int(sbvis_v, 0);
+                   set_int(sbalways_v, 0);
+                   set_int(sbalways_h, 0);
+                   set_int(sbvis_timer, 0);
+               }
+           }
+
+           program { name: "vbar_show";
+               signal: "elm,action,show,vbar";
+               source: "elm";
+               action:  STATE_SET "default" 0.0;
+               target: "sb_vbar_clip_master";
+           }
+           program { name: "vbar_hide";
+               signal: "elm,action,hide,vbar";
+               source: "elm";
+               action:  STATE_SET "hidden" 0.0;
+               target: "sb_vbar_clip_master";
+           }
+           program { name: "vbar_show_always";
+               signal: "elm,action,show_always,vbar";
+               source: "elm";
+               script {
+                   new v;
+                   v = get_int(sbvis_v);
+                   v |= get_int(sbalways_v);
+                   if (!v) {
+                       set_int(sbalways_v, 1);
+                       emit("do-show-vbar", "");
+                       set_int(sbvis_v, 1);
+                   }
+               }
+           }
+           program { name: "vbar_show_notalways";
+               signal: "elm,action,show_notalways,vbar";
+               source: "elm";
+               script {
+                   new v;
+                   v = get_int(sbalways_v);
+                   if (v) {
+                       set_int(sbalways_v, 0);
+                       v = get_int(sbvis_v);
+                       if (!v) {
+                           emit("do-hide-vbar", "");
+                           set_int(sbvis_v, 0);
+                       }
+                   }
+               }
+           }
+           program { name: "sb_vbar_show";
+               signal: "do-show-vbar";
+               source: "";
+               action:  STATE_SET "default" 0.0;
+               transition: LINEAR 1.0;
+               target: "sb_vbar_clip";
+           }
+           program { name: "sb_vbar_hide";
+               signal: "do-hide-vbar";
+               source: "";
+               action:  STATE_SET "hidden" 0.0;
+               transition: LINEAR 1.0;
+               target: "sb_vbar_clip";
+           }
+
+           program { name: "hbar_show";
+               signal: "elm,action,show,hbar";
+               source: "elm";
+               action:  STATE_SET "default" 0.0;
+               target: "sb_hbar_clip_master";
+           }
+           program { name: "hbar_hide";
+               signal: "elm,action,hide,hbar";
+               source: "elm";
+               action:  STATE_SET "hidden" 0.0;
+               target: "sb_hbar_clip_master";
+           }
+           program { name: "hbar_show_always";
+               signal: "elm,action,show_always,hbar";
+               source: "elm";
+               script {
+                   new v;
+                   v = get_int(sbvis_h);
+                   v |= get_int(sbalways_h);
+                   if (!v) {
+                       set_int(sbalways_h, 1);
+                       emit("do-show-hbar", "");
+                       set_int(sbvis_h, 1);
+                   }
+               }
+           }
+           program { name: "hbar_show_notalways";
+               signal: "elm,action,show_notalways,hbar";
+               source: "elm";
+               script {
+                   new v;
+                   v = get_int(sbalways_h);
+                   if (v) {
+                       set_int(sbalways_h, 0);
+                       v = get_int(sbvis_h);
+                       if (!v) {
+                           emit("do-hide-hbar", "");
+                           set_int(sbvis_h, 0);
+                       }
+                   }
+               }
+           }
+           program { name: "sb_hbar_show";
+               signal: "do-show-hbar";
+               source: "";
+               action:  STATE_SET "default" 0.0;
+               transition: LINEAR 1.0;
+               target: "sb_hbar_clip";
+           }
+           program { name: "sb_hbar_hide";
+               signal: "do-hide-hbar";
+               source: "";
+               action:  STATE_SET "hidden" 0.0;
+               transition: LINEAR 1.0;
+               target: "sb_hbar_clip";
+           }
+
+           program { name: "scroll";
+               signal: "elm,action,scroll";
+               source: "elm";
+               script {
+                   new v;
+                   v = get_int(sbvis_v);
+                   v |= get_int(sbalways_v);
+                   if (!v) {
+                       emit("do-show-vbar", "");
+                       set_int(sbvis_v, 1);
+                   }
+                   v = get_int(sbvis_h);
+                   v |= get_int(sbalways_h);
+                   if (!v) {
+                       emit("do-show-hbar", "");
+                       set_int(sbvis_h, 1);
+                   }
+                   v = get_int(sbvis_timer);
+                   if (v > 0) cancel_timer(v);
+                   v = timer(2.0, "timer0", 0);
+                   set_int(sbvis_timer, v);
+               }
+           }
+           program { name: "go1";
+               signal: "elm,state,busy,start";
+               source: "elm";
+               action: STATE_SET "active" 0.0;
+               transition: SINUSOIDAL 1.0;
+               target:  "busy_clip";
+           }
+           program { name: "go2";
+               signal: "elm,state,busy,start";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               transition: LINEAR 0.5;
+               target: "busy";
+               after:  "go2";
+           }
+           program { name: "stop1";
+               signal: "elm,state,busy,stop";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               transition: SINUSOIDAL 1.0;
+               target: "busy_clip";
+               after: "stop2";
+           }
+         program { name: "stop2";
+            action: ACTION_STOP;
+            target: "go2";
+         }
+      }
+   }
+
+   ///////////////////////////////////////////////////////////////////////////////
+   group { name: "elm/map/base/default";
+       script {
+           public sbvis_v, sbvis_h, sbalways_v, sbalways_h, sbvis_timer;
+           public timer0(val) {
+               new v;
+               v = get_int(sbvis_v);
+               if (v) {
+                   v = get_int(sbalways_v);
+                   if (!v) {
+                       emit("do-hide-vbar", "");
+                       set_int(sbvis_v, 0);
+                   }
+               }
+               v = get_int(sbvis_h);
+               if (v) {
+                   v = get_int(sbalways_h);
+                   if (!v) {
+                       emit("do-hide-hbar", "");
+                       set_int(sbvis_h, 0);
+                   }
+               }
+               set_int(sbvis_timer, 0);
+               return 0;
+           }
+       }
+       images {
+           image: "shelf_inset.png" COMP;
+           image: "bt_sm_base2.png" COMP;
+           image: "bt_sm_shine.png" COMP;
+           image: "bt_sm_hilight.png" COMP;
+           image: "sb_runnerh.png" COMP;
+           image: "sb_runnerv.png" COMP;
+           image: "busy-1.png" COMP;
+           image: "busy-2.png" COMP;
+           image: "busy-3.png" COMP;
+           image: "busy-4.png" COMP;
+           image: "busy-5.png" COMP;
+           image: "busy-6.png" COMP;
+           image: "busy-7.png" COMP;
+           image: "busy-8.png" COMP;
+           image: "busy-9.png" COMP;
+       }
+       parts {
+           part { name: "bg";
+               type: RECT;
+               description { state: "default" 0.0;
+                   rel1.offset: 1 1;
+                   rel2.offset: -2 -2;
+                   color: 255 255 255 0;
+               }
+           }
+           part { name: "clipper";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "bg";
+                   rel2.to: "bg";
+               }
+           }
+           part { name: "elm.swallow.content";
+               clip_to: "clipper";
+               type: SWALLOW;
+               description { state: "default" 0.0;
+                   rel1.offset: 1 1;
+                   rel2.offset: -2 -2;
+               }
+           }
+           part { name: "busy_clip";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+               }
+               description { state: "active" 0.0;
+                   visible: 1;
+                   color: 255 255 255 255;
+               }
+           }
+           part { name: "busy";
+               clip_to: "busy_clip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   fixed: 1 1;
+                   min: 32 32;
+                   aspect: 1.0 1.0;
+                   align: 1.0 1.0;
+                   aspect_preference: BOTH;
+                   rel1 {
+                       relative: 0.9 0.9;
+                       offset:   -9 -9;
+                   }
+                   rel2 {
+                       relative: 0.9 0.9;
+                       offset:   -9 -9;
+                   }
+                   image {
+                       normal: "busy-9.png";
+                       tween:  "busy-1.png";
+                       tween:  "busy-2.png";
+                       tween:  "busy-3.png";
+                       tween:  "busy-4.png";
+                       tween:  "busy-5.png";
+                       tween:  "busy-6.png";
+                       tween:  "busy-7.png";
+                       tween:  "busy-8.png";
+                   }
+               }
+           }
+           part { name: "conf_over";
+               mouse_events:  0;
+               description { state: "default" 0.0;
+                   rel1.offset: 0 0;
+                   rel2.offset: -1 -1;
+                   image {
+                       normal: "shelf_inset.png";
+                       border: 7 7 7 7;
+                       middle: 0;
+                   }
+                   fill.smooth : 0;
+               }
+           }
+           part { name: "sb_vbar_clip_master";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+               }
+               description { state: "hidden" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+               }
+           }
+           part { name: "sb_vbar_clip";
+               clip_to: "sb_vbar_clip_master";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+               }
+               description { state: "hidden" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+               }
+           }
+           part { name: "sb_vbar";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   fixed: 1 1;
+                   visible: 0;
+                   min: 17 17;
+                   align: 1.0 0.0;
+                   rel1 {
+                       relative: 1.0 0.0;
+                       offset:   -2 0;
+                   }
+                   rel2 {
+                       relative: 1.0 0.0;
+                       offset:   -2 -1;
+                       to_y:     "sb_hbar";
+                   }
+               }
+           }
+           part { name: "sb_vbar_runner";
+               clip_to: "sb_vbar_clip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   min: 3 3;
+                   max: 3 99999;
+                   rel1.to:       "sb_vbar";
+                   rel2.to:       "sb_vbar";
+                   image {
+                       normal: "sb_runnerv.png";
+                       border: 0 0 4 4;
+                   }
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "elm.dragable.vbar";
+               clip_to: "sb_vbar_clip";
+               mouse_events: 0;
+               dragable {
+                   x: 0 0 0;
+                   y: 1 1 0;
+                   confine: "sb_vbar";
+               }
+               description { state: "default" 0.0;
+                   fixed: 1 1;
+                   min: 17 17;
+                   rel1 {
+                       relative: 0.5  0.5;
+                       offset:   0    0;
+                       to: "sb_vbar";
+                   }
+                   rel2 {
+                       relative: 0.5  0.5;
+                       offset:   0    0;
+                       to: "sb_vbar";
+                   }
+                   image {
+                       normal: "bt_sm_base2.png";
+                       border: 6 6 6 6;
+                   }
+                   image.middle: SOLID;
+               }
+           }
+           part { name: "sb_vbar_over1";
+               clip_to: "sb_vbar_clip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.dragable.vbar";
+                   rel2.relative: 1.0 0.5;
+                   rel2.to: "elm.dragable.vbar";
+                   image {
+                       normal: "bt_sm_hilight.png";
+                       border: 6 6 6 0;
+                   }
+               }
+           }
+           part { name: "sb_vbar_over2";
+               clip_to: "sb_vbar_clip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.dragable.vbar";
+                   rel2.to: "elm.dragable.vbar";
+                   image {
+                       normal: "bt_sm_shine.png";
+                       border: 6 6 6 0;
+                   }
+               }
+           }
+
+           part { name: "sb_hbar_clip_master";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+               }
+               description { state: "hidden" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+               }
+           }
+           part { name: "sb_hbar_clip";
+               clip_to: "sb_hbar_clip_master";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+               }
+               description { state: "hidden" 0.0;
+                   visible: 0;
+                   color: 255 255 255 0;
+               }
+           }
+           part { name: "sb_hbar";
+               type: RECT;
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   fixed: 1 1;
+                   visible: 0;
+                   min: 17 17;
+                   align: 0.0 1.0;
+                   rel1 {
+                       relative: 0.0 1.0;
+                       offset:   0 -2;
+                   }
+                   rel2 {
+                       relative: 0.0 1.0;
+                       offset:   -1 -2;
+                       to_x:     "sb_vbar";
+                   }
+               }
+           }
+           part { name: "sb_hbar_runner";
+               clip_to: "sb_hbar_clip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   min: 3 3;
+                   max: 99999 3;
+                   rel1.to:       "sb_hbar";
+                   rel2.to:       "sb_hbar";
+                   image {
+                       normal: "sb_runnerh.png";
+                       border: 4 4 0 0;
+                   }
+                   fill.smooth: 0;
+               }
+           }
+           part { name: "elm.dragable.hbar";
+               clip_to: "sb_hbar_clip";
+               mouse_events: 0;
+               dragable {
+                   x: 1 1 0;
+                   y: 0 0 0;
+                   confine: "sb_hbar";
+               }
+               description { state: "default" 0.0;
+                   fixed: 1 1;
+                   min: 17 17;
+                   rel1 {
+                       relative: 0.5  0.5;
+                       offset:   0    0;
+                       to: "sb_hbar";
+                   }
+                   rel2 {
+                       relative: 0.5  0.5;
+                       offset:   0    0;
+                       to: "sb_hbar";
+                   }
+                   image {
+                       normal: "bt_sm_base2.png";
+                       border: 6 6 6 6;
+                   }
+                   image.middle: SOLID;
+               }
+           }
+           part { name: "sb_hbar_over1";
+               clip_to: "sb_hbar_clip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.dragable.hbar";
+                   rel2.relative: 1.0 0.5;
+                   rel2.to: "elm.dragable.hbar";
+                   image {
+                       normal: "bt_sm_hilight.png";
+                       border: 6 6 6 0;
+                   }
+               }
+           }
+           part { name: "sb_hbar_over2";
+               clip_to: "sb_hbar_clip";
+               mouse_events: 0;
+               description { state: "default" 0.0;
+                   rel1.to: "elm.dragable.hbar";
+                   rel2.to: "elm.dragable.hbar";
+                   image {
+                       normal: "bt_sm_shine.png";
+                       border: 6 6 6 0;
+                   }
+               }
+           }
+       }
+       programs {
+           program { name: "load";
+               signal: "load";
+               source: "";
+               script {
+                   set_state(PART:"sb_hbar_clip", "hidden", 0.0);
+                   set_state(PART:"sb_vbar_clip", "hidden", 0.0);
+                   set_int(sbvis_h, 0);
+                   set_int(sbvis_v, 0);
+                   set_int(sbalways_v, 0);
+                   set_int(sbalways_h, 0);
+                   set_int(sbvis_timer, 0);
+               }
+           }
+
+           program { name: "vbar_show";
+               signal: "elm,action,show,vbar";
+               source: "elm";
+               action:  STATE_SET "default" 0.0;
+               target: "sb_vbar_clip_master";
+           }
+           program { name: "vbar_hide";
+               signal: "elm,action,hide,vbar";
+               source: "elm";
+               action:  STATE_SET "hidden" 0.0;
+               target: "sb_vbar_clip_master";
+           }
+           program { name: "vbar_show_always";
+               signal: "elm,action,show_always,vbar";
+               source: "elm";
+               script {
+                   new v;
+                   v = get_int(sbvis_v);
+                   v |= get_int(sbalways_v);
+                   if (!v) {
+                       set_int(sbalways_v, 1);
+                       emit("do-show-vbar", "");
+                       set_int(sbvis_v, 1);
+                   }
+               }
+           }
+           program { name: "vbar_show_notalways";
+               signal: "elm,action,show_notalways,vbar";
+               source: "elm";
+               script {
+                   new v;
+                   v = get_int(sbalways_v);
+                   if (v) {
+                       set_int(sbalways_v, 0);
+                       v = get_int(sbvis_v);
+                       if (!v) {
+                           emit("do-hide-vbar", "");
+                           set_int(sbvis_v, 0);
+                       }
+                   }
+               }
+           }
+           program { name: "sb_vbar_show";
+               signal: "do-show-vbar";
+               source: "";
+               action:  STATE_SET "default" 0.0;
+               transition: LINEAR 1.0;
+               target: "sb_vbar_clip";
+           }
+           program { name: "sb_vbar_hide";
+               signal: "do-hide-vbar";
+               source: "";
+               action:  STATE_SET "hidden" 0.0;
+               transition: LINEAR 1.0;
+               target: "sb_vbar_clip";
+           }
+
+           program { name: "hbar_show";
+               signal: "elm,action,show,hbar";
+               source: "elm";
+               action:  STATE_SET "default" 0.0;
+               target: "sb_hbar_clip_master";
+           }
+           program { name: "hbar_hide";
+               signal: "elm,action,hide,hbar";
+               source: "elm";
+               action:  STATE_SET "hidden" 0.0;
+               target: "sb_hbar_clip_master";
+           }
+           program { name: "hbar_show_always";
+               signal: "elm,action,show_always,hbar";
+               source: "elm";
+               script {
+                   new v;
+                   v = get_int(sbvis_h);
+                   v |= get_int(sbalways_h);
+                   if (!v) {
+                       set_int(sbalways_h, 1);
+                       emit("do-show-hbar", "");
+                       set_int(sbvis_h, 1);
+                   }
+               }
+           }
+           program { name: "hbar_show_notalways";
+               signal: "elm,action,show_notalways,hbar";
+               source: "elm";
+               script {
+                   new v;
+                   v = get_int(sbalways_h);
+                   if (v) {
+                       set_int(sbalways_h, 0);
+                       v = get_int(sbvis_h);
+                       if (!v) {
+                           emit("do-hide-hbar", "");
+                           set_int(sbvis_h, 0);
+                       }
+                   }
+               }
+           }
+           program { name: "sb_hbar_show";
+               signal: "do-show-hbar";
+               source: "";
+               action:  STATE_SET "default" 0.0;
+               transition: LINEAR 1.0;
+               target: "sb_hbar_clip";
+           }
+           program { name: "sb_hbar_hide";
+               signal: "do-hide-hbar";
+               source: "";
+               action:  STATE_SET "hidden" 0.0;
+               transition: LINEAR 1.0;
+               target: "sb_hbar_clip";
+           }
+
+           program { name: "scroll";
+               signal: "elm,action,scroll";
+               source: "elm";
+               script {
+                   new v;
+                   v = get_int(sbvis_v);
+                   v |= get_int(sbalways_v);
+                   if (!v) {
+                       emit("do-show-vbar", "");
+                       set_int(sbvis_v, 1);
+                   }
+                   v = get_int(sbvis_h);
+                   v |= get_int(sbalways_h);
+                   if (!v) {
+                       emit("do-show-hbar", "");
+                       set_int(sbvis_h, 1);
+                   }
+                   v = get_int(sbvis_timer);
+                   if (v > 0) cancel_timer(v);
+                   v = timer(2.0, "timer0", 0);
+                   set_int(sbvis_timer, v);
+               }
+           }
+           program { name: "go1";
+               signal: "elm,state,busy,start";
+               source: "elm";
+               action: STATE_SET "active" 0.0;
+               transition: SINUSOIDAL 1.0;
+               target:  "busy_clip";
+           }
+           program { name: "go2";
+               signal: "elm,state,busy,start";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               transition: LINEAR 0.5;
+               target: "busy";
+               after:  "go2";
+           }
+           program { name: "stop1";
+               signal: "elm,state,busy,stop";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               transition: SINUSOIDAL 1.0;
+               target: "busy_clip";
+               after: "stop2";
+           }
+         program { name: "stop2";
+            action: ACTION_STOP;
+            target: "go2";
+         }
+      }
+   }
+   group { name: "elm/map/marker/radio/default";
+        data {
+            item: size_w 32;
+            item: size_h 32;
+            item: size_max_w 64;
+            item: size_max_h 64;
+        }
+        parts {
+            part { name: "whole";
+                description { state: "default" 0.0;
+                }
+            }
+            part { name: "base";
+                ignore_flags: ON_HOLD;
+                description { state: "default" 0.0;
+                    image.normal: "radio.png";
+                }
+            }
+            part { name: "elm.icon";
+                type: SWALLOW;
+                clip_to: "whole";
+                mouse_events:  0;
+                description { state: "default" 0.0;
+                    rel1.relative: 0.27 0.27;
+                    rel2.relative: 0.73 0.73;
+                }
+            }
+            part { name: "elm.text";
+                type:          TEXT;
+                effect:        SOFT_SHADOW;
+                mouse_events:  0;
+                scale: 1;
+                description { state: "default" 0.0;
+                    align:    0.5 0.5;
+                    color: 224 224 224 255;
+                    color3: 0 0 0 64;
+                    rel1.relative: 0.28 0.25;
+                    rel2.relative: 0.75 0.75;
+                    text {
+                        font:     "Sans,Edje-Vera";
+                        size:     10;
+                        min:      0 0;
+                        align:    0.5 0.5;
+                    }
+                }
+            }
+       }
+       programs {
+            program { name: "open";
+                signal: "mouse,clicked,1";
+                source: "base";
+                action: SIGNAL_EMIT "open" "elm";
+            }
+            program { name: "bringin";
+                signal: "mouse,down,1,double";
+                source: "base";
+                action: SIGNAL_EMIT "bringin" "elm";
+            }
+       }
+   }
+   group { name: "elm/map/marker/radio2/default";
+        data {
+            item: size_w 32;
+            item: size_h 32;
+            item: size_max_w 64;
+            item: size_max_h 64;
+        }
+        parts {
+            part { name: "base";
+                ignore_flags: ON_HOLD;
+                description { state: "default" 0.0;
+                    image.normal: "radio2.png";
+                }
+            }
+            part { name: "elm.text";
+                type:          TEXT;
+                effect:        SOFT_SHADOW;
+                mouse_events:  0;
+                scale: 1;
+                description { state: "default" 0.0;
+                    align:    0.5 0.5;
+                    color: 224 224 224 255;
+                    color3: 0 0 0 64;
+                    rel1.relative: 0.28 0.25;
+                    rel2.relative: 0.75 0.75;
+                    text {
+                        font:     "Sans,Edje-Vera";
+                        size:     10;
+                        min:      0 0;
+                        align:    0.5 0.5;
+                    }
+                }
+            }
+       }
+       programs {
+            program { name: "open";
+                signal: "mouse,clicked,1";
+                source: "base";
+                action: SIGNAL_EMIT "open" "elm";
+            }
+            program { name: "bringin";
+                signal: "mouse,down,1,double";
+                source: "base";
+                action: SIGNAL_EMIT "bringin" "elm";
+            }
+       }
+   }
+   group { name: "elm/map/marker/empty/default";
+        data {
+            item: size_w 22;
+            item: size_h 22;
+            item: size_max_w 64;
+            item: size_max_h 64;
+        }
+        parts {
+            part { name: "whole";
+                description { state: "default" 0.0;
+                }
+            }
+            part { name: "base";
+                ignore_flags: ON_HOLD;
+                description { state: "default" 0.0;
+                }
+            }
+            part { name: "elm.icon";
+                type: SWALLOW;
+                clip_to: "whole";
+                mouse_events:  0;
+                description { state: "default" 0.0;
+                }
+            }
+            part { name: "elm.text";
+                type:          TEXT;
+                effect:        SOFT_SHADOW;
+                mouse_events:  0;
+                scale: 1;
+                description { state: "default" 0.0;
+                    align:    0.5 0.5;
+                    color: 224 224 224 255;
+                    color3: 0 0 0 64;
+                    rel1.relative: 0.28 0.25;
+                    rel2.relative: 0.75 0.75;
+                    text {
+                        font:     "Sans,Edje-Vera";
+                        size:     10;
+                        min:      0 0;
+                        align:    0.5 0.5;
+                    }
+                }
+            }
+       }
+       programs {
+            program { name: "open";
+                signal: "mouse,clicked,1";
+                source: "base";
+                action: SIGNAL_EMIT "open" "elm";
+            }
+            program { name: "bringin";
+                signal: "mouse,down,1,double";
+                source: "base";
+                action: SIGNAL_EMIT "bringin" "elm";
+            }
+       }
+   }
+   group { name: "elm/map/marker_bubble/default";
+    images {
+      image: "bubble.png" COMP;
+      image: "bubble_shine.png" COMP;
+    }
+    data {
+            item: size_w 400;
+            item: size_h 100;
+        }
+    parts {
+    part { name: "clipper";
+        mouse_events:  1;
+        description { state: "default" 0.0;
+          color: 255 255 255 0;
+        }
+        description { state: "show" 0.0;
+            inherit: "default" 0.0;
+            color: 255 255 255 255;
+        }
+      }
+     part { name: "base0";
+        mouse_events:  0;
+        clip_to: "clipper";
+        description { state: "default" 0.0;
+          image {
+            normal: "bubble.png";
+            border: 11 36 10 19;
+          }
+          image.middle: SOLID;
+          fill.smooth: 0;
+        }
+      }
+      part { name: "elm.swallow.content";
+        type: SWALLOW;
+        clip_to: "clipper";
+        description { state: "default" 0.0;
+            align: 0.5 0.5;
+          rel1 {
+            offset: 9 8;
+          }
+          rel2 {
+            offset: -10 -17;
+          }
+        }
+      }
+      part { name: "shine";
+        mouse_events:  0;
+        clip_to: "clipper";
+        description { state:    "default" 0.0;
+          rel1 {
+            to: "base0";
+          }
+          rel2 {
+            to: "base0";
+            relative: 1.0 0.5;
+          }
+          image {
+            normal: "bubble_shine.png";
+            border: 5 5 5 0;
+          }
+          fill.smooth: 0;
+        }
+        }
+    }
+    programs {
+        program { name: "show";
+            signal: "show";
+            action: STATE_SET "show" 0.0;
+            target: "clipper";
+            transition: ACCELERATE 0.5;
+        }
+    }
+  }
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// PANEL
+/////////////////////////////////////////////////////////////////////////////
+  group {
+     name: "elm/panel/base/left";
+     images
+       {
+          image: "bt_base1.png" COMP;
+          image: "bt_hilight.png" COMP;
+          image: "bt_shine.png" COMP;
+          image: "bt_glow.png" COMP;
+          image: "bt_dis_base.png" COMP;
+          image: "icon_arrow_left.png" COMP;
+          image: "icon_arrow_right.png" COMP;
+       }
+     parts
+       {
+          part
+            {
+               name: "bg";
+               type: RECT;
+               mouse_events: 0;
+               description
+                 {
+                    state: "default" 0.0;
+                    color: 255 255 255 0;
+                    rel1.offset: 30 0;
+                    rel2.relative: 0.0 1.0;
+                 }
+               description
+                 {
+                    state: "visible" 0.0;
+                    inherit: "default" 0.0;
+                    rel2.relative: 1.0 1.0;
+                 }
+            }
+          part
+            {
+               name: "base";
+               type: IMAGE;
+               mouse_events: 0;
+               description
+                 {
+                    state: "default" 0.0;
+                    rel2
+                      {
+                         offset: -20 -1;
+                         to_x: "bg";
+                      }
+                    image
+                      {
+                         normal: "bt_dis_base.png";
+                         border: 4 4 4 4;
+                      }
+                 }
+            }
+          part
+            {
+               name: "clipper";
+               type: RECT;
+               mouse_events: 0;
+               description
+                 {
+                    state: "default" 0.0;
+                    rel1
+                      {
+                         offset: 4 4;
+                         to: "base";
+                      }
+                    rel2
+                      {
+                         offset: -5 -5;
+                         to: "base";
+                      }
+                 }
+            }
+          part
+            {
+               name: "elm.swallow.content";
+               type: SWALLOW;
+               clip_to: "clipper";
+               description
+                 {
+                    state: "default" 0.0;
+                    rel1.to: "clipper";
+                    rel2.to: "clipper";
+                 }
+            }
+          part
+            {
+               name: "btn";
+               type: IMAGE;
+               mouse_events: 1;
+               description
+                 {
+                    state: "default" 0.0;
+                    max: 32 48;
+                    fixed: 1 1;
+                    align: 0.0 0.5;
+                    rel1
+                      {
+                         relative: 1.0 0.0;
+                         offset: -3 0;
+                         to_x: "base";
+                      }
+                    rel2.to_x: "bg";
+                    image
+                      {
+                         normal: "bt_base1.png";
+                         border: 0 5 4 12;
+                      }
+                    fill.smooth: 0;
+                 }
+               description
+                 {
+                    state: "clicked" 0.0;
+                    inherit: "default" 0.0;
+                 }
+            }
+          part
+            {
+               name: "btn_over";
+               type: IMAGE;
+               mouse_events: 0;
+               description
+                 {
+                    state: "default" 0.0;
+                    rel1.to: "btn";
+                    rel2
+                      {
+                         relative: 1.0 0.5;
+                         to: "btn";
+                      }
+                    image
+                      {
+                         normal: "bt_hilight.png";
+                         border: 0 7 7 0;
+                      }
+                 }
+            }
+          part
+            {
+               name: "btn_over2";
+               type: IMAGE;
+               mouse_events: 1;
+               repeat_events: 1;
+               ignore_flags: ON_HOLD;
+               description
+                 {
+                    state: "default" 0.0;
+                    rel1.to: "btn";
+                    rel2.to: "btn";
+                    image
+                      {
+                         normal: "bt_shine.png";
+                         border: 0 7 7 7;
+                    }
+                 }
+            }
+          part
+            {
+               name: "btn_over3";
+               type: IMAGE;
+               mouse_events: 1;
+               repeat_events: 1;
+               description
+                 {
+                    state: "default" 0.0;
+                    color: 255 255 255 0;
+                    rel1.to: "btn";
+                    rel2.to: "btn";
+                    image
+                      {
+                       normal: "bt_glow.png";
+                       border: 12 12 12 12;
+                    }
+                  fill.smooth: 0;
+               }
+             description
+               {
+                  state: "clicked" 0.0;
+                  inherit: "default" 0.0;
+                  visible: 1;
+                  color: 255 255 255 255;
+               }
+            }
+          part
+            {
+               name: "btn_icon";
+               type: IMAGE;
+               repeat_events: 1;
+               description
+                 {
+                    state: "default" 0.0;
+                    rel1.to: "btn";
+                    rel2.to: "btn";
+                    align: 0.5 0.5;
+                    min: 16 16;
+                    max: 16 16;
+                    image.normal: "icon_arrow_right.png";
+                 }
+               description
+                 {
+                    state: "visible" 0.0;
+                    inherit: "default" 0.0;
+                    image.normal: "icon_arrow_left.png";
+                 }
+            }
+       }
+     programs
+       {
+          program
+            {
+               name: "show";
+               signal: "elm,action,show";
+               source: "elm";
+               action: STATE_SET "visible" 0.0;
+               target: "bg";
+               target: "btn_icon";
+               transition: LINEAR 0.5;
+            }
+          program
+            {
+               name: "show2";
+               signal: "show";
+               action: STATE_SET "default" 0.0;
+               target: "bg";
+               target: "btn_icon";
+               after: "show3";
+            }
+          program
+            {
+               name: "show3";
+               action: STATE_SET "visible" 0.0;
+               target: "bg";
+               target: "btn_icon";
+               transition: LINEAR 0.5;
+            }
+          program
+            {
+               name: "hide";
+               signal: "elm,action,hide";
+               source: "elm";
+               action: STATE_SET "default" 0.0;
+               target: "bg";
+               target: "btn_icon";
+               transition: LINEAR 0.5;
+            }
+          program
+            {
+               name: "btn_click";
+               signal: "mouse,down,1";
+               source: "btn_over2";
+               action: STATE_SET "clicked" 0.0;
+               target: "btn";
+            }
+          program
+            {
+               name: "btn_unclick";
+               signal: "mouse,up,1";
+               source: "btn_over2";
+               action: STATE_SET "default" 0.0;
+               target: "btn";
+            }
+          program
+            {
+               name: "btn_click2";
+               signal: "mouse,down,1";
+               source: "btn_over3";
+               action: STATE_SET "clicked" 0.0;
+               target: "btn_over3";
+            }
+          program
+            {
+               name: "btn_unclick2";
+               signal: "mouse,up,1";
+               source: "btn_over3";
+               action: STATE_SET "default" 0.0;
+               transition: DECELERATE 0.5;
+               target: "btn_over3";
+            }
+          program
+            {
+               name: "btn_unclick3";
+               signal: "mouse,up,1";
+               source: "btn_over2";
+               action: SIGNAL_EMIT "elm,action,panel,toggle" "";
+            }
+       }
+  }
+
+///////////////////////////////////////////////////////////////////////////////
+  group { name: "elm/conformant/base/default";
+     parts {
+        part { name: "elm.swallow.shelf";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              fixed: 1 1;
+              align: 0.0 0.0;
+              rel2.relative: 1.0 0.0;
+           }
+        }
+        part { name: "elm.swallow.content";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              align: 0.5 0.5;
+              rel1.relative: 0.0 1.0;
+              rel1.to_y: "elm.swallow.shelf";
+              rel2.relative: 1.0 0.0;
+              rel2.to_y: "elm.swallow.panel";
+           }
+        }
+        part { name: "elm.swallow.panel";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+              fixed: 1 1;
+              align: 0.0 1.0;
+              rel1.relative: 0.0 1.0;
+           }
+        }
+     }
+  }
+}
diff --git a/data/themes/dia_botshad.png b/data/themes/dia_botshad.png
new file mode 100644 (file)
index 0000000..89a598e
Binary files /dev/null and b/data/themes/dia_botshad.png differ
diff --git a/data/themes/dia_grad.png b/data/themes/dia_grad.png
new file mode 100644 (file)
index 0000000..bfd7d0e
Binary files /dev/null and b/data/themes/dia_grad.png differ
diff --git a/data/themes/dia_topshad.png b/data/themes/dia_topshad.png
new file mode 100644 (file)
index 0000000..1a77213
Binary files /dev/null and b/data/themes/dia_topshad.png differ
diff --git a/data/themes/down.png b/data/themes/down.png
new file mode 100644 (file)
index 0000000..528c543
Binary files /dev/null and b/data/themes/down.png differ
diff --git a/data/themes/emo-angry-shout.png b/data/themes/emo-angry-shout.png
new file mode 100644 (file)
index 0000000..25477c5
Binary files /dev/null and b/data/themes/emo-angry-shout.png differ
diff --git a/data/themes/emo-angry.png b/data/themes/emo-angry.png
new file mode 100644 (file)
index 0000000..e151077
Binary files /dev/null and b/data/themes/emo-angry.png differ
diff --git a/data/themes/emo-crazy-laugh.png b/data/themes/emo-crazy-laugh.png
new file mode 100644 (file)
index 0000000..4e87937
Binary files /dev/null and b/data/themes/emo-crazy-laugh.png differ
diff --git a/data/themes/emo-evil-laugh.png b/data/themes/emo-evil-laugh.png
new file mode 100644 (file)
index 0000000..1a0ec3a
Binary files /dev/null and b/data/themes/emo-evil-laugh.png differ
diff --git a/data/themes/emo-evil.png b/data/themes/emo-evil.png
new file mode 100644 (file)
index 0000000..32233fd
Binary files /dev/null and b/data/themes/emo-evil.png differ
diff --git a/data/themes/emo-goggle-smile.png b/data/themes/emo-goggle-smile.png
new file mode 100644 (file)
index 0000000..a0e4859
Binary files /dev/null and b/data/themes/emo-goggle-smile.png differ
diff --git a/data/themes/emo-grumpy-smile.png b/data/themes/emo-grumpy-smile.png
new file mode 100644 (file)
index 0000000..12e301f
Binary files /dev/null and b/data/themes/emo-grumpy-smile.png differ
diff --git a/data/themes/emo-grumpy.png b/data/themes/emo-grumpy.png
new file mode 100644 (file)
index 0000000..7de77fa
Binary files /dev/null and b/data/themes/emo-grumpy.png differ
diff --git a/data/themes/emo-guilty-smile.png b/data/themes/emo-guilty-smile.png
new file mode 100644 (file)
index 0000000..57de06e
Binary files /dev/null and b/data/themes/emo-guilty-smile.png differ
diff --git a/data/themes/emo-guilty.png b/data/themes/emo-guilty.png
new file mode 100644 (file)
index 0000000..071deb0
Binary files /dev/null and b/data/themes/emo-guilty.png differ
diff --git a/data/themes/emo-haha.png b/data/themes/emo-haha.png
new file mode 100644 (file)
index 0000000..760535d
Binary files /dev/null and b/data/themes/emo-haha.png differ
diff --git a/data/themes/emo-half-smile.png b/data/themes/emo-half-smile.png
new file mode 100644 (file)
index 0000000..529f60a
Binary files /dev/null and b/data/themes/emo-half-smile.png differ
diff --git a/data/themes/emo-happy-panting.png b/data/themes/emo-happy-panting.png
new file mode 100644 (file)
index 0000000..c6461bc
Binary files /dev/null and b/data/themes/emo-happy-panting.png differ
diff --git a/data/themes/emo-happy.png b/data/themes/emo-happy.png
new file mode 100644 (file)
index 0000000..a8a3c0b
Binary files /dev/null and b/data/themes/emo-happy.png differ
diff --git a/data/themes/emo-indifferent.png b/data/themes/emo-indifferent.png
new file mode 100644 (file)
index 0000000..254133b
Binary files /dev/null and b/data/themes/emo-indifferent.png differ
diff --git a/data/themes/emo-kiss.png b/data/themes/emo-kiss.png
new file mode 100644 (file)
index 0000000..5eb606d
Binary files /dev/null and b/data/themes/emo-kiss.png differ
diff --git a/data/themes/emo-knowing-grin.png b/data/themes/emo-knowing-grin.png
new file mode 100644 (file)
index 0000000..589b44d
Binary files /dev/null and b/data/themes/emo-knowing-grin.png differ
diff --git a/data/themes/emo-laugh.png b/data/themes/emo-laugh.png
new file mode 100644 (file)
index 0000000..282c620
Binary files /dev/null and b/data/themes/emo-laugh.png differ
diff --git a/data/themes/emo-little-bit-sorry.png b/data/themes/emo-little-bit-sorry.png
new file mode 100644 (file)
index 0000000..fced0e2
Binary files /dev/null and b/data/themes/emo-little-bit-sorry.png differ
diff --git a/data/themes/emo-love-lots.png b/data/themes/emo-love-lots.png
new file mode 100644 (file)
index 0000000..4591fe8
Binary files /dev/null and b/data/themes/emo-love-lots.png differ
diff --git a/data/themes/emo-love.png b/data/themes/emo-love.png
new file mode 100644 (file)
index 0000000..8fd0785
Binary files /dev/null and b/data/themes/emo-love.png differ
diff --git a/data/themes/emo-minimal-smile.png b/data/themes/emo-minimal-smile.png
new file mode 100644 (file)
index 0000000..c005174
Binary files /dev/null and b/data/themes/emo-minimal-smile.png differ
diff --git a/data/themes/emo-not-happy.png b/data/themes/emo-not-happy.png
new file mode 100644 (file)
index 0000000..91b4759
Binary files /dev/null and b/data/themes/emo-not-happy.png differ
diff --git a/data/themes/emo-not-impressed.png b/data/themes/emo-not-impressed.png
new file mode 100644 (file)
index 0000000..8a6901c
Binary files /dev/null and b/data/themes/emo-not-impressed.png differ
diff --git a/data/themes/emo-omg.png b/data/themes/emo-omg.png
new file mode 100644 (file)
index 0000000..8f16f50
Binary files /dev/null and b/data/themes/emo-omg.png differ
diff --git a/data/themes/emo-opensmile.png b/data/themes/emo-opensmile.png
new file mode 100644 (file)
index 0000000..3e37d18
Binary files /dev/null and b/data/themes/emo-opensmile.png differ
diff --git a/data/themes/emo-smile.png b/data/themes/emo-smile.png
new file mode 100644 (file)
index 0000000..082731d
Binary files /dev/null and b/data/themes/emo-smile.png differ
diff --git a/data/themes/emo-sorry.png b/data/themes/emo-sorry.png
new file mode 100644 (file)
index 0000000..757fbc7
Binary files /dev/null and b/data/themes/emo-sorry.png differ
diff --git a/data/themes/emo-squint-laugh.png b/data/themes/emo-squint-laugh.png
new file mode 100644 (file)
index 0000000..0e1850b
Binary files /dev/null and b/data/themes/emo-squint-laugh.png differ
diff --git a/data/themes/emo-surprised.png b/data/themes/emo-surprised.png
new file mode 100644 (file)
index 0000000..0b980c6
Binary files /dev/null and b/data/themes/emo-surprised.png differ
diff --git a/data/themes/emo-suspicious.png b/data/themes/emo-suspicious.png
new file mode 100644 (file)
index 0000000..15bcdc0
Binary files /dev/null and b/data/themes/emo-suspicious.png differ
diff --git a/data/themes/emo-tongue-dangling.png b/data/themes/emo-tongue-dangling.png
new file mode 100644 (file)
index 0000000..eb711ce
Binary files /dev/null and b/data/themes/emo-tongue-dangling.png differ
diff --git a/data/themes/emo-tongue-poke.png b/data/themes/emo-tongue-poke.png
new file mode 100644 (file)
index 0000000..932ef85
Binary files /dev/null and b/data/themes/emo-tongue-poke.png differ
diff --git a/data/themes/emo-uh.png b/data/themes/emo-uh.png
new file mode 100644 (file)
index 0000000..554ca35
Binary files /dev/null and b/data/themes/emo-uh.png differ
diff --git a/data/themes/emo-unhappy.png b/data/themes/emo-unhappy.png
new file mode 100644 (file)
index 0000000..163ae6d
Binary files /dev/null and b/data/themes/emo-unhappy.png differ
diff --git a/data/themes/emo-very-sorry.png b/data/themes/emo-very-sorry.png
new file mode 100644 (file)
index 0000000..97091f2
Binary files /dev/null and b/data/themes/emo-very-sorry.png differ
diff --git a/data/themes/emo-what.png b/data/themes/emo-what.png
new file mode 100644 (file)
index 0000000..a472434
Binary files /dev/null and b/data/themes/emo-what.png differ
diff --git a/data/themes/emo-wink.png b/data/themes/emo-wink.png
new file mode 100644 (file)
index 0000000..ad4553a
Binary files /dev/null and b/data/themes/emo-wink.png differ
diff --git a/data/themes/emo-worried.png b/data/themes/emo-worried.png
new file mode 100644 (file)
index 0000000..b081784
Binary files /dev/null and b/data/themes/emo-worried.png differ
diff --git a/data/themes/emo-wtf.png b/data/themes/emo-wtf.png
new file mode 100644 (file)
index 0000000..5551d8b
Binary files /dev/null and b/data/themes/emo-wtf.png differ
diff --git a/data/themes/flip.xcf.gz b/data/themes/flip.xcf.gz
new file mode 100644 (file)
index 0000000..36aca4d
Binary files /dev/null and b/data/themes/flip.xcf.gz differ
diff --git a/data/themes/flip_0b.png b/data/themes/flip_0b.png
new file mode 100644 (file)
index 0000000..8a6ae9e
Binary files /dev/null and b/data/themes/flip_0b.png differ
diff --git a/data/themes/flip_0t.png b/data/themes/flip_0t.png
new file mode 100644 (file)
index 0000000..72506aa
Binary files /dev/null and b/data/themes/flip_0t.png differ
diff --git a/data/themes/flip_1b.png b/data/themes/flip_1b.png
new file mode 100644 (file)
index 0000000..ed80e8b
Binary files /dev/null and b/data/themes/flip_1b.png differ
diff --git a/data/themes/flip_1t.png b/data/themes/flip_1t.png
new file mode 100644 (file)
index 0000000..6c1fba8
Binary files /dev/null and b/data/themes/flip_1t.png differ
diff --git a/data/themes/flip_2b.png b/data/themes/flip_2b.png
new file mode 100644 (file)
index 0000000..3183b59
Binary files /dev/null and b/data/themes/flip_2b.png differ
diff --git a/data/themes/flip_2t.png b/data/themes/flip_2t.png
new file mode 100644 (file)
index 0000000..3453e3d
Binary files /dev/null and b/data/themes/flip_2t.png differ
diff --git a/data/themes/flip_3b.png b/data/themes/flip_3b.png
new file mode 100644 (file)
index 0000000..2eca7d4
Binary files /dev/null and b/data/themes/flip_3b.png differ
diff --git a/data/themes/flip_3t.png b/data/themes/flip_3t.png
new file mode 100644 (file)
index 0000000..4de9804
Binary files /dev/null and b/data/themes/flip_3t.png differ
diff --git a/data/themes/flip_4b.png b/data/themes/flip_4b.png
new file mode 100644 (file)
index 0000000..23484c9
Binary files /dev/null and b/data/themes/flip_4b.png differ
diff --git a/data/themes/flip_4t.png b/data/themes/flip_4t.png
new file mode 100644 (file)
index 0000000..2029161
Binary files /dev/null and b/data/themes/flip_4t.png differ
diff --git a/data/themes/flip_5b.png b/data/themes/flip_5b.png
new file mode 100644 (file)
index 0000000..8d9312a
Binary files /dev/null and b/data/themes/flip_5b.png differ
diff --git a/data/themes/flip_5t.png b/data/themes/flip_5t.png
new file mode 100644 (file)
index 0000000..df43929
Binary files /dev/null and b/data/themes/flip_5t.png differ
diff --git a/data/themes/flip_6b.png b/data/themes/flip_6b.png
new file mode 100644 (file)
index 0000000..09393e6
Binary files /dev/null and b/data/themes/flip_6b.png differ
diff --git a/data/themes/flip_6t.png b/data/themes/flip_6t.png
new file mode 100644 (file)
index 0000000..3cc4061
Binary files /dev/null and b/data/themes/flip_6t.png differ
diff --git a/data/themes/flip_7b.png b/data/themes/flip_7b.png
new file mode 100644 (file)
index 0000000..9afc419
Binary files /dev/null and b/data/themes/flip_7b.png differ
diff --git a/data/themes/flip_7t.png b/data/themes/flip_7t.png
new file mode 100644 (file)
index 0000000..abe1bc9
Binary files /dev/null and b/data/themes/flip_7t.png differ
diff --git a/data/themes/flip_8b.png b/data/themes/flip_8b.png
new file mode 100644 (file)
index 0000000..2185ee9
Binary files /dev/null and b/data/themes/flip_8b.png differ
diff --git a/data/themes/flip_8t.png b/data/themes/flip_8t.png
new file mode 100644 (file)
index 0000000..718e484
Binary files /dev/null and b/data/themes/flip_8t.png differ
diff --git a/data/themes/flip_9b.png b/data/themes/flip_9b.png
new file mode 100644 (file)
index 0000000..f867aea
Binary files /dev/null and b/data/themes/flip_9b.png differ
diff --git a/data/themes/flip_9t.png b/data/themes/flip_9t.png
new file mode 100644 (file)
index 0000000..5800a4c
Binary files /dev/null and b/data/themes/flip_9t.png differ
diff --git a/data/themes/flip_amb.png b/data/themes/flip_amb.png
new file mode 100644 (file)
index 0000000..e7b3b17
Binary files /dev/null and b/data/themes/flip_amb.png differ
diff --git a/data/themes/flip_amt.png b/data/themes/flip_amt.png
new file mode 100644 (file)
index 0000000..bc6a715
Binary files /dev/null and b/data/themes/flip_amt.png differ
diff --git a/data/themes/flip_base.png b/data/themes/flip_base.png
new file mode 100644 (file)
index 0000000..607fba9
Binary files /dev/null and b/data/themes/flip_base.png differ
diff --git a/data/themes/flip_base_shad.png b/data/themes/flip_base_shad.png
new file mode 100644 (file)
index 0000000..0569977
Binary files /dev/null and b/data/themes/flip_base_shad.png differ
diff --git a/data/themes/flip_pmb.png b/data/themes/flip_pmb.png
new file mode 100644 (file)
index 0000000..de14fa5
Binary files /dev/null and b/data/themes/flip_pmb.png differ
diff --git a/data/themes/flip_pmt.png b/data/themes/flip_pmt.png
new file mode 100644 (file)
index 0000000..8a72655
Binary files /dev/null and b/data/themes/flip_pmt.png differ
diff --git a/data/themes/flip_shad.png b/data/themes/flip_shad.png
new file mode 100644 (file)
index 0000000..3d74cea
Binary files /dev/null and b/data/themes/flip_shad.png differ
diff --git a/data/themes/frame_1.png b/data/themes/frame_1.png
new file mode 100644 (file)
index 0000000..fd5645e
Binary files /dev/null and b/data/themes/frame_1.png differ
diff --git a/data/themes/frame_2.png b/data/themes/frame_2.png
new file mode 100644 (file)
index 0000000..0fef1e9
Binary files /dev/null and b/data/themes/frame_2.png differ
diff --git a/data/themes/head.png b/data/themes/head.png
new file mode 100644 (file)
index 0000000..905b92c
Binary files /dev/null and b/data/themes/head.png differ
diff --git a/data/themes/hoversel_entry_bg.png b/data/themes/hoversel_entry_bg.png
new file mode 100644 (file)
index 0000000..ec8b31d
Binary files /dev/null and b/data/themes/hoversel_entry_bg.png differ
diff --git a/data/themes/icon_apps.png b/data/themes/icon_apps.png
new file mode 100644 (file)
index 0000000..a3b90c6
Binary files /dev/null and b/data/themes/icon_apps.png differ
diff --git a/data/themes/icon_arrow_down.png b/data/themes/icon_arrow_down.png
new file mode 100644 (file)
index 0000000..899373f
Binary files /dev/null and b/data/themes/icon_arrow_down.png differ
diff --git a/data/themes/icon_arrow_left.png b/data/themes/icon_arrow_left.png
new file mode 100644 (file)
index 0000000..6651510
Binary files /dev/null and b/data/themes/icon_arrow_left.png differ
diff --git a/data/themes/icon_arrow_right.png b/data/themes/icon_arrow_right.png
new file mode 100644 (file)
index 0000000..58fa68d
Binary files /dev/null and b/data/themes/icon_arrow_right.png differ
diff --git a/data/themes/icon_arrow_up.png b/data/themes/icon_arrow_up.png
new file mode 100644 (file)
index 0000000..46584db
Binary files /dev/null and b/data/themes/icon_arrow_up.png differ
diff --git a/data/themes/icon_chat.png b/data/themes/icon_chat.png
new file mode 100644 (file)
index 0000000..1fe8f63
Binary files /dev/null and b/data/themes/icon_chat.png differ
diff --git a/data/themes/icon_clock.png b/data/themes/icon_clock.png
new file mode 100644 (file)
index 0000000..c89ae17
Binary files /dev/null and b/data/themes/icon_clock.png differ
diff --git a/data/themes/icon_close.png b/data/themes/icon_close.png
new file mode 100644 (file)
index 0000000..d0a5166
Binary files /dev/null and b/data/themes/icon_close.png differ
diff --git a/data/themes/icon_delete.png b/data/themes/icon_delete.png
new file mode 100644 (file)
index 0000000..e0a635e
Binary files /dev/null and b/data/themes/icon_delete.png differ
diff --git a/data/themes/icon_edit.png b/data/themes/icon_edit.png
new file mode 100644 (file)
index 0000000..8dcec9e
Binary files /dev/null and b/data/themes/icon_edit.png differ
diff --git a/data/themes/icon_file.png b/data/themes/icon_file.png
new file mode 100644 (file)
index 0000000..371f1d0
Binary files /dev/null and b/data/themes/icon_file.png differ
diff --git a/data/themes/icon_folder.png b/data/themes/icon_folder.png
new file mode 100644 (file)
index 0000000..2ec380a
Binary files /dev/null and b/data/themes/icon_folder.png differ
diff --git a/data/themes/icon_home.png b/data/themes/icon_home.png
new file mode 100644 (file)
index 0000000..a395fff
Binary files /dev/null and b/data/themes/icon_home.png differ
diff --git a/data/themes/icon_left_arrow.png b/data/themes/icon_left_arrow.png
new file mode 100644 (file)
index 0000000..556399e
Binary files /dev/null and b/data/themes/icon_left_arrow.png differ
diff --git a/data/themes/icon_refresh.png b/data/themes/icon_refresh.png
new file mode 100644 (file)
index 0000000..5ea70bf
Binary files /dev/null and b/data/themes/icon_refresh.png differ
diff --git a/data/themes/icon_right_arrow.png b/data/themes/icon_right_arrow.png
new file mode 100644 (file)
index 0000000..6bbb2c6
Binary files /dev/null and b/data/themes/icon_right_arrow.png differ
diff --git a/data/themes/ilist_1.png b/data/themes/ilist_1.png
new file mode 100644 (file)
index 0000000..40a3238
Binary files /dev/null and b/data/themes/ilist_1.png differ
diff --git a/data/themes/ilist_2.png b/data/themes/ilist_2.png
new file mode 100644 (file)
index 0000000..ee69f15
Binary files /dev/null and b/data/themes/ilist_2.png differ
diff --git a/data/themes/ilist_item_shadow.png b/data/themes/ilist_item_shadow.png
new file mode 100644 (file)
index 0000000..bffa9dc
Binary files /dev/null and b/data/themes/ilist_item_shadow.png differ
diff --git a/data/themes/leftright.png b/data/themes/leftright.png
new file mode 100644 (file)
index 0000000..8188c19
Binary files /dev/null and b/data/themes/leftright.png differ
diff --git a/data/themes/outdent-bottom.png b/data/themes/outdent-bottom.png
new file mode 100644 (file)
index 0000000..2cd49b5
Binary files /dev/null and b/data/themes/outdent-bottom.png differ
diff --git a/data/themes/outdent-top.png b/data/themes/outdent-top.png
new file mode 100644 (file)
index 0000000..b4f891d
Binary files /dev/null and b/data/themes/outdent-top.png differ
diff --git a/data/themes/radio.png b/data/themes/radio.png
new file mode 100644 (file)
index 0000000..f964acd
Binary files /dev/null and b/data/themes/radio.png differ
diff --git a/data/themes/radio2.png b/data/themes/radio2.png
new file mode 100644 (file)
index 0000000..b83e552
Binary files /dev/null and b/data/themes/radio2.png differ
diff --git a/data/themes/radio_base.png b/data/themes/radio_base.png
new file mode 100644 (file)
index 0000000..d219400
Binary files /dev/null and b/data/themes/radio_base.png differ
diff --git a/data/themes/sb_runnerh.png b/data/themes/sb_runnerh.png
new file mode 100644 (file)
index 0000000..a483ce8
Binary files /dev/null and b/data/themes/sb_runnerh.png differ
diff --git a/data/themes/sb_runnerv.png b/data/themes/sb_runnerv.png
new file mode 100644 (file)
index 0000000..cb2da6f
Binary files /dev/null and b/data/themes/sb_runnerv.png differ
diff --git a/data/themes/separator_h.png b/data/themes/separator_h.png
new file mode 100644 (file)
index 0000000..0823fbc
Binary files /dev/null and b/data/themes/separator_h.png differ
diff --git a/data/themes/separator_v.png b/data/themes/separator_v.png
new file mode 100644 (file)
index 0000000..cd1b018
Binary files /dev/null and b/data/themes/separator_v.png differ
diff --git a/data/themes/shad_circ.png b/data/themes/shad_circ.png
new file mode 100644 (file)
index 0000000..e344e5c
Binary files /dev/null and b/data/themes/shad_circ.png differ
diff --git a/data/themes/shelf_inset.png b/data/themes/shelf_inset.png
new file mode 100644 (file)
index 0000000..bb1989d
Binary files /dev/null and b/data/themes/shelf_inset.png differ
diff --git a/data/themes/sl_bg.png b/data/themes/sl_bg.png
new file mode 100644 (file)
index 0000000..ef88a18
Binary files /dev/null and b/data/themes/sl_bg.png differ
diff --git a/data/themes/sl_bg_over.png b/data/themes/sl_bg_over.png
new file mode 100644 (file)
index 0000000..cca085d
Binary files /dev/null and b/data/themes/sl_bg_over.png differ
diff --git a/data/themes/sl_bt2_0_0.png b/data/themes/sl_bt2_0_0.png
new file mode 100644 (file)
index 0000000..f1270cc
Binary files /dev/null and b/data/themes/sl_bt2_0_0.png differ
diff --git a/data/themes/sl_bt2_0_1.png b/data/themes/sl_bt2_0_1.png
new file mode 100644 (file)
index 0000000..5db1c7c
Binary files /dev/null and b/data/themes/sl_bt2_0_1.png differ
diff --git a/data/themes/sl_bt2_0_2.png b/data/themes/sl_bt2_0_2.png
new file mode 100644 (file)
index 0000000..5c04539
Binary files /dev/null and b/data/themes/sl_bt2_0_2.png differ
diff --git a/data/themes/sl_bt2_1.png b/data/themes/sl_bt2_1.png
new file mode 100644 (file)
index 0000000..3872c8c
Binary files /dev/null and b/data/themes/sl_bt2_1.png differ
diff --git a/data/themes/sl_bt2_2.png b/data/themes/sl_bt2_2.png
new file mode 100644 (file)
index 0000000..061ac29
Binary files /dev/null and b/data/themes/sl_bt2_2.png differ
diff --git a/data/themes/sl_bt_0.png b/data/themes/sl_bt_0.png
new file mode 100644 (file)
index 0000000..8691b19
Binary files /dev/null and b/data/themes/sl_bt_0.png differ
diff --git a/data/themes/sl_bt_1.png b/data/themes/sl_bt_1.png
new file mode 100644 (file)
index 0000000..a29f65c
Binary files /dev/null and b/data/themes/sl_bt_1.png differ
diff --git a/data/themes/sl_bt_2.png b/data/themes/sl_bt_2.png
new file mode 100644 (file)
index 0000000..96bd191
Binary files /dev/null and b/data/themes/sl_bt_2.png differ
diff --git a/data/themes/sl_units.png b/data/themes/sl_units.png
new file mode 100644 (file)
index 0000000..87b4c1d
Binary files /dev/null and b/data/themes/sl_units.png differ
diff --git a/data/themes/slv_bg.png b/data/themes/slv_bg.png
new file mode 100644 (file)
index 0000000..97af4d9
Binary files /dev/null and b/data/themes/slv_bg.png differ
diff --git a/data/themes/slv_bg_over.png b/data/themes/slv_bg_over.png
new file mode 100644 (file)
index 0000000..837a721
Binary files /dev/null and b/data/themes/slv_bg_over.png differ
diff --git a/data/themes/slv_units.png b/data/themes/slv_units.png
new file mode 100644 (file)
index 0000000..d935b3b
Binary files /dev/null and b/data/themes/slv_units.png differ
diff --git a/data/themes/sp_bt_l.png b/data/themes/sp_bt_l.png
new file mode 100644 (file)
index 0000000..31d0d94
Binary files /dev/null and b/data/themes/sp_bt_l.png differ
diff --git a/data/themes/sp_bt_r.png b/data/themes/sp_bt_r.png
new file mode 100644 (file)
index 0000000..bef2c54
Binary files /dev/null and b/data/themes/sp_bt_r.png differ
diff --git a/data/themes/tog_base.png b/data/themes/tog_base.png
new file mode 100644 (file)
index 0000000..25b9bc4
Binary files /dev/null and b/data/themes/tog_base.png differ
diff --git a/data/themes/tog_dis_base.png b/data/themes/tog_dis_base.png
new file mode 100644 (file)
index 0000000..7f6865d
Binary files /dev/null and b/data/themes/tog_dis_base.png differ
diff --git a/data/themes/toolbar_sel.png b/data/themes/toolbar_sel.png
new file mode 100644 (file)
index 0000000..4890e3a
Binary files /dev/null and b/data/themes/toolbar_sel.png differ
diff --git a/data/themes/toolbar_separator_v.png b/data/themes/toolbar_separator_v.png
new file mode 100644 (file)
index 0000000..cb2da6f
Binary files /dev/null and b/data/themes/toolbar_separator_v.png differ
diff --git a/data/themes/up.png b/data/themes/up.png
new file mode 100644 (file)
index 0000000..f8697a1
Binary files /dev/null and b/data/themes/up.png differ
diff --git a/data/themes/updown.png b/data/themes/updown.png
new file mode 100644 (file)
index 0000000..549960c
Binary files /dev/null and b/data/themes/updown.png differ
diff --git a/debian/SVN_REV b/debian/SVN_REV
new file mode 100644 (file)
index 0000000..a7df81f
--- /dev/null
@@ -0,0 +1,2 @@
+Revision 48959
+Last Changed Rev 48945
diff --git a/debian/_original/changelog b/debian/_original/changelog
new file mode 100644 (file)
index 0000000..c0f64a7
--- /dev/null
@@ -0,0 +1,5 @@
+elementary (0.4.0+svnYYYYMMDD-1) unstable; urgency=low
+
+  * a SVN release.
+
+ -- quaker <quaker66@gmail.com>  Fri, 23 May 2009 15:52:37 +0100
diff --git a/debian/_original/compat b/debian/_original/compat
new file mode 100644 (file)
index 0000000..1e8b314
--- /dev/null
@@ -0,0 +1 @@
+6
diff --git a/debian/_original/control b/debian/_original/control
new file mode 100644 (file)
index 0000000..91619c5
--- /dev/null
@@ -0,0 +1,26 @@
+Source: elementary
+Section: x11
+Priority: optional
+Maintainer: quaker <quaker66@gmail.com>
+Build-Depends: debhelper (>= 6), cdbs, libecore-dev, libevas-dev, libeet-dev, libedje-dev, pkg-config, libtool, libeina-dev
+Standards-Version: 3.8.1
+Homepage: http://www.enlightenment.org
+
+Package: libelm-dev
+Section: libdevel
+Architecture: any
+Depends: libelm-svn-01 (= ${binary:Version}), libecore-dev, libevas-dev, libeet-dev, libedje-dev
+Description: Elementary - a basic widget set that is easy to use based on EFL for mobile
+ This package contains devel content.
+
+Package: libelm-svn-01
+Architecture: any
+Depends: ${shlibs:Depends}, libelm-bin
+Description: Elementary - a basic widget set that is easy to use based on EFL for mobile
+ This package contains a widget toolkit.
+
+Package: libelm-bin
+Architecture: any
+Depends: ${shlibs:Depends}
+Description: Elementary - a basic widget set that is easy to use based on EFL for mobile
+ This package contains elementary_test
diff --git a/debian/_original/copyright b/debian/_original/copyright
new file mode 100644 (file)
index 0000000..67cec8a
--- /dev/null
@@ -0,0 +1,12 @@
+This package was debianized by quaker <quaker66@gmail.com> on
+Fri, 03 Jan 2008 10:03:48 +0100.
+
+Author: The Rasterman (Carsten Haitzler) <raster@rasterman.com>
+
+Copyright: 
+
+  Copyright (C) 2008 The Rasterman (Carsten Haitzler) <raster@rasterman.com>
+
+License:
+
+  TBD (LGPL)
diff --git a/debian/_original/libelm-bin.install b/debian/_original/libelm-bin.install
new file mode 100644 (file)
index 0000000..30b643e
--- /dev/null
@@ -0,0 +1 @@
+debian/tmp/usr/bin/elementary_test
diff --git a/debian/_original/libelm-dev.install b/debian/_original/libelm-dev.install
new file mode 100644 (file)
index 0000000..cc69688
--- /dev/null
@@ -0,0 +1,3 @@
+debian/tmp/usr/lib/*.a
+debian/tmp/usr/include/*
+debian/tmp/usr/lib/pkgconfig/*.pc
diff --git a/debian/_original/libelm-svn-01.install b/debian/_original/libelm-svn-01.install
new file mode 100644 (file)
index 0000000..60d0439
--- /dev/null
@@ -0,0 +1,6 @@
+debian/tmp/usr/lib/*.so.*
+debian/tmp/usr/lib/*.so
+debian/tmp/usr/share/elementary/images/*
+debian/tmp/usr/share/elementary/objects/*
+debian/tmp/usr/share/elementary/themes/*
+debian/tmp/usr/share/icons/elementary.png
diff --git a/debian/_original/rules b/debian/_original/rules
new file mode 100755 (executable)
index 0000000..6acb8ff
--- /dev/null
@@ -0,0 +1,11 @@
+#!/usr/bin/make -f
+
+include /usr/share/cdbs/1/rules/debhelper.mk
+include /usr/share/cdbs/1/class/autotools.mk
+
+DEB_CONFIGURE_SCRIPT := ./autogen.sh
+DEB_MAKE_CLEAN_TARGET := distclean
+DEB_CONFIGURE_EXTRA_FLAGS := --disable-rpath
+
+clean::
+       [ ! -f Makefile ] || make distclean
diff --git a/doc/.cvsignore b/doc/.cvsignore
new file mode 100644 (file)
index 0000000..cc370ed
--- /dev/null
@@ -0,0 +1,3 @@
+html
+latex
+man
diff --git a/doc/Doxyfile b/doc/Doxyfile
new file mode 100644 (file)
index 0000000..ba707c3
--- /dev/null
@@ -0,0 +1,139 @@
+PROJECT_NAME           = Elementary
+PROJECT_NUMBER         =
+OUTPUT_DIRECTORY       = .
+INPUT                  = elementary.dox ../src/lib
+IMAGE_PATH             = img
+OUTPUT_LANGUAGE        = English
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = head.html
+HTML_FOOTER            = foot.html
+HTML_STYLESHEET        = e.css
+HTML_ALIGN_MEMBERS     = YES
+ENUM_VALUES_PER_LINE   = 1
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = YES
+EXTRACT_ALL            = NO
+EXTRACT_PRIVATE        = NO
+EXTRACT_STATIC         = NO
+EXTRACT_LOCAL_CLASSES  = NO
+HIDE_UNDOC_MEMBERS     = YES
+HIDE_UNDOC_CLASSES     = YES
+HIDE_FRIEND_COMPOUNDS  = YES
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = 
+INTERNAL_DOCS          = NO
+STRIP_CODE_COMMENTS    = YES
+CASE_SENSE_NAMES       = YES
+SHORT_NAMES            = NO
+HIDE_SCOPE_NAMES       = NO
+VERBATIM_HEADERS       = NO
+SHOW_INCLUDE_FILES     = NO
+JAVADOC_AUTOBRIEF      = YES
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = NO
+INHERIT_DOCS           = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+DISTRIBUTE_GROUP_DOC   = NO
+TAB_SIZE               = 2
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ALIASES                = 
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+OPTIMIZE_OUTPUT_FOR_C  = YES
+OPTIMIZE_OUTPUT_JAVA   = NO
+SHOW_USED_FILES        = NO
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+FILE_PATTERNS          =
+RECURSIVE              = NO
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = 
+EXAMPLE_RECURSIVE      = NO
+INPUT_FILTER           = 
+FILTER_SOURCE_FILES    = NO
+SOURCE_BROWSER         = NO
+INLINE_SOURCES         = NO
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+ALPHABETICAL_INDEX     = YES
+COLS_IN_ALPHA_INDEX    = 2
+IGNORE_PREFIX          = 
+GENERATE_TREEVIEW      = NO
+TREEVIEW_WIDTH         = 250
+GENERATE_LATEX         = YES
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = YES
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+GENERATE_MAN           = YES
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = YES
+GENERATE_XML           = NO
+XML_SCHEMA             = 
+XML_DTD                = 
+GENERATE_AUTOGEN_DEF   = NO
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = NO
+INCLUDE_PATH           =
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+CLASS_DIAGRAMS         = NO
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = NO
+CLASS_GRAPH            = NO
+COLLABORATION_GRAPH    = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = NO
+INCLUDED_BY_GRAPH      = NO
+GRAPHICAL_HIERARCHY    = NO
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 512
+MAX_DOT_GRAPH_HEIGHT   = 512
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+SEARCHENGINE           = NO
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644 (file)
index 0000000..98c0866
--- /dev/null
@@ -0,0 +1,32 @@
+MAINTAINERCLEANFILES = Makefile.in elementary.dox
+
+.PHONY: doc
+
+PACKAGE_DOCNAME = $(PACKAGE_TARNAME)-$(PACKAGE_VERSION)-doc
+
+if EFL_BUILD_DOC
+
+doc-clean:
+       rm -rf html/ latex/ man/ xml/ $(PACKAGE_DOCNAME).tar*
+
+doc: all doc-clean
+       $(efl_doxygen)
+       cp img/* html/
+       rm -rf $(PACKAGE_DOCNAME).tar*
+       mkdir -p $(PACKAGE_DOCNAME)/doc
+       cp -R html/ latex/ man/ $(PACKAGE_DOCNAME)/doc
+       tar cf $(PACKAGE_DOCNAME).tar $(PACKAGE_DOCNAME)/
+       bzip2 -9 $(PACKAGE_DOCNAME).tar
+       rm -rf $(PACKAGE_DOCNAME)/
+       mv $(PACKAGE_DOCNAME).tar.bz2 $(top_srcdir)
+
+clean-local: doc-clean
+
+else
+
+doc:
+       @echo "Documentation not built. Run ./configure --help"
+
+endif
+
+EXTRA_DIST = Doxyfile $(wildcard img/*.*) e.css head.html foot.html elementary.dox.in
diff --git a/doc/e.css b/doc/e.css
new file mode 100644 (file)
index 0000000..2dd6b44
--- /dev/null
+++ b/doc/e.css
@@ -0,0 +1,273 @@
+/*
+    Author:
+        Andres Blanc <andresblanc@gmail.com>
+       DaveMDS Andreoli <dave@gurumeditation.it>
+
+    Supported Browsers:
+        ie7, opera9, konqueror4 and firefox3
+
+        Please use a different file for ie6, ie5, etc. hacks.
+*/
+
+
+/* Necessary to place the footer at the bottom of the page */
+html, body {
+       height: 100%;
+       margin: 0px;
+       padding: 0px;
+}
+
+#container {
+       min-height: 100%;
+       height: auto !important;
+       height: 100%;
+       margin: 0 auto -53px;
+}
+
+#footer, #push {
+       height: 53px;
+}
+
+
+* html #container {
+       height: 100%;
+}
+
+/* Prevent floating elements overflowing containers */
+.clear {
+       clear: both;
+       width: 0px;
+       height: 0px;
+}
+
+/* Flexible & centered layout from 750 to 960 pixels */
+.layout {
+       max-width: 960px;
+       min-width: 760px;
+       margin-left: auto;
+       margin-right: auto;
+}
+
+body {
+       /*font-family: Lucida Grande, Helvetica, sans-serif;*/
+       font-family: "Bitstream Vera","Vera","Trebuchet MS",Trebuchet,Tahoma,sans-serif
+}
+
+/* Prevent design overflowing the viewport in small resolutions */
+#container {
+       padding-right: 17px;
+       padding-left: 17px;
+       background-image: url(head_bg.png);
+       background-repeat: repeat-x;
+}
+
+/****************************/
+/* Top main menu            */
+/****************************/
+#header_logo {
+   background-image        : url(logo.png);
+   width                   : 61px;
+}
+
+#header_logo a {
+   position                : absolute;
+   border                  : 0px;
+   background-color        : transparent;
+   top                     : 0px;
+   width                   : 60px;
+   height                  : 60px;
+}
+
+#header_menu {
+   background-image        : url(header_menu_background.png);
+   font                    : normal 10pt verdana,'Bitstream Vera Sans',helvetica,arial,sans-serif;
+   text-align              : right;
+}
+
+#header_last {
+   background-image        : url(header_menu_background_last.png);
+   width                   : 15px;
+}
+
+td.nav_passive {
+   background              : url(header_menu_unselected_background.png) 0 0 no-repeat;
+   height                  : 63px;
+   font-family             : "Bitstream Vera","Vera","Trebuchet MS",Trebuchet,Tahoma,sans-serif;
+   font-size               : 11px;
+   padding                 : 20px 10px 20px 10px;
+   vertical-align          : middle;
+}
+
+td.nav_active {
+   background              : url(header_menu_current_background.png) 0 0 no-repeat;
+   height                  : 63px;
+   color                   : #646464;
+   font-family             : "Bitstream Vera","Vera","Trebuchet MS",Trebuchet,Tahoma,sans-serif;
+   font-size               : 11px;
+   font-weight             : bold;
+   padding                 : 20px 10px 20px 10px;
+   vertical-align          : middle;
+}
+
+#header_menu a {
+   display                 : block;
+   text-decoration         : none;
+   cursor                  : pointer;
+   color                   : #cdcdcd;
+}
+
+
+
+#header {
+       width: 100%;
+       height: 102px;
+}
+
+#header h1 {
+       width: 63px;
+       height: 63px;
+       position: absolute;
+       margin: 0px;
+}
+
+#header h1 span {
+       display: none;
+}
+
+#header h2 {
+       display: none;
+}
+
+/* .menu-container is used to set properties common to .menu and .submenu */
+#header .menu-container {
+}
+
+#header .menu-container ul {
+       list-style-type: none;
+       list-style-position: inside;
+       margin: 0;
+}
+
+#header .menu-container li {
+       display: block;
+       float: right;
+}
+
+#header .menu {
+       height: 63px;
+       display: block;
+       background-image: url(menu_bg.png);
+       background-repeat: repeat-x;
+}
+
+#header .menu ul {
+       height: 100%;
+       display: block;
+       background-image: url(menu_bg_last.png);
+       background-repeat: no-repeat;
+       background-position: top right;
+       padding-right: 17px;
+}
+
+#header .menu li {
+       height: 100%;
+       text-align: center;
+       background-image: url(menu_bg_unsel.png);
+       background-repeat: no-repeat;
+}
+
+#header .menu a {
+       height: 100%;
+       display: block;
+       color: #cdcdcd;
+       text-decoration: none;
+       font-size: 10pt;
+       line-height: 59px;
+       text-align: center;
+       padding: 0px 15px 0px 15px;
+}
+
+#header .menu li:hover {
+       background-image: url(menu_bg_hover.png);
+       background-repeat: no-repeat;
+}
+
+#header .menu li:hover a {
+       color: #FFFFFF;
+}
+
+#header .menu li.current {
+       background-image: url(menu_bg_current.png);
+       background-repeat: no-repeat;
+}
+
+#header .menu li.current a {
+       color: #646464;
+}
+
+
+/* Hide all the submenus but the current */
+#header .submenu ul {
+       display: none;
+}
+
+#header .submenu .current {
+       display: block;
+}
+
+#header .submenu {
+       font: bold 10px verdana,'Bitstream Vera Sans',helvetica,arial,sans-serif;
+       margin-top: 10px;
+}
+
+#header .submenu a {
+       color: #888888;
+       text-decoration: none;
+       font-size: 0.9em;
+       line-height: 15px;
+       padding:0px 5px 0px 5px;
+}
+
+#header .submenu a:hover {
+       color: #444444;
+}
+
+#header .submenu li {
+       border-left: 1px solid #DDDDDD;
+}
+
+#header .submenu li:last-child {
+       border-left: 0;
+}
+
+#header .doxytitle {
+       position: absolute;
+       font-size: 1.8em;
+       font-weight: bold;
+       color: #444444;
+       line-height: 35px;
+}
+
+#header small {
+       font-size: 0.4em;
+}
+
+#footer {
+       background-image: url(foot_bg.png);
+       width: 100%;
+}
+
+#footer table {
+       width: 100%;
+       text-align: center;
+       white-space: nowrap;
+       padding: 5px 30px 5px 30px;
+       font-size: 0.8em;
+       font-family: "Bitstream Vera","Vera","Trebuchet MS",Trebuchet,Tahoma,sans-serif;
+       color: #888888;
+}
+
+#footer td.copyright {
+       width: 100%;
+}
+
diff --git a/doc/elementary.dox.in b/doc/elementary.dox.in
new file mode 100644 (file)
index 0000000..fc39668
--- /dev/null
@@ -0,0 +1,43 @@
+/**
+@file elementary.dox
+@brief Elementary Widget Library
+*/
+
+/**
+@mainpage Elementary
+@image html  elementary.png
+@version @PACKAGE_VERSION@
+@author Carsten Haitzler <raster@rasterman.com>
+@author Gustavo Sverzut Barbieri <barbieri@profusion.mobi>
+@author Cedric Bail <cedric.bail@free.fr>
+@author Vincent Torri <vtorri@univ-evry.fr>
+@author Daniel Kolesa <quaker66@gmail.com>
+@author Jaime Thomas <avi.thomas@gmail.com>
+@author Swisscom - http://www.swisscom.ch/
+@author Christopher Michael <devilhorns@devilhorns.us>
+@author Marco Trevisan (Treviño) <mail@3v1n0.net>
+@author Michael Bouchaud <michael.bouchaud@gmail.com>
+@author Mike Blumenkrantz (zmike) <mike@zentific.com>
+@date 2008-2010
+
+@section intro What is Elementary?
+
+This is a VERY SIMPLE toolkit. It is not meant for writing extensive desktop
+applications (yet). Small simple ones with simple needs.
+
+It is meant to make the programmers work almost brainless but give them lots
+of flexibility.
+
+License: LGPL v2 (see COPYING in the base of Elementary's source). This
+applies to all files in the source here.
+
+Acknowledgements: There is a lot that goes into making a widget set, and
+they don't happen out of nothing. It's like trying to make everyone
+everywhere happy, regardless of age, gender, race or nationality - and
+that is really tough. So thanks to people and organisations behind this,
+aslisted in the Authors section above.
+
+@verbatim
+Pants
+@endverbatim
+*/
diff --git a/doc/foot.html b/doc/foot.html
new file mode 100644 (file)
index 0000000..d43cf8f
--- /dev/null
@@ -0,0 +1,18 @@
+ <div id="push"></div>
+ </div> <!-- #content -->
+  </div> <!-- .layout -->
+ </div> <!-- #container -->
+  <div id="footer">
+    <table><tr>
+      <td class="copyright">Copyright &copy;$year Enlightenment</td>
+      <td class="generated">Docs generated $datetime</td>
+    </tr></table>
+  </div>
+
+
+</body>
+</html>
diff --git a/doc/head.html b/doc/head.html
new file mode 100644 (file)
index 0000000..7e20e6d
--- /dev/null
@@ -0,0 +1,68 @@
+<html>
+<head>
+    <title>$title</title>
+    <meta http-equiv="content-type" content="text/html;charset=UTF-8">
+    <meta name="author" content="Andres Blanc" >
+    
+    <link rel="icon" href="img/favicon.png" type="image/x-icon">
+    <link rel="shortcut icon" href="img/favicon.png" type="image/x-icon">
+    <link rel="icon" href="img/favicon.png" type="image/ico">
+    <link rel="shortcut icon" href="img/favicon.png" type="image/ico">
+
+    <link rel="stylesheet" type="text/css" href="e.css">
+    <link rel="stylesheet" type="text/css" href="edoxy.css">
+</head>
+
+<body>
+
+<div id="container">
+
+<div id="header">
+<div class="layout">
+    
+    <h1><span>Enlightenment</span></h1>
+    <h2><span>Beauty at your fingertips</span></h2>
+
+    <table cellspacing="0" cellpadding="0" width="100%"><tr>
+      <td id="header_logo">
+        <a href="http://www.enlightenment.org"></a>
+      </td>
+      <td id="header_menu">
+        <table cellspacing="0" cellpadding="0" align="right"><tr>
+          <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=home">Home</a></td> 
+          <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=news">News</a></td> 
+          <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=about">About</a></td> 
+          <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=download">Download</a></td> 
+          <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=support">Support</a></td> 
+          <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=contribute">Contribute</a></td> 
+          <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=contact">Contact</a></td> 
+          <td class="nav_passive"><a class="nav_passive" href="http://trac.enlightenment.org/e">Tracker</a></td>
+          <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=docs">Docs</a></td> 
+        </tr></table>          
+      </td>
+      <td id="header_last"></td>
+    </tr></table>
+
+    <div class="doxytitle">
+        $projectname Documentation <small>at $date</small>
+    </div>
+
+    <div class="menu-container">
+        <div class="submenu">
+            <ul class="current">
+                <li><a href="files.html">Files</a></li>
+                <li><a href="globals.html">Globals</a></li>
+                <li><a href="Elementary_8h.html">API Reference</a></li>
+                <li><a href="modules.html">Modules</a></li>
+               <li class="current"><a  href="index.html">Main Page</a></li>
+            </ul>
+        </div>
+    </div>
+
+
+    <div class="clear"></div>
+</div>
+</div>
+
+<div id="content">
+<div class="layout">
diff --git a/doc/img/edoxy.css b/doc/img/edoxy.css
new file mode 100644 (file)
index 0000000..311ca23
--- /dev/null
@@ -0,0 +1,486 @@
+/*
+ * This file contain a custom doxygen style to match e.org graphics
+ */
+
+
+
+/* BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
+       font-family: Geneva, Arial, Helvetica, sans-serif;
+}*/ 
+BODY, TD {
+       font-size: 12px;
+}
+H1 {
+       text-align: center;
+       font-size: 160%;
+}
+H2 {
+       font-size: 120%;
+}
+H3 {
+       font-size: 100%;
+}
+CAPTION { 
+       font-weight: bold 
+}
+DIV.qindex {
+       width: 100%;
+       background-color: #e8eef2;
+       border: 1px solid #84b0c7;
+       text-align: center;
+       margin: 2px;
+       padding: 2px;
+       line-height: 140%;
+}
+DIV.navpath {
+       width: 100%;
+       background-color: #e8eef2;
+       border: 1px solid #84b0c7;
+       text-align: center;
+       margin: 2px;
+       padding: 2px;
+       line-height: 140%;
+}
+DIV.navtab {
+       background-color: #e8eef2;
+       border: 1px solid #84b0c7;
+       text-align: center;
+       margin: 2px;
+       margin-right: 15px;
+       padding: 2px;
+}
+TD.navtab {
+       font-size: 70%;
+}
+A.qindex {
+       text-decoration: none;
+       font-weight: bold;
+       color: #1A419D;
+}
+A.qindex:visited {
+       text-decoration: none;
+       font-weight: bold;
+       color: #1A419D
+}
+A.qindex:hover {
+       text-decoration: none;
+       background-color: #ddddff;
+}
+A.qindexHL {
+       text-decoration: none;
+       font-weight: bold;
+       background-color: #6666cc;
+       color: #ffffff;
+       border: 1px double #9295C2;
+}
+A.qindexHL:hover {
+       text-decoration: none;
+       background-color: #6666cc;
+       color: #ffffff;
+}
+A.qindexHL:visited { 
+       text-decoration: none; 
+       background-color: #6666cc; 
+       color: #ffffff 
+}
+A.el { 
+       text-decoration: none; 
+       font-weight: bold 
+}
+A.elRef { 
+       font-weight: bold 
+}
+A.code:link { 
+       text-decoration: none; 
+       font-weight: normal; 
+       color: #0000FF
+}
+A.code:visited { 
+       text-decoration: none; 
+       font-weight: normal; 
+       color: #0000FF
+}
+A.codeRef:link { 
+       font-weight: normal; 
+       color: #0000FF
+}
+A.codeRef:visited { 
+       font-weight: normal; 
+       color: #0000FF
+}
+A:hover, A:visited:hover { 
+       text-decoration: none;  
+       /* background-color: #f2f2ff; */
+       color: #000055;
+}
+A.anchor {
+       color: #000;
+}
+DL.el { 
+       margin-left: -1cm 
+}
+.fragment {
+       font-family: monospace, fixed;
+       font-size: 95%;
+}
+PRE.fragment {
+       border: 1px solid #CCCCCC;
+       background-color: #f5f5f5;
+       margin-top: 4px;
+       margin-bottom: 4px;
+       margin-left: 2px;
+       margin-right: 8px;
+       padding-left: 6px;
+       padding-right: 6px;
+       padding-top: 4px;
+       padding-bottom: 4px;
+}
+DIV.ah { 
+       background-color: black; 
+       font-weight: bold; 
+       color: #ffffff; 
+       margin-bottom: 3px; 
+       margin-top: 3px 
+}
+
+DIV.groupHeader {
+       margin-left: 16px;
+       margin-top: 12px;
+       margin-bottom: 6px;
+       font-weight: bold;
+}
+DIV.groupText { 
+       margin-left: 16px; 
+       font-style: italic; 
+       font-size: 90% 
+}
+/*BODY {
+       background: white;
+       color: black;
+       margin-right: 20px;
+       margin-left: 20px;
+}*/
+TD.indexkey {
+       background-color: #e8eef2;
+       font-weight: bold;
+       padding-right  : 10px;
+       padding-top    : 2px;
+       padding-left   : 10px;
+       padding-bottom : 2px;
+       margin-left    : 0px;
+       margin-right   : 0px;
+       margin-top     : 2px;
+       margin-bottom  : 2px;
+       border: 1px solid #CCCCCC;
+}
+TD.indexvalue {
+       background-color: #e8eef2;
+       font-style: italic;
+       padding-right  : 10px;
+       padding-top    : 2px;
+       padding-left   : 10px;
+       padding-bottom : 2px;
+       margin-left    : 0px;
+       margin-right   : 0px;
+       margin-top     : 2px;
+       margin-bottom  : 2px;
+       border: 1px solid #CCCCCC;
+}
+TR.memlist {
+       background-color: #f0f0f0; 
+}
+P.formulaDsp { 
+       text-align: center; 
+}
+IMG.formulaDsp {
+}
+IMG.formulaInl { 
+       vertical-align: middle; 
+}
+SPAN.keyword       { color: #008000 }
+SPAN.keywordtype   { color: #604020 }
+SPAN.keywordflow   { color: #e08000 }
+SPAN.comment       { color: #800000 }
+SPAN.preprocessor  { color: #806020 }
+SPAN.stringliteral { color: #002080 }
+SPAN.charliteral   { color: #008080 }
+SPAN.vhdldigit     { color: #ff00ff }
+SPAN.vhdlchar      { color: #000000 }
+SPAN.vhdlkeyword   { color: #700070 }
+SPAN.vhdllogic     { color: #ff0000 }
+
+.mdescLeft {
+       padding: 0px 8px 4px 8px;
+       font-size: 80%;
+       font-style: italic;
+       background-color: #FAFAFA;
+       border-top: 1px none #E0E0E0;
+       border-right: 1px none #E0E0E0;
+       border-bottom: 1px none #E0E0E0;
+       border-left: 1px none #E0E0E0;
+       margin: 0px;
+}
+.mdescRight {
+        padding: 0px 8px 4px 8px;
+       font-size: 80%;
+       font-style: italic;
+       background-color: #FAFAFA;
+       border-top: 1px none #E0E0E0;
+       border-right: 1px none #E0E0E0;
+       border-bottom: 1px none #E0E0E0;
+       border-left: 1px none #E0E0E0;
+       margin: 0px;
+}
+.memItemLeft {
+       padding: 1px 0px 0px 8px;
+       margin: 4px;
+       border-top-width: 1px;
+       border-right-width: 1px;
+       border-bottom-width: 1px;
+       border-left-width: 1px;
+       border-top-color: #E0E0E0;
+       border-right-color: #E0E0E0;
+       border-bottom-color: #E0E0E0;
+       border-left-color: #E0E0E0;
+       border-top-style: solid;
+       border-right-style: none;
+       border-bottom-style: none;
+       border-left-style: none;
+       background-color: #FAFAFA;
+       font-size: 80%;
+}
+.memItemRight {
+       padding: 1px 8px 0px 8px;
+       margin: 4px;
+       border-top-width: 1px;
+       border-right-width: 1px;
+       border-bottom-width: 1px;
+       border-left-width: 1px;
+       border-top-color: #E0E0E0;
+       border-right-color: #E0E0E0;
+       border-bottom-color: #E0E0E0;
+       border-left-color: #E0E0E0;
+       border-top-style: solid;
+       border-right-style: none;
+       border-bottom-style: none;
+       border-left-style: none;
+       background-color: #FAFAFA;
+       font-size: 80%;
+}
+.memTemplItemLeft {
+       padding: 1px 0px 0px 8px;
+       margin: 4px;
+       border-top-width: 1px;
+       border-right-width: 1px;
+       border-bottom-width: 1px;
+       border-left-width: 1px;
+       border-top-color: #E0E0E0;
+       border-right-color: #E0E0E0;
+       border-bottom-color: #E0E0E0;
+       border-left-color: #E0E0E0;
+       border-top-style: none;
+       border-right-style: none;
+       border-bottom-style: none;
+       border-left-style: none;
+       background-color: #FAFAFA;
+       font-size: 80%;
+}
+.memTemplItemRight {
+       padding: 1px 8px 0px 8px;
+       margin: 4px;
+       border-top-width: 1px;
+       border-right-width: 1px;
+       border-bottom-width: 1px;
+       border-left-width: 1px;
+       border-top-color: #E0E0E0;
+       border-right-color: #E0E0E0;
+       border-bottom-color: #E0E0E0;
+       border-left-color: #E0E0E0;
+       border-top-style: none;
+       border-right-style: none;
+       border-bottom-style: none;
+       border-left-style: none;
+       background-color: #FAFAFA;
+       font-size: 80%;
+}
+.memTemplParams {
+       padding: 1px 0px 0px 8px;
+       margin: 4px;
+       border-top-width: 1px;
+       border-right-width: 1px;
+       border-bottom-width: 1px;
+       border-left-width: 1px;
+       border-top-color: #E0E0E0;
+       border-right-color: #E0E0E0;
+       border-bottom-color: #E0E0E0;
+       border-left-color: #E0E0E0;
+       border-top-style: solid;
+       border-right-style: none;
+       border-bottom-style: none;
+       border-left-style: none;
+       color: #606060;
+       background-color: #FAFAFA;
+       font-size: 80%;
+}
+.search { 
+       color: #003399;
+       font-weight: bold;
+}
+FORM.search {
+       margin-bottom: 0px;
+       margin-top: 0px;
+}
+INPUT.search { 
+       font-size: 75%;
+       color: #000080;
+       font-weight: normal;
+       background-color: #e8eef2;
+}
+TD.tiny { 
+       font-size: 75%;
+}
+a {
+       color: #1A41A8;
+}
+a:visited {
+       color: #2A3798;
+}
+.dirtab { 
+       padding: 4px;
+       border-collapse: collapse;
+       border: 1px solid #84b0c7;
+}
+TH.dirtab { 
+       background: #e8eef2;
+       font-weight: bold;
+}
+HR { 
+       height: 1px;
+       border: none;
+       border-top: 1px solid black;
+}
+
+/* Style for detailed member documentation */
+.memtemplate {
+       font-size: 80%;
+       color: #606060;
+       font-weight: normal;
+       margin-left: 3px;
+} 
+.memnav { 
+       background-color: #eeeeee;
+       border: 1px solid #dddddd;
+       text-align: center;
+       margin: 2px;
+       margin-right: 15px;
+       padding: 2px;
+}
+.memitem {
+       padding: 4px;
+       background-color: #eeeeee;
+       border-width: 1px;
+       border-style: solid;
+       border-color: #dddddd;
+       -moz-border-radius: 4px 4px 4px 4px;
+}
+.memname {
+       white-space: nowrap;
+       font-weight: bold;
+        color: #ffffff;
+}
+.memdoc{
+       padding-left: 10px;
+}
+.memproto {
+       background-color: #111111;
+       width: 100%;
+       border-width: 1px;
+       border-style: solid;
+       border-color: #000000;
+       font-weight: bold;
+       -moz-border-radius: 4px 4px 4px 4px;
+}
+.paramkey {
+       text-align: right;
+       color: #ffffff;
+}
+.paramtype {
+       white-space: nowrap;
+       color: #aaaaaa;
+}
+.paramname {
+       color: #ff0000;
+       font-style: italic;
+       white-space: nowrap;
+}
+/* End Styling for detailed member documentation */
+
+/* for the tree view */
+.ftvtree {
+       font-family: sans-serif;
+       margin:0.5em;
+}
+/* these are for tree view when used as main index */
+.directory { 
+       font-size: 9pt; 
+       font-weight: bold; 
+}
+.directory h3 { 
+       margin: 0px; 
+       margin-top: 1em; 
+       font-size: 11pt; 
+}
+
+/* The following two styles can be used to replace the root node title */
+/* with an image of your choice.  Simply uncomment the next two styles, */
+/* specify the name of your image and be sure to set 'height' to the */
+/* proper pixel height of your image. */
+
+/* .directory h3.swap { */
+/*     height: 61px; */
+/*     background-repeat: no-repeat; */
+/*     background-image: url("yourimage.gif"); */
+/* } */
+/* .directory h3.swap span { */
+/*     display: none; */
+/* } */
+
+.directory > h3 { 
+       margin-top: 0; 
+}
+.directory p { 
+       margin: 0px; 
+       white-space: nowrap; 
+}
+.directory div { 
+       display: none; 
+       margin: 0px; 
+}
+.directory img { 
+       vertical-align: -30%; 
+}
+/* these are for tree view when not used as main index */
+.directory-alt { 
+       font-size: 100%; 
+       font-weight: bold; 
+}
+.directory-alt h3 { 
+       margin: 0px; 
+       margin-top: 1em; 
+       font-size: 11pt; 
+}
+.directory-alt > h3 { 
+       margin-top: 0; 
+}
+.directory-alt p { 
+       margin: 0px; 
+       white-space: nowrap; 
+}
+.directory-alt div { 
+       display: none; 
+       margin: 0px; 
+}
+.directory-alt img { 
+       vertical-align: -30%; 
+}
+
diff --git a/doc/img/elementary.png b/doc/img/elementary.png
new file mode 100644 (file)
index 0000000..7975489
Binary files /dev/null and b/doc/img/elementary.png differ
diff --git a/doc/img/foot_bg.png b/doc/img/foot_bg.png
new file mode 100644 (file)
index 0000000..b24f3a4
Binary files /dev/null and b/doc/img/foot_bg.png differ
diff --git a/doc/img/head_bg.png b/doc/img/head_bg.png
new file mode 100644 (file)
index 0000000..081dc13
Binary files /dev/null and b/doc/img/head_bg.png differ
diff --git a/doc/img/header_menu_background.png b/doc/img/header_menu_background.png
new file mode 100644 (file)
index 0000000..e978743
Binary files /dev/null and b/doc/img/header_menu_background.png differ
diff --git a/doc/img/header_menu_background_last.png b/doc/img/header_menu_background_last.png
new file mode 100644 (file)
index 0000000..88c116c
Binary files /dev/null and b/doc/img/header_menu_background_last.png differ
diff --git a/doc/img/header_menu_current_background.png b/doc/img/header_menu_current_background.png
new file mode 100644 (file)
index 0000000..de97c92
Binary files /dev/null and b/doc/img/header_menu_current_background.png differ
diff --git a/doc/img/header_menu_unselected_background.png b/doc/img/header_menu_unselected_background.png
new file mode 100644 (file)
index 0000000..50e5fd8
Binary files /dev/null and b/doc/img/header_menu_unselected_background.png differ
diff --git a/doc/img/logo.png b/doc/img/logo.png
new file mode 100644 (file)
index 0000000..b3884a5
Binary files /dev/null and b/doc/img/logo.png differ
diff --git a/elementary.pc.in b/elementary.pc.in
new file mode 100644 (file)
index 0000000..307d3ad
--- /dev/null
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: elementary
+Description: Mobile device touchscreen widget library
+@pkgconfig_requires_private@: @requirement_elm@
+Version: @VERSION@
+Libs: -L${libdir} -lelementary
+Libs.private: @dlopen_libs@ @my_libs@
+Cflags: -I${includedir} -I${includedir}/elementary
diff --git a/elementary.spec.in b/elementary.spec.in
new file mode 100644 (file)
index 0000000..e255c54
--- /dev/null
@@ -0,0 +1,102 @@
+%define _missing_doc_files_terminate_build 0
+
+%{!?_rel:%{expand:%%global _rel 0.r%(svnversion | sed 's/[^0-9].*$//' || echo 0000)}}
+
+Summary: EFL toolkit for small touchscreens
+Name: @PACKAGE@
+Version: @VERSION@
+Release: %{_rel}
+License: Lesser GPL
+Group: System Environment/Libraries
+URL: http://trac.enlightenment.org/e/wiki/Elementary
+Source: %{name}-%{version}.tar.gz
+Packager: %{?_packager:%{_packager}}%{!?_packager:Rui Miguel Silva Seabra <rms@1407.org>}
+Vendor: %{?_vendorinfo:%{_vendorinfo}}%{!?_vendorinfo:The Enlightenment Project (http://www.enlightenment.org/)}
+Distribution: %{?_distribution:%{_distribution}}%{!?_distribution:%{_vendor}}
+#BuildSuggests: xorg-x11-devel, vim-enhanced
+BuildRequires: evas-devel
+Requires:  evas
+BuildRoot: %{_tmppath}/%{name}-%{version}-root
+
+%description
+Elementary is a widget set. It is a new-style of widget set much more canvas
+object based than anything else. Why not ETK? Why not EWL? Well they both
+tend to veer away from the core of Evas, Ecore and Edje a lot to build their
+own worlds. Also I wanted something focused on embedded devices -
+specifically small touchscreens. Unlike GTK+ and Qt, 75% of the "widget set"
+is already embodied in a common core - Ecore, Edje, Evas etc. So this
+fine-grained library splitting means all of this is shared, just a new
+widget "personality" is on top. And that is... Elementary, my dear watson.
+Elementary.
+
+%package devel
+Summary: Elementary headers, static libraries, documentation and test programs
+Group: System Environment/Libraries
+Requires: %{name} = %{version}, %{name}-bin = %{version}
+Requires: evas-devel
+
+%description devel
+Headers, static libraries, test programs and documentation for Elementary
+
+%package bin
+Summary: Elementary file compiler/decompiler suite
+Group: System Environment/Libraries
+Requires: %{name} = %{version}
+Requires: elementary
+
+%description bin
+Elmementary programs
+
+%prep
+%setup -q
+
+%build
+%{configure} --prefix=%{_prefix}
+%{__make} %{?_smp_mflags} %{?mflags}
+
+%install
+%{__make} %{?mflags_install} DESTDIR=$RPM_BUILD_ROOT install
+test -x `which doxygen` && sh gendoc || :
+
+%post
+/sbin/ldconfig || :
+
+%postun
+/sbin/ldconfig || :
+
+%clean
+test "x$RPM_BUILD_ROOT" != "x/" && rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-, root, root)
+%doc AUTHORS COPYING README
+%{_libdir}/libelementary*.so.*
+
+%files devel
+%defattr(-, root, root)
+%doc doc/html
+%{_libdir}/*.so
+%{_libdir}/*.la
+%{_libdir}/*.a
+%{_libdir}/edje/*.so
+%{_libdir}/edje/*.la
+%{_libdir}/elementary/modules/test_entry/*/module.*
+%{_libdir}/pkgconfig/*
+%{_includedir}/*.h
+%{_includedir}/elementary/*.h
+
+%files bin
+%defattr(-, root, root)
+%{_bindir}/*
+%{_datadir}/applications/*.desktop
+%{_datadir}/elementary/config/*.cfg
+%{_datadir}/elementary/config/default/*
+%{_datadir}/elementary/config/illume/*
+%{_datadir}/elementary/config/standard/*
+%{_datadir}/elementary/edje_externals/*
+%{_datadir}/elementary/images/*
+%{_datadir}/elementary/objects/*
+%{_datadir}/elementary/themes/*
+%{_datadir}/icons/elementary.png
+
+%changelog
diff --git a/m4/ac_attribute.m4 b/m4/ac_attribute.m4
new file mode 100644 (file)
index 0000000..23479a9
--- /dev/null
@@ -0,0 +1,47 @@
+dnl Copyright (C) 2004-2008 Kim Woelders
+dnl Copyright (C) 2008 Vincent Torri <vtorri at univ-evry dot fr>
+dnl That code is public domain and can be freely used or copied.
+dnl Originally snatched from somewhere...
+
+dnl Macro for checking if the compiler supports __attribute__
+
+dnl Usage: AC_C___ATTRIBUTE__
+dnl call AC_DEFINE for HAVE___ATTRIBUTE__ and __UNUSED__
+dnl if the compiler supports __attribute__, HAVE___ATTRIBUTE__ is
+dnl defined to 1 and __UNUSED__ is defined to __attribute__((unused))
+dnl otherwise, HAVE___ATTRIBUTE__ is not defined and __UNUSED__ is
+dnl defined to nothing.
+
+AC_DEFUN([AC_C___ATTRIBUTE__],
+[
+
+AC_MSG_CHECKING([for __attribute__])
+
+AC_CACHE_VAL([ac_cv___attribute__],
+   [AC_TRY_COMPILE(
+       [
+#include <stdlib.h>
+
+int func(int x);
+int foo(int x __attribute__ ((unused)))
+{
+   exit(1);
+}
+       ],
+       [],
+       [ac_cv___attribute__="yes"],
+       [ac_cv___attribute__="no"]
+    )])
+
+AC_MSG_RESULT($ac_cv___attribute__)
+
+if test "x${ac_cv___attribute__}" = "xyes" ; then
+   AC_DEFINE([HAVE___ATTRIBUTE__], [1], [Define to 1 if your compiler has __attribute__])
+   AC_DEFINE([__UNUSED__], [__attribute__((unused))], [Macro declaring a function argument to be unused])
+  else
+    AC_DEFINE([__UNUSED__], [], [Macro declaring a function argument to be unused])
+fi
+
+])
+
+dnl End of ac_attribute.m4
diff --git a/m4/efl_doxygen.m4 b/m4/efl_doxygen.m4
new file mode 100644 (file)
index 0000000..dd6bc3e
--- /dev/null
@@ -0,0 +1,99 @@
+dnl Copyright (C) 2008 Vincent Torri <vtorri at univ-evry dot fr>
+dnl That code is public domain and can be freely used or copied.
+
+dnl Macro that check if doxygen is available or not.
+
+dnl EFL_CHECK_DOXYGEN([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
+dnl Test for the doxygen program
+dnl Defines efl_doxygen
+dnl Defines the automake conditionnal EFL_BUILD_DOC
+dnl
+AC_DEFUN([EFL_CHECK_DOXYGEN],
+[
+
+dnl
+dnl Disable the build of the documentation
+dnl
+AC_ARG_ENABLE([doc],
+   [AC_HELP_STRING(
+       [--disable-doc],
+       [Disable documentation build @<:@default=enabled@:>@])],
+   [
+    if test "x${enableval}" = "xyes" ; then
+       efl_enable_doc="yes"
+    else
+       efl_enable_doc="no"
+    fi
+   ],
+   [efl_enable_doc="yes"])
+
+AC_MSG_CHECKING([whether to build documentation])
+AC_MSG_RESULT([${efl_enable_doc}])
+
+if test "x${efl_enable_doc}" = "xyes" ; then
+
+dnl
+dnl Specify the file name, without path
+dnl
+
+   efl_doxygen="doxygen"
+
+   AC_ARG_WITH([doxygen],
+      [AC_HELP_STRING(
+          [--with-doxygen=FILE],
+          [doxygen program to use @<:@default=doxygen@:>@])],
+dnl
+dnl Check the given doxygen program.
+dnl
+      [efl_doxygen=${withval}
+       AC_CHECK_PROG([efl_have_doxygen],
+          [${efl_doxygen}],
+          [yes],
+          [no])
+       if test "x${efl_have_doxygen}" = "xno" ; then
+          echo "WARNING:"
+          echo "The doxygen program you specified:"
+          echo "${efl_doxygen}"
+          echo "was not found.  Please check the path and make sure "
+          echo "the program exists and is executable."
+          AC_MSG_WARN([no doxygen detected. Documentation will not be built])
+       fi
+      ],
+      [AC_CHECK_PROG([efl_have_doxygen],
+          [${efl_doxygen}],
+          [yes],
+          [no])
+       if test "x${efl_have_doxygen}" = "xno" ; then
+          echo "WARNING:"
+          echo "The doxygen program was not found in your execute path."
+          echo "You may have doxygen installed somewhere not covered by your path."
+          echo ""
+          echo "If this is the case make sure you have the packages installed, AND"
+          echo "that the doxygen program is in your execute path (see your"
+          echo "shell manual page on setting the \$PATH environment variable), OR"
+          echo "alternatively, specify the program to use with --with-doxygen."
+          AC_MSG_WARN([no doxygen detected. Documentation will not be built])
+       fi
+      ])
+fi
+
+dnl
+dnl Substitution
+dnl
+AC_SUBST([efl_doxygen])
+
+if ! test "x${efl_have_doxygen}" = "xyes" ; then
+   efl_enable_doc="no"
+fi
+
+AM_CONDITIONAL(EFL_BUILD_DOC, test "x${efl_enable_doc}" = "xyes")
+
+if test "x${efl_enable_doc}" = "xyes" ; then
+  m4_default([$1], [:])
+else
+  m4_default([$2], [:])
+fi
+
+])
+
+dnl End of doxygen.m4
diff --git a/src/.cvsignore b/src/.cvsignore
new file mode 100644 (file)
index 0000000..282522d
--- /dev/null
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644 (file)
index 0000000..be7ccd9
--- /dev/null
@@ -0,0 +1,4 @@
+AUTOMAKE_OPTIONS     = 1.4 foreign
+MAINTAINERCLEANFILES = Makefile.in
+
+SUBDIRS = lib bin modules edje_externals
diff --git a/src/bin/.cvsignore b/src/bin/.cvsignore
new file mode 100644 (file)
index 0000000..a25cf77
--- /dev/null
@@ -0,0 +1,7 @@
+.deps
+.libs
+Makefile
+Makefile.in
+rage
+raged
+rage_thumb
diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am
new file mode 100644 (file)
index 0000000..172287d
--- /dev/null
@@ -0,0 +1,118 @@
+AUTOMAKE_OPTIONS     = 1.4 foreign
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir) \
+-I$(top_srcdir)/src/lib \
+-I$(top_builddir)/src/lib \
+-I$(top_srcdir)/src/bin \
+-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
+@ELEMENTARY_CFLAGS@ \
+@ELEMENTARY_X_CFLAGS@ \
+@ELEMENTARY_FB_CFLAGS@ \
+@ELEMENTARY_WIN32_CFLAGS@ \
+@ELEMENTARY_WINCE_CFLAGS@ \
+@ELEMENTARY_EDBUS_CFLAGS@ \
+@ELEMENTARY_EFREET_CFLAGS@ \
+@ELEMENTARY_EWEATHER_CFLAGS@ \
+@ELEMENTARY_ETHUMB_CFLAGS@
+
+if ELEMENTARY_WINDOWS_BUILD
+AM_CPPFLAGS += -DELEMENTARY_BUILD
+endif
+
+bin_PROGRAMS = elementary_test elementary_config
+if BUILD_QUICKLAUNCH
+bin_PROGRAMS += elementary_quicklaunch elementary_run elementary_testql
+endif
+
+elementary_test_SOURCES = \
+test.c \
+test_bg.c \
+test_icon.c \
+test_box.c \
+test_button.c \
+test_fileselector_button.c \
+test_toggle.c \
+test_table.c \
+test_grid.c \
+test_clock.c \
+test_layout.c \
+test_hover.c \
+test_entry.c \
+test_notepad.c \
+test_anchorview.c \
+test_anchorblock.c \
+test_toolbar.c \
+test_hoversel.c \
+test_list.c \
+test_carousel.c \
+test_inwin.c \
+test_scaling.c \
+test_slider.c \
+test_genlist.c \
+test_check.c \
+test_pager.c \
+test_radio.c \
+test_win_state.c \
+test_progressbar.c \
+test_fileselector.c \
+test_separator.c \
+test_scroller.c \
+test_spinner.c \
+test_index.c \
+test_photocam.c \
+test_photo.c \
+test_thumb.c \
+test_icon_desktops.c \
+test_notify.c \
+test_slideshow.c \
+test_menu.c \
+test_panel.c \
+test_map.c \
+test_weather.c \
+test_flip.c \
+test_label.c \
+test_conform.c \
+test_multi.c \
+test_floating.c \
+test_launcher.c \
+test_anim.c
+
+elementary_test_LDADD = $(top_builddir)/src/lib/libelementary.la @ELEMENTARY_EWEATHER_LIBS@
+elementary_test_LDFLAGS =
+
+elementary_config_SOURCES = \
+config.c
+
+elementary_config_LDADD = $(top_builddir)/src/lib/libelementary.la @ELEMENTARY_EWEATHER_LIBS@
+elementary_config_LDFLAGS =
+
+if BUILD_QUICKLAUNCH
+elementary_quicklaunch_SOURCES = quicklaunch.c
+elementary_quicklaunch_LDADD = $(top_builddir)/src/lib/libelementary.la @ELEMENTARY_EWEATHER_LIBS@
+elementary_quicklaunch_LDFLAGS =
+
+if BUILD_RUN
+elementary_run_SOURCES = run.c
+elementary_run_LDADD =
+elementary_run_LDFLAGS =
+endif
+
+## This is how to build a quicklanch capable app
+# build the shared lib version - libtool produces a .a and .la file as well
+# as a .so - these get put in libdir ($PREIFX/lib) as elementary_testql.so
+# etc. - this is where elementary will expect to find the .so's for
+# quicklaunch apps.
+elementary_testqldir = $(libdir)
+elementary_testql_LTLIBRARIES = elementary_testql.la
+elementary_testql_la_SOURCES = $(elementary_test_SOURCES)
+elementary_testql_la_LIBADD = $(top_builddir)/src/lib/libelementary.la
+elementary_testql_la_CFLAGS =
+elementary_testql_la_LDFLAGS = -module -avoid-version -no-undefined
+elementary_testql_SOURCES = $(elementary_test_SOURCES)
+elementary_testql_LDADD = $(top_builddir)/src/lib/libelementary.la
+elementary_testql_CFLAGS = -DELM_LIB_QUICKLAUNCH=1
+elementary_testql_LDFLAGS =
+endif
diff --git a/src/bin/config.c b/src/bin/config.c
new file mode 100644 (file)
index 0000000..9c3946b
--- /dev/null
@@ -0,0 +1,738 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+
+static int quiet = 0;
+static int interactive = 1;
+
+static const char *theme_set = NULL;
+static const char *finger_size_set = NULL;
+static const char *scale_set = NULL;
+
+static void
+my_win_del(void *data, Evas_Object *obj, void *event_info)
+{
+   /* called when my_win_main is requested to be deleted */
+   elm_exit(); /* exit the program's main loop that runs in elm_run() */
+}
+
+static void
+sc_round(void *data, Evas_Object *obj, void *event_info)
+{
+   double val = elm_slider_value_get(obj);
+   double v;
+   
+   v = ((double)((int)(val * 10.0))) / 10.0;
+   if (v != val) elm_slider_value_set(obj, v);
+}
+
+static void
+sc_change(void *data, Evas_Object *obj, void *event_info)
+{
+   double scale = elm_scale_get();
+   double val = elm_slider_value_get(obj);
+   
+   if (scale == val) return;
+   elm_scale_all_set(val);
+}
+
+static void
+fs_round(void *data, Evas_Object *obj, void *event_info)
+{
+   double val = elm_slider_value_get(obj);
+   double v;
+   
+   v = ((double)((int)(val * 5.0))) / 5.0;
+   if (v != val) elm_slider_value_set(obj, v);
+}
+
+static void
+fs_change(void *data, Evas_Object *obj, void *event_info)
+{
+   double scale = elm_scale_get();
+   double val = elm_slider_value_get(obj);
+   
+   if (scale == val) return;
+   elm_finger_size_all_set(val);
+}
+
+static void
+_status_basic(Evas_Object *win, Evas_Object *bx0)
+{
+   Evas_Object *lb, *fr;
+   
+   fr = elm_frame_add(win);
+   evas_object_size_hint_weight_set(fr, 1.0, 1.0);
+   elm_frame_label_set(fr, "Information");
+   elm_box_pack_end(bx0, fr);
+   evas_object_show(fr);
+   
+   lb = elm_label_add(win);
+   elm_label_label_set(lb,
+                       "Applying configuration change"
+                       );
+   elm_frame_content_set(fr, lb);
+   evas_object_show(lb);
+}
+
+static void
+_status_config(Evas_Object *win, Evas_Object *bx0)
+{
+   Evas_Object *lb, *pd, *bx2, *fr, *sl, *sp;
+   
+   fr = elm_frame_add(win);
+   evas_object_size_hint_weight_set(fr, 1.0, 1.0);
+   evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_frame_label_set(fr, "Sizing");
+   elm_box_pack_end(bx0, fr);
+   evas_object_show(fr);
+   
+   bx2 = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx2, 1.0, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, 0.5);
+   
+   pd = elm_frame_add(win);
+   evas_object_size_hint_weight_set(pd, 1.0, 0.0);
+   evas_object_size_hint_align_set(pd, EVAS_HINT_FILL, 0.5);
+   elm_object_style_set(pd, "pad_medium");
+   elm_box_pack_end(bx2, pd);
+   evas_object_show(pd);
+   
+   lb = elm_label_add(win);
+   evas_object_size_hint_weight_set(lb, 1.0, 0.0);
+   evas_object_size_hint_align_set(lb, EVAS_HINT_FILL, 0.5);
+   elm_label_label_set(lb,"<hilight>Scale</>");
+   elm_frame_content_set(pd, lb);
+   evas_object_show(lb);
+   
+   sl = elm_slider_add(win);
+   evas_object_size_hint_weight_set(sl, 1.0, 0.0);
+   evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
+   elm_slider_span_size_set(sl, 120);
+   elm_slider_unit_format_set(sl, "%1.2f");
+   elm_slider_indicator_format_set(sl, "%1.2f");
+   elm_slider_min_max_set(sl, 0.25, 5.0);
+   elm_slider_value_set(sl, elm_scale_get());
+   elm_box_pack_end(bx2, sl);
+   evas_object_show(sl);
+   
+   evas_object_smart_callback_add(sl, "changed", sc_round, NULL);
+   evas_object_smart_callback_add(sl, "delay,changed", sc_change, NULL);
+   
+   sp = elm_separator_add(win);
+   elm_separator_horizontal_set(sp, 1);
+   evas_object_size_hint_weight_set(sp, 1.0, 0.0);
+   evas_object_size_hint_align_set(sp, EVAS_HINT_FILL, 0.5);
+   elm_box_pack_end(bx2, sp);
+   evas_object_show(sp);
+   
+   pd = elm_frame_add(win);
+   evas_object_size_hint_weight_set(pd, 1.0, 0.0);
+   evas_object_size_hint_align_set(pd, EVAS_HINT_FILL, 0.5);
+   elm_object_style_set(pd, "pad_medium");
+   elm_box_pack_end(bx2, pd);
+   evas_object_show(pd);
+   
+   lb = elm_label_add(win);
+   evas_object_size_hint_weight_set(lb, 1.0, 0.0);
+   evas_object_size_hint_align_set(lb, EVAS_HINT_FILL, 0.5);
+   elm_label_label_set(lb, "<hilight>Finger Size</><br>");
+   elm_frame_content_set(pd, lb);
+   evas_object_show(lb);
+   
+   sl = elm_slider_add(win);
+   evas_object_size_hint_weight_set(sl, 1.0, 0.0);
+   evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
+   elm_slider_span_size_set(sl, 120);
+   elm_slider_unit_format_set(sl, "%1.0f");
+   elm_slider_indicator_format_set(sl, "%1.0f");
+   elm_slider_min_max_set(sl, 5, 200);
+   elm_slider_value_set(sl, elm_finger_size_get());
+   elm_box_pack_end(bx2, sl);
+   evas_object_show(sl);
+   
+   evas_object_smart_callback_add(sl, "changed", fs_round, NULL);
+   evas_object_smart_callback_add(sl, "delay,changed", fs_change, NULL);
+   
+   // FIXME: add theme selector (basic mode and advanced for fallbacks)
+   // FIXME: save config
+   // FIXME: profile selector / creator etc.
+   // 
+   elm_frame_content_set(fr, bx2);
+   evas_object_show(bx2);
+}
+
+static void
+_flip_to(Evas_Object *win, const char *name)
+{
+   Evas_Object *wid, *fl, *holder, *front, *back;
+   int front_vis;
+   wid        = evas_object_data_get(win, name);
+   fl         = evas_object_data_get(win, "flip");
+   holder     = evas_object_data_get(win, "holder");
+   front_vis  = elm_flip_front_get(fl);
+   if (front_vis)
+     {
+        front = elm_flip_content_front_get(fl);
+        back  = elm_flip_content_back_get(fl);
+        elm_table_pack(holder, back, 0, 0, 1, 1);
+        evas_object_hide(back);
+//        elm_table_unpack(holder, wid); // this should NOT be needed - but in evas_table/elm_table
+        elm_flip_content_back_set(fl, wid);
+     }
+   else
+     {
+        front = elm_flip_content_front_get(fl);
+        back  = elm_flip_content_back_get(fl);
+        elm_table_pack(holder, front, 0, 0, 1, 1);
+        evas_object_hide(front);
+//        elm_table_unpack(holder, wid); // this should NOT be needed - but in evas_table/elm_table
+        elm_flip_content_front_set(fl, wid);
+     }
+   
+   evas_object_show(wid);
+   elm_flip_go(fl, ELM_FLIP_ROTATE_Y_CENTER_AXIS);
+}
+
+static void
+_cf_sizing(void *data, Evas_Object *obj, void *event_info)
+{
+   _flip_to(data, "sizing");
+}
+
+static void
+_cf_themes(void *data, Evas_Object *obj, void *event_info)
+{
+   _flip_to(data, "themes");
+}
+
+static void
+_cf_fonts(void *data, Evas_Object *obj, void *event_info)
+{
+   _flip_to(data, "fonts");
+}
+
+static void
+_cf_profiles(void *data, Evas_Object *obj, void *event_info)
+{
+   _flip_to(data, "profiles");
+}
+
+static void
+_cf_scrolling(void *data, Evas_Object *obj, void *event_info)
+{
+   _flip_to(data, "scrolling");
+}
+
+static void
+_cf_rendering(void *data, Evas_Object *obj, void *event_info)
+{
+   _flip_to(data, "rendering");
+}
+
+static void
+_cf_caches(void *data, Evas_Object *obj, void *event_info)
+{
+   _flip_to(data, "caches");
+}
+
+static void
+_theme_use(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("not implemented\n");
+}
+
+static void
+_theme_browse(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("not implemented\n");
+}
+
+static void
+_status_config_sizing(Evas_Object *win, Evas_Object *holder)
+{
+   Evas_Object *lb, *pd, *bx2, *sl, *sp;
+   
+   bx2 = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx2, 1.0, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, 0.5);
+   
+   pd = elm_frame_add(win);
+   evas_object_size_hint_weight_set(pd, 1.0, 0.0);
+   evas_object_size_hint_align_set(pd, EVAS_HINT_FILL, 0.5);
+   elm_object_style_set(pd, "pad_medium");
+   elm_box_pack_end(bx2, pd);
+   evas_object_show(pd);
+   
+   lb = elm_label_add(win);
+   evas_object_size_hint_weight_set(lb, 1.0, 0.0);
+   evas_object_size_hint_align_set(lb, EVAS_HINT_FILL, 0.5);
+   elm_label_label_set(lb,"<hilight>Scale</>");
+   elm_frame_content_set(pd, lb);
+   evas_object_show(lb);
+   
+   sl = elm_slider_add(win);
+   evas_object_size_hint_weight_set(sl, 1.0, 0.0);
+   evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
+   elm_slider_span_size_set(sl, 120);
+   elm_slider_unit_format_set(sl, "%1.2f");
+   elm_slider_indicator_format_set(sl, "%1.2f");
+   elm_slider_min_max_set(sl, 0.25, 5.0);
+   elm_slider_value_set(sl, elm_scale_get());
+   elm_box_pack_end(bx2, sl);
+   evas_object_show(sl);
+   
+   evas_object_smart_callback_add(sl, "changed", sc_round, NULL);
+   evas_object_smart_callback_add(sl, "delay,changed", sc_change, NULL);
+   
+   sp = elm_separator_add(win);
+   elm_separator_horizontal_set(sp, 1);
+   evas_object_size_hint_weight_set(sp, 1.0, 0.0);
+   evas_object_size_hint_align_set(sp, EVAS_HINT_FILL, 0.5);
+   elm_box_pack_end(bx2, sp);
+   evas_object_show(sp);
+   
+   pd = elm_frame_add(win);
+   evas_object_size_hint_weight_set(pd, 1.0, 0.0);
+   evas_object_size_hint_align_set(pd, EVAS_HINT_FILL, 0.5);
+   elm_object_style_set(pd, "pad_medium");
+   elm_box_pack_end(bx2, pd);
+   evas_object_show(pd);
+   
+   lb = elm_label_add(win);
+   evas_object_size_hint_weight_set(lb, 1.0, 0.0);
+   evas_object_size_hint_align_set(lb, EVAS_HINT_FILL, 0.5);
+   elm_label_label_set(lb, "<hilight>Finger Size</><br>");
+   elm_frame_content_set(pd, lb);
+   evas_object_show(lb);
+   
+   sl = elm_slider_add(win);
+   evas_object_size_hint_weight_set(sl, 1.0, 0.0);
+   evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
+   elm_slider_span_size_set(sl, 120);
+   elm_slider_unit_format_set(sl, "%1.0f");
+   elm_slider_indicator_format_set(sl, "%1.0f");
+   elm_slider_min_max_set(sl, 5, 200);
+   elm_slider_value_set(sl, elm_finger_size_get());
+   elm_box_pack_end(bx2, sl);
+   evas_object_show(sl);
+   
+   evas_object_smart_callback_add(sl, "changed", fs_round, NULL);
+   evas_object_smart_callback_add(sl, "delay,changed", fs_change, NULL);
+
+   evas_object_data_set(win, "sizing", bx2);
+   
+   elm_table_pack(holder, bx2, 0, 0, 1, 1);
+}
+
+static Evas_Object *
+_sample_theme_new(Evas_Object *win)
+{
+   Evas_Object *base, *bg, *bt, *ck, *rd, *rdg, *sl, *fr, *li, *rc, *sp;
+   
+   base = elm_table_add(win);
+   evas_object_size_hint_weight_set(base, 1.0, 1.0);
+   evas_object_size_hint_align_set(base, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   
+   bg = elm_bg_add(win);
+   evas_object_size_hint_weight_set(bg, 1.0, 1.0);
+   evas_object_size_hint_align_set(bg, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_table_pack(base, bg, 0, 0, 2, 4);
+   evas_object_show(bg);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button");
+   elm_table_pack(base, bt, 0, 0, 1, 1);
+   evas_object_show(bt);
+
+   ck = elm_check_add(win);
+   elm_check_label_set(ck, "Check");
+   elm_table_pack(base, ck, 0, 1, 1, 1);
+   evas_object_show(ck);
+   
+   rd = elm_radio_add(win);
+   elm_radio_state_value_set(rd, 0);
+   elm_radio_label_set(rd, "Radio 1");
+   elm_table_pack(base, rd, 1, 0, 1, 1);
+   evas_object_show(rd);
+   rdg = rd;
+   
+   rd = elm_radio_add(win);
+   elm_radio_state_value_set(rd, 1);
+   elm_radio_label_set(rd, "Radio 2");
+   elm_radio_group_add(rd, rdg);
+   elm_table_pack(base, rd, 1, 1, 1, 1);
+   evas_object_show(rd);
+   
+   sp = elm_separator_add(win);
+   elm_separator_horizontal_set(sp, 1);
+   evas_object_size_hint_weight_set(sp, 1.0, 0.0);
+   evas_object_size_hint_align_set(sp, EVAS_HINT_FILL, 0.5);
+   elm_table_pack(base, sl, 0, 2, 2, 1);
+   evas_object_show(sp);
+   
+   sl = elm_slider_add(win);
+   elm_slider_label_set(sl, "Slider");
+   elm_slider_span_size_set(sl, 120);
+   elm_slider_min_max_set(sl, 1, 10);
+   elm_slider_value_set(sl, 4);
+   evas_object_size_hint_weight_set(sl, 1.0, 0.0);
+   evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_table_pack(base, sl, 0, 3, 2, 1);
+   evas_object_show(sl);
+
+   fr = elm_frame_add(win);
+   elm_frame_label_set(fr, "Frame");
+   elm_table_pack(base, fr, 0, 4, 2, 1);
+   evas_object_size_hint_weight_set(fr, 1.0, 1.0);
+   evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_show(fr);
+   
+   li = elm_list_add(win);
+   evas_object_size_hint_weight_set(li, 1.0, 1.0);
+   evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_frame_content_set(fr, li);
+   evas_object_show(li);
+   
+   elm_list_item_append(li, "List Item 1", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "Second Item", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "Third Item", NULL, NULL,  NULL, NULL);
+   elm_list_go(li);
+
+   rc = evas_object_rectangle_add(evas_object_evas_get(win));
+   evas_object_size_hint_min_set(rc, 120, 120);
+   elm_table_pack(base, rc, 0, 4, 2, 1);
+   
+   return base;
+}
+
+static void
+_status_config_themes(Evas_Object *win, Evas_Object *holder)
+{
+   Evas_Object *tb, *rc, *sc, *sp, *li, *pd, *fr, *bt, *sample;
+   
+   tb = elm_table_add(win);
+   evas_object_size_hint_weight_set(tb, 1.0, 1.0);
+   evas_object_size_hint_align_set(tb, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   
+   rc = evas_object_rectangle_add(evas_object_evas_get(win));
+   evas_object_size_hint_min_set(rc, 240, 120);
+   elm_table_pack(tb, rc, 0, 0, 1, 1);
+
+   rc = evas_object_rectangle_add(evas_object_evas_get(win));
+   evas_object_size_hint_min_set(rc, 240, 240);
+   elm_table_pack(tb, rc, 0, 1, 1, 1);
+   
+   /////////////////////////////////////////////
+   
+   pd = elm_frame_add(win);
+   elm_object_style_set(pd, "pad_medium");
+   evas_object_size_hint_weight_set(pd, 1.0, 1.0);
+   evas_object_size_hint_align_set(pd, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_table_pack(tb, pd, 0, 0, 1, 1);
+   evas_object_show(pd);
+   
+   li = elm_list_add(win);
+   evas_object_size_hint_weight_set(li, 1.0, 1.0);
+   evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_frame_content_set(pd, li);
+   evas_object_show(li);
+   
+   // FIXME: list all themes:
+   // ~/.elementary/themes/*.edj
+   // $PREFIX/datadir/themes/*.edj
+   
+   elm_list_item_append(li, "theme 1", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "theme 2", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "theme 3", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "theme 4", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "theme 5", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "theme 6", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "theme 7", NULL, NULL,  NULL, NULL);
+
+   elm_list_go(li);
+   
+   pd = elm_frame_add(win);
+   elm_object_style_set(pd, "pad_medium");
+   evas_object_size_hint_weight_set(pd, 1.0, 1.0);
+   evas_object_size_hint_align_set(pd, 0.9, 0.9);
+   elm_table_pack(tb, pd, 0, 0, 1, 1);
+   evas_object_show(pd);
+   
+   bt = elm_button_add(win);
+   evas_object_smart_callback_add(bt, "clicked", _theme_browse, win);
+   elm_button_label_set(bt, "Browse...");
+   evas_object_size_hint_weight_set(bt, 1.0, 1.0);
+   evas_object_size_hint_align_set(bt, 0.9, 0.9);
+   elm_frame_content_set(pd, bt);
+   evas_object_show(bt);
+   
+   pd = elm_frame_add(win);
+   elm_object_style_set(pd, "pad_medium");
+   evas_object_size_hint_weight_set(pd, 1.0, 0.0);
+   evas_object_size_hint_align_set(pd, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_table_pack(tb, pd, 0, 1, 1, 1);
+   evas_object_show(pd);
+
+   fr = elm_frame_add(win);
+   elm_frame_label_set(fr, "Preview");
+   evas_object_size_hint_weight_set(fr, 1.0, 1.0);
+   evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_frame_content_set(pd, fr);
+   evas_object_show(fr);
+   
+   sc = elm_scroller_add(win);
+   elm_scroller_bounce_set(sc, 0, 0);
+   evas_object_size_hint_weight_set(sc, 1.0, 1.0);
+   evas_object_size_hint_align_set(sc, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_frame_content_set(fr, sc);
+   evas_object_show(sc);
+   
+   sample = _sample_theme_new(win);
+   elm_scroller_content_set(sc, sample);
+   evas_object_show(sample);
+   evas_object_data_set(win, "sample", sample);
+   
+   /////////////////////////////////////////////
+   sp = elm_separator_add(win);
+   elm_separator_horizontal_set(sp, 1);
+   evas_object_size_hint_weight_set(sp, 1.0, 0.0);
+   evas_object_size_hint_align_set(sp, EVAS_HINT_FILL, 0.5);
+   elm_table_pack(tb, sp, 0, 2, 1, 1);
+   evas_object_show(sp);
+   
+   pd = elm_frame_add(win);
+   elm_object_style_set(pd, "pad_medium");
+   evas_object_size_hint_weight_set(pd, 0.0, 0.0);
+   evas_object_size_hint_align_set(pd, 0.5, 0.5);
+   elm_table_pack(tb, pd, 0, 3, 1, 1);
+   evas_object_show(pd);
+   
+   bt = elm_button_add(win);
+   evas_object_smart_callback_add(bt, "clicked", _theme_use, win);
+   elm_button_label_set(bt, "Use Theme");
+   evas_object_size_hint_weight_set(bt, 0.0, 0.0);
+   evas_object_size_hint_align_set(bt, 0.5, 0.5);
+   elm_frame_content_set(pd, bt);
+   evas_object_show(bt);
+   
+   evas_object_data_set(win, "themes", tb);
+   
+   elm_table_pack(holder, tb, 0, 0, 1, 1);
+}
+
+static void
+_unimplemented(Evas_Object *win, Evas_Object *holder, const char *name)
+{
+   Evas_Object *lb, *pd, *bx2;
+   
+   bx2 = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx2, 1.0, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, 0.5);
+   
+   pd = elm_frame_add(win);
+   evas_object_size_hint_weight_set(pd, 0.0, 0.0);
+   evas_object_size_hint_align_set(pd, 0.5, 0.5);
+   elm_object_style_set(pd, "pad_medium");
+   elm_box_pack_end(bx2, pd);
+   evas_object_show(pd);
+   
+   lb = elm_label_add(win);
+   evas_object_size_hint_weight_set(lb, 0.0, 0.0);
+   evas_object_size_hint_align_set(lb, 0.5, 0.5);
+   elm_label_label_set(lb,"<hilight>Not implemented yet</>");
+   elm_frame_content_set(pd, lb);
+   evas_object_show(lb);
+   
+   evas_object_data_set(win, name, bx2);
+   
+   elm_table_pack(holder, bx2, 0, 0, 1, 1);
+}
+
+static void
+_status_config_fonts(Evas_Object *win, Evas_Object *holder)
+{
+   _unimplemented(win, holder, "fonts");
+}
+
+static void
+_status_config_profiles(Evas_Object *win, Evas_Object *holder)
+{
+   _unimplemented(win, holder, "profiles");
+}
+
+static void
+_status_config_scrolling(Evas_Object *win, Evas_Object *holder)
+{
+   _unimplemented(win, holder, "scrolling");
+}
+
+static void
+_status_config_rendering(Evas_Object *win, Evas_Object *holder)
+{
+   _unimplemented(win, holder, "rendering");
+}
+
+static void
+_status_config_caches(Evas_Object *win, Evas_Object *holder)
+{
+   _unimplemented(win, holder, "caches");
+}
+
+static void
+_status_config_full(Evas_Object *win, Evas_Object *bx0)
+{
+   Evas_Object *tb, *holder, *fl;
+   Elm_Toolbar_Item *it;
+   
+   tb = elm_toolbar_add(win);
+   elm_toolbar_homogenous_set(tb, 0);
+   evas_object_size_hint_weight_set(tb, 1.0, 0.0);
+   evas_object_size_hint_align_set(tb, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   it = elm_toolbar_item_add(tb, NULL, "Sizing", _cf_sizing, win);
+   elm_toolbar_item_add(tb, NULL, "Theme", _cf_themes, win);
+   
+   elm_toolbar_item_add(tb, NULL, "Fonts", _cf_fonts, win);
+   elm_toolbar_item_add(tb, NULL, "Profiles", _cf_profiles, win);
+   elm_toolbar_item_add(tb, NULL, "Scrolling", _cf_scrolling, win);
+   elm_toolbar_item_add(tb, NULL, "Rendering", _cf_rendering, win);
+   elm_toolbar_item_add(tb, NULL, "Caches", _cf_caches, win);
+   elm_box_pack_end(bx0, tb);
+   evas_object_show(tb);
+   
+   holder = elm_table_add(win);
+   evas_object_size_hint_align_set(holder, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(holder, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx0, holder);
+   evas_object_show(holder);
+   evas_object_data_set(win, "holder", holder);
+   
+   _status_config_sizing(win, holder);
+   _status_config_themes(win, holder);
+   _status_config_fonts(win, holder);
+   _status_config_profiles(win, holder);
+   _status_config_rendering(win, holder);
+   _status_config_scrolling(win, holder);
+   _status_config_caches(win, holder);
+   
+   fl = elm_flip_add(win);
+   evas_object_size_hint_align_set(fl, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(fl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_table_pack(holder, fl, 0, 0, 1, 1);
+   evas_object_show(fl);
+   evas_object_data_set(win, "flip", fl);
+   
+   elm_toolbar_item_select(it);
+}
+
+static void
+status_win(void)
+{
+   Evas_Object *win, *bg, *bx0;
+
+   win = elm_win_add(NULL, "main", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Elementary Config");
+
+   evas_object_smart_callback_add(win, "delete,request", my_win_del, NULL);
+   bg = elm_bg_add(win);
+   evas_object_size_hint_weight_set(bg, 1.0, 1.0);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+
+   bx0 = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx0, 1.0, 1.0);
+   elm_win_resize_object_add(win, bx0);
+   evas_object_show(bx0);
+
+   if (!interactive) _status_basic(win, bx0);
+//   else _status_config(win, bx0);
+   else _status_config_full(win, bx0);
+   
+   evas_object_show(win);
+}
+
+static int
+_exit_timer(void *data)
+{
+   elm_exit();
+}
+
+/* this is your elementary main function - it MUSt be called IMMEDIATELY
+ * after elm_init() and MUSt be passed argc and argv, and MUST be called
+ * elm_main and not be static - must be a visible symbol with EAPI infront */
+EAPI int
+elm_main(int argc, char **argv)
+{
+   int i;
+   
+   for (i = 1; i < argc; i++)
+     {
+        if (!strcmp(argv[i], "-h"))
+          {
+             printf("Usage:\n"
+                    "  -h                This help\n"
+                    "  -q                Quiet mode (dont show window)\n"
+                    "  -t THEME          Set theme to THEME (ELM_THEME spec)\n"
+                    "  -f SIZE           Set finger size to SIZE pixels\n"
+                    "  -s SCALE          Set scale factor to SCALE\n"
+                    );
+          }
+        else if (!strcmp(argv[i], "-q"))
+          {
+             quiet = 1;
+             interactive = 0;
+          }
+        else if ((!strcmp(argv[i], "-t")) && (i < argc - 1))
+          {
+             i++;
+             theme_set = argv[i];
+             interactive = 0;
+          }
+        else if ((!strcmp(argv[i], "-f")) && (i < argc - 1))
+          {
+             i++;
+             finger_size_set = argv[i];
+             interactive = 0;
+          }
+        else if ((!strcmp(argv[i], "-s")) && (i < argc - 1))
+          {
+             i++;
+             scale_set = argv[i];
+             interactive = 0;
+          }
+     }
+   /* put ere any init specific to this app like parsing args etc. */
+   if (!quiet)
+     {
+        status_win(); /* create main window */
+        if (!interactive)
+          ecore_timer_add(2.0, _exit_timer, NULL);
+     }
+   if (!interactive)
+     {
+        if (theme_set)
+          {
+             elm_theme_all_set(theme_set);
+          }
+        if (finger_size_set)
+          {
+             elm_finger_size_all_set(atoi(finger_size_set));
+          }
+        if (scale_set)
+          {
+             elm_scale_all_set(atof(scale_set));
+          }
+        if (quiet)
+          {
+             elm_exit();
+          }
+     }
+   elm_run(); /* and run the program now  and handle all events etc. */
+   /* if the mainloop that elm_run() runs exist - we exit the app */
+   elm_shutdown(); /* clean up and shut down */
+   /* exit code */
+   return 0;
+}
+#endif
+/* all emeentary apps should use this. but it right after elm_main() */
+ELM_MAIN()
diff --git a/src/bin/quicklaunch.c b/src/bin/quicklaunch.c
new file mode 100644 (file)
index 0000000..512497e
--- /dev/null
@@ -0,0 +1,295 @@
+#include <Elementary.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+static double restart_time = 0.0;
+
+#define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
+
+static struct sigaction old_sigint;
+static struct sigaction old_sigterm;
+static struct sigaction old_sigquit;
+static struct sigaction old_sigalrm;
+static struct sigaction old_sigusr1;
+static struct sigaction old_sigusr2;
+static struct sigaction old_sighup;
+static struct sigaction old_sigchld;
+static struct sigaction old_sigsegv;
+static struct sigaction old_sigill;
+static struct sigaction old_sigfpe;
+static struct sigaction old_sigbus;
+static struct sigaction old_sigabrt;
+static int _log_dom = -1;
+
+#define CRITICAL(...) EINA_LOG_DOM_CRIT(_log_dom, __VA_ARGS__)
+#define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
+#define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__)
+#define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__)
+#define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
+
+static void
+post_fork(void *data)
+{
+   sigaction(SIGINT, &old_sigint, NULL);
+   sigaction(SIGTERM, &old_sigterm, NULL);
+   sigaction(SIGQUIT, &old_sigquit, NULL);
+   sigaction(SIGALRM, &old_sigalrm, NULL);
+   sigaction(SIGUSR1, &old_sigusr1, NULL);
+   sigaction(SIGUSR2, &old_sigusr2, NULL);
+   sigaction(SIGHUP, &old_sighup, NULL);
+   sigaction(SIGCHLD, &old_sigchld, NULL);
+   sigaction(SIGSEGV, &old_sigsegv, NULL);
+   sigaction(SIGILL, &old_sigill, NULL);
+   sigaction(SIGFPE, &old_sigfpe, NULL);
+   sigaction(SIGBUS, &old_sigbus, NULL);
+   sigaction(SIGABRT, &old_sigabrt, NULL);
+   if ((_log_dom > -1) && (_log_dom != EINA_LOG_DOMAIN_GLOBAL))
+     {
+       eina_log_domain_unregister(_log_dom);
+       _log_dom = -1;
+     }
+}
+
+static void
+child_handler(int x, siginfo_t *info, void *data)
+{
+   int status;
+   pid_t pid;
+
+   while ((pid = waitpid(-1, &status, WNOHANG)) > 0);
+}
+
+static void
+crash_handler(int x, siginfo_t *info, void *data)
+{
+   double t;
+
+   ERR("crash detected. restarting.");
+   t = ecore_time_get();
+   if ((t - restart_time) <= 2.0)
+     {
+       CRITICAL("crash too fast - less than 2 seconds. abort restart");
+       exit(-1);
+     }
+   ecore_app_restart();
+}
+
+static void
+handle_run(int fd, unsigned long bytes)
+{
+   unsigned char *buf = NULL;
+   int i, num;
+   char **argv = NULL;
+   char *cwd;
+   int argc;
+
+   buf = alloca(bytes);
+   if ((num = read(fd, buf, bytes)) < 0)
+     {
+       close(fd);
+       return;
+     }
+   close(fd);
+   argc = ((unsigned long *)(buf))[0];
+   argv = (char **)(&(((unsigned long *)(buf))[1]));
+   for (i = 0; i < argc; i++) argv[i] = (char *)(buf + (unsigned long)argv[i]);
+   cwd = argv[argc - 1] + strlen(argv[argc - 1]) + 1;
+   elm_quicklaunch_prepare(argc, argv);
+   elm_quicklaunch_fork(argc, argv, cwd, post_fork, NULL);
+   elm_quicklaunch_cleanup();
+}
+
+int
+main(int argc, char **argv)
+{
+   int sock, socket_unix_len;
+   struct stat st;
+   struct sockaddr_un socket_unix;
+   struct linger lin;
+   char buf[PATH_MAX];
+   struct sigaction action;
+
+   if (!eina_init())
+     {
+       fprintf(stderr, "ERROR: failed to init eina.");
+       exit(-1);
+     }
+   _log_dom = eina_log_domain_register
+     ("elementary_quicklaunch", EINA_COLOR_CYAN);
+   if (_log_dom < 0)
+     {
+       EINA_LOG_ERR("could not register elementary_quicklaunch log domain.");
+       _log_dom = EINA_LOG_DOMAIN_GLOBAL;
+     }
+
+   if (!getenv("DISPLAY"))
+     {
+       CRITICAL("DISPLAY env var not set");
+       exit(-1);
+     }
+   snprintf(buf, sizeof(buf), "/tmp/elm-ql-%i", getuid());
+   if (stat(buf, &st) < 0) mkdir(buf, S_IRUSR | S_IWUSR | S_IXUSR);
+   snprintf(buf, sizeof(buf), "/tmp/elm-ql-%i/%s", getuid(), getenv("DISPLAY"));
+   unlink(buf);
+   sock = socket(AF_UNIX, SOCK_STREAM, 0);
+   if (sock < 0)
+     {
+       CRITICAL("cannot create socket for socket for '%s': %s",
+                buf, strerror(errno));
+       exit(-1);
+     }
+   if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0)
+     {
+       CRITICAL("cannot set close on exec socket for '%s' (fd=%d): %s",
+                buf, sock, strerror(errno));
+       exit(-1);
+     }
+   lin.l_onoff = 1;
+   lin.l_linger = 0;
+   if (setsockopt(sock, SOL_SOCKET, SO_LINGER, &lin, sizeof(struct linger)) < 0)
+     {
+       CRITICAL("cannot set linger for socket for '%s' (fd=%d): %s",
+                buf, sock, strerror(errno));
+       exit(-1);
+     }
+   socket_unix.sun_family = AF_UNIX;
+   strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
+   socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
+   if (bind(sock, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
+     {
+       CRITICAL("cannot bind socket for '%s' (fd=%d): %s",
+                buf, sock, strerror(errno));
+       exit(-1);
+     }
+   if (listen(sock, 4096) < 0)
+     {
+       CRITICAL("listen(sock=%d, 4096): %s", sock, strerror(errno));
+       exit(-1);
+     }
+   elm_quicklaunch_init(argc, argv);
+   restart_time = ecore_time_get();
+
+   memset(&action, 0, sizeof(struct sigaction));
+   action.sa_handler = SIG_DFL;
+   action.sa_sigaction = NULL;
+   action.sa_flags = SA_RESTART | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGINT, &action, &old_sigint);
+
+   action.sa_handler = SIG_DFL;
+   action.sa_sigaction = NULL;
+   action.sa_flags = SA_RESTART | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGTERM, &action, &old_sigterm);
+
+   action.sa_handler = SIG_DFL;
+   action.sa_sigaction = NULL;
+   action.sa_flags = SA_RESTART | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGQUIT, &action, &old_sigquit);
+
+   action.sa_handler = SIG_DFL;
+   action.sa_sigaction = NULL;
+   action.sa_flags = SA_RESTART | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGALRM, &action, &old_sigalrm);
+
+   action.sa_handler = SIG_DFL;
+   action.sa_sigaction = NULL;
+   action.sa_flags = SA_RESTART | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGUSR1, &action, &old_sigusr1);
+
+   action.sa_handler = SIG_DFL;
+   action.sa_sigaction = NULL;
+   action.sa_flags = SA_RESTART | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGUSR2, &action, &old_sigusr2);
+
+   action.sa_handler = SIG_DFL;
+   action.sa_sigaction = NULL;
+   action.sa_flags = SA_RESTART | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGHUP, &action, &old_sighup);
+
+   action.sa_handler = NULL;
+   action.sa_sigaction = child_handler;
+   action.sa_flags = SA_RESTART | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGCHLD, &action, &old_sigchld);
+
+   action.sa_handler = NULL;
+   action.sa_sigaction = crash_handler;
+   action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGSEGV, &action, &old_sigsegv);
+
+   action.sa_handler = NULL;
+   action.sa_sigaction = crash_handler;
+   action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGILL, &action, &old_sigill);
+
+   action.sa_handler = NULL;
+   action.sa_sigaction = crash_handler;
+   action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGFPE, &action, &old_sigfpe);
+
+   action.sa_handler = NULL;
+   action.sa_sigaction = crash_handler;
+   action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGBUS, &action, &old_sigbus);
+
+   action.sa_handler = NULL;
+   action.sa_sigaction = crash_handler;
+   action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
+   sigemptyset(&action.sa_mask);
+   sigaction(SIGABRT, &action, &old_sigabrt);
+
+   for (;;)
+     {
+       int fd;
+       struct sockaddr_un client;
+       socklen_t len;
+
+       elm_quicklaunch_sub_init(argc, argv);
+       elm_quicklaunch_seed();
+       len = sizeof(struct sockaddr_un);
+       fd = accept(sock, (struct sockaddr *)&client, &len);
+       if (fd >= 0)
+         {
+            unsigned long bytes;
+            int num;
+
+            num = read(fd, &bytes, sizeof(unsigned long));
+            if (num == sizeof(unsigned long))
+              {
+                 ecore_app_args_set(argc, (const char **)argv);
+                 handle_run(fd, bytes);
+              }
+         }
+       elm_quicklaunch_sub_shutdown();
+     }
+   elm_quicklaunch_shutdown();
+
+   if ((_log_dom > -1) && (_log_dom != EINA_LOG_DOMAIN_GLOBAL))
+     {
+       eina_log_domain_unregister(_log_dom);
+       _log_dom = -1;
+     }
+   eina_shutdown();
+
+   return 0;
+}
diff --git a/src/bin/run.c b/src/bin/run.c
new file mode 100644 (file)
index 0000000..e43d145
--- /dev/null
@@ -0,0 +1,160 @@
+#include "elementary_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#endif
+
+#define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
+
+int
+main(int argc, char **argv)
+{
+   int sock, socket_unix_len, i;
+   struct sockaddr_un socket_unix;
+   char buf[PATH_MAX];
+   struct stat st;
+   char *exe;
+   int we_are_elementary_run = 0;
+   char *disp;
+   char *cwd;
+
+   int sargc, slen;
+   unsigned char *sbuf = NULL, *pos;
+   char **sargv = NULL;
+
+   if (!getcwd(buf, sizeof(buf) - 1))
+     {
+       fprintf(stderr, "elementary_quicklaunch: currect working dir too big.\n");
+       exit(-1);
+     }
+   cwd = strdup(buf);
+   if (!(disp = getenv("DISPLAY")))
+     {
+       fprintf(stderr, "elementary_quicklaunch: DISPLAY env var not set\n");
+       exit(-1);
+     }
+   snprintf(buf, sizeof(buf), "/tmp/elm-ql-%i/%s", getuid(), disp);
+   if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+     {
+       perror("elementary_quicklaunch: socket(AF_UNIX, SOCK_STREAM, 0)");
+       exit(-1);
+     }
+   socket_unix.sun_family = AF_UNIX;
+   strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
+   socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
+   if (connect(sock, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
+     {
+       perror("elementary_quicklaunch: connect(sock, (struct sockaddr *)&socket_unix, socket_unix_len)");
+       printf("elementary_quicklaunch: cannot connect to socket '%s'\n", buf);
+       exit(1);
+     }
+   exe = argv[0];
+   if (!(((exe[0] == '/')) ||
+        ((exe[0] == '.') && (exe[1] == '/')) ||
+        ((exe[0] == '.') && (exe[1] == '.') && (exe[2] == '/'))))
+     {
+       char *path = getenv("PATH");
+       int exelen = strlen(argv[0]);
+       if (path)
+         {
+            const char *p, *pp;
+
+            p = path;
+            pp = p;
+            exe = NULL;
+            for (;;)
+              {
+                 if ((*p == ':') || (*p == 0))
+                   {
+                      int len;
+
+                      len = p - pp;
+                      if (len < (sizeof(buf) - exelen - 3))
+                        {
+                           strncpy(buf, pp, len);
+                           strcpy(buf + len, "/");
+                           strcpy(buf + len + 1, argv[0]);
+                           if (access(buf, R_OK | X_OK) == 0)
+                             {
+                                exe = buf;
+                                break;
+                             }
+                           if (*p == 0) break;
+                           p++;
+                           pp = p;
+                        }
+                   }
+                 else
+                   {
+                      if (*p == 0) break;
+                      p++;
+                   }
+              }
+         }
+     }
+   if (exe)
+     {
+       if (lstat(exe, &st) == 0)
+         {
+            if (S_ISLNK(st.st_mode))
+              {
+                 char buf2[PATH_MAX];
+
+                 ssize_t len = readlink(exe, buf2, sizeof(buf2) - 1);
+                 if (len >= 0)
+                   {
+                      char *p;
+                      buf2[len] = 0;
+                      p = strrchr(buf2, '/');
+                      if (p) p++;
+                      else p = buf2;
+                      if (!strncasecmp(p, "elementary_run", 14))
+                        we_are_elementary_run = 1;
+                   }
+              }
+         }
+     }
+   if (we_are_elementary_run)
+     {
+       sargc = argc;
+       sargv = argv;
+     }
+   else
+     {
+       sargc = argc - 1;
+       sargv = &(argv[1]);
+     }
+   slen = sizeof(unsigned long) + sizeof(unsigned long);
+   for (i = 0; i < sargc; i++)
+     {
+       slen += sizeof(unsigned long);
+       slen += strlen(sargv[i]) + 1;
+     }
+   slen += strlen(cwd) + 1;
+   sbuf = alloca(slen);
+   ((unsigned long *)(sbuf))[0] = slen - sizeof(unsigned long);
+   ((unsigned long *)(sbuf))[1] = sargc;
+   pos = (unsigned char *)(&((((unsigned long *)(sbuf))[2 + sargc])));
+   for (i = 0; i < sargc; i++)
+     {
+       ((unsigned long *)(sbuf))[2 + i] =
+         (unsigned long)pos - ((unsigned long)sbuf + sizeof(unsigned long));
+       strcpy((char *)pos, sargv[i]);
+       pos += strlen(sargv[i]) + 1;
+     }
+   strcpy((char *)pos, cwd);
+   if (write(sock, sbuf, slen) < 0)
+     printf("elementary_quicklaunch: cannot write to socket '%s'\n", buf);
+   close(sock);
+   return 0;
+}
diff --git a/src/bin/test.c b/src/bin/test.c
new file mode 100644 (file)
index 0000000..7f166b5
--- /dev/null
@@ -0,0 +1,314 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+
+/* all tests prototypes */
+void test_bg_plain(void *data, Evas_Object *obj, void *event_info);
+void test_bg_image(void *data, Evas_Object *obj, void *event_info);
+void test_icon(void *data, Evas_Object *obj, void *event_info);
+void test_box_vert(void *data, Evas_Object *obj, void *event_info);
+void test_box_vert2(void *data, Evas_Object *obj, void *event_info);
+void test_box_horiz(void *data, Evas_Object *obj, void *event_info);
+void test_button(void *data, Evas_Object *obj, void *event_info);
+void test_fileselector_button(void *data, Evas_Object *obj, void *event_info);
+void test_toggle(void *data, Evas_Object *obj, void *event_info);
+void test_clock(void *data, Evas_Object *obj, void *event_info);
+void test_check(void *data, Evas_Object *obj, void *event_info);
+void test_radio(void *data, Evas_Object *obj, void *event_info);
+void test_layout(void *data, Evas_Object *obj, void *event_info);
+void test_hover(void *data, Evas_Object *obj, void *event_info);
+void test_hover2(void *data, Evas_Object *obj, void *event_info);
+void test_entry(void *data, Evas_Object *obj, void *event_info);
+void test_entry_scrolled(void *data, Evas_Object *obj, void *event_info);
+void test_entry3(void *data, Evas_Object *obj, void *event_info);
+void test_entry4(void *data, Evas_Object *obj, void *event_info);
+void test_entry5(void *data, Evas_Object *obj, void *event_info);
+void test_notepad(void *data, Evas_Object *obj, void *event_info);
+void test_anchorview(void *data, Evas_Object *obj, void *event_info);
+void test_anchorblock(void *data, Evas_Object *obj, void *event_info);
+void test_toolbar(void *data, Evas_Object *obj, void *event_info);
+void test_hoversel(void *data, Evas_Object *obj, void *event_info);
+void test_list(void *data, Evas_Object *obj, void *event_info);
+void test_list2(void *data, Evas_Object *obj, void *event_info);
+void test_list3(void *data, Evas_Object *obj, void *event_info);
+void test_carousel(void *data, Evas_Object *obj, void *event_info);
+void test_inwin(void *data, Evas_Object *obj, void *event_info);
+void test_inwin2(void *data, Evas_Object *obj, void *event_info);
+void test_scaling(void *data, Evas_Object *obj, void *event_info);
+void test_scaling2(void *data, Evas_Object *obj, void *event_info);
+void test_slider(void *data, Evas_Object *obj, void *event_info);
+void test_genlist(void *data, Evas_Object *obj, void *event_info);
+void test_genlist2(void *data, Evas_Object *obj, void *event_info);
+void test_genlist3(void *data, Evas_Object *obj, void *event_info);
+void test_genlist4(void *data, Evas_Object *obj, void *event_info);
+void test_genlist5(void *data, Evas_Object *obj, void *event_info);
+void test_genlist6(void *data, Evas_Object *obj, void *event_info);
+void test_table(void *data, Evas_Object *obj, void *event_info);
+void test_grid(void *data, Evas_Object *obj, void *event_info);
+void test_pager(void *data, Evas_Object *obj, void *event_info);
+void test_win_state(void *data, Evas_Object *obj, void *event_info);
+void test_win_state2(void *data, Evas_Object *obj, void *event_info);
+void test_progressbar(void *data, Evas_Object *obj, void *event_info);
+void test_fileselector(void *data, Evas_Object *obj, void *event_info);
+void test_separator(void *data, Evas_Object *obj, void *event_info);
+void test_scroller(void *data, Evas_Object *obj, void *event_info);
+void test_scroller2(void *data, Evas_Object *obj, void *event_info);
+void test_spinner(void *data, Evas_Object *obj, void *event_info);
+void test_index(void *data, Evas_Object *obj, void *event_info);
+void test_photocam(void *data, Evas_Object *obj, void *event_info);
+void test_photo(void *data, Evas_Object *obj, void *event_info);
+void test_thumb(void *data, Evas_Object *obj, void *event_info);
+void test_icon_desktops(void *data, Evas_Object *obj, void *event_info);
+void test_notify(void *data, Evas_Object *obj, void *event_info);
+void test_slideshow(void *data, Evas_Object *obj, void *event_info);
+void test_menu(void *data, Evas_Object *obj, void *event_info);
+void test_panel(void *data, Evas_Object *obj, void *event_info);
+void test_map(void *data, Evas_Object *obj, void *event_info);
+void test_weather(void *data, Evas_Object *obj, void *event_info);
+void test_flip(void *data, Evas_Object *obj, void *event_info);
+void test_flip2(void *data, Evas_Object *obj, void *event_info);
+void test_label(void *data, Evas_Object *obj, void *event_info);
+void test_conformant(void *data, Evas_Object *obj, void *event_info);
+void test_multi(void *data, Evas_Object *obj, void *event_info);
+void test_floating(void *data, Evas_Object *obj, void *event_info);
+void test_launcher(void *data, Evas_Object *obj, void *event_info);
+void test_launcher2(void *data, Evas_Object *obj, void *event_info);
+void test_anim(void *data, Evas_Object *obj, void *event_info);
+
+
+struct elm_test
+{
+   const char *name;
+   void (*cb)(void *, Evas_Object *, void *);
+};
+
+static int
+elm_test_sort(const void *pa, const void *pb)
+{
+   const struct elm_test *a = pa, *b = pb;
+   return strcasecmp(a->name, b->name);
+}
+
+static void
+elm_test_add(Eina_List **p_list, const char *name, void (*cb)(void *, Evas_Object *, void *))
+{
+   struct elm_test *t = malloc(sizeof(struct elm_test));
+   t->name = name;
+   t->cb = cb;
+   *p_list = eina_list_sorted_insert(*p_list, elm_test_sort, t);
+}
+
+static void
+my_win_del(void *data, Evas_Object *obj, void *event_info)
+{
+   /* called when my_win_main is requested to be deleted */
+   elm_exit(); /* exit the program's main loop that runs in elm_run() */
+}
+
+static void
+index_changed(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_list_item_show(event_info);
+}
+
+static void
+my_win_main(void)
+{
+   Evas_Object *win, *bg, *bx0, *lb, *li, *idx, *fr;
+   Eina_List *tests;
+
+   /* 1 create an elm window - it returns an evas object. this is a little
+    * special as the object lives in the canvas that is inside the window
+    * so what is returned is really inside the window, but as you manipulate
+    * the evas object returned - the window will respond. elm_win makes sure
+    * of that so you can blindly treat it like any other evas object
+    * pretty much, just as long as you know it has special significance */
+   /* the first parameter is a "parent" window - eg for a dialog you want to
+    * have a main window it is related to, here it is NULL meaning there
+    * is no parent. "main" is the name of the window - used by the window
+    * manager for identifying the window uniquely amongst all the windows
+    * within this application (and all instances of the application). the
+    * type is a basic window (the final parameter) */
+   win = elm_win_add(NULL, "main", ELM_WIN_BASIC);
+   /* set the title of the window - this is in the titlebar */
+   elm_win_title_set(win, "Elementary Tests");
+
+   /* set a callback on the window when "delete,request" is emitted as
+    * a callback. when this happens my_win_del() is called and the
+    * data pointer (first param) is passed the final param here (in this
+    * case it is NULL). This is how you can pass specific things to a
+    * callback like objects or data layered on top */
+   evas_object_smart_callback_add(win, "delete,request", my_win_del, NULL);
+
+   /* add a background to our window. this just uses the standard theme set
+    * background. without a backgorund, you could make a window seem
+    * transparent with elm_win_alpha_set(win, 1); for example. if you have
+    * a compositor running this will make the window able to be
+    * semi-transparent and any space not filled by object/widget pixels will
+    * be transparent or translucent based on alpha. if you do not have a
+    * comnpositor running this should fall back to using shaped windows
+    * (which have a mask). both these features will be slow and rely on
+    * a lot more resources, so only use it if you need it. */
+   bg = elm_bg_add(win);
+   /* set weight to 1.0 x 1.0 == expand in both x and y direction */
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   /* tell the window that this object is to be resized along with the window.
+    * also as a result this object will be one of several objects that
+    * controls the minimum/maximum size of the window */
+   elm_win_resize_object_add(win, bg);
+   /* and show the background */
+   evas_object_show(bg);
+
+   /* add a box layout widget to the window */
+   bx0 = elm_box_add(win);
+   /* allow base box (bx0) to expand in x and y */
+   evas_object_size_hint_weight_set(bx0, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   /* tell the window that the box affects window size and also will be
+    * resized when the window is */
+   elm_win_resize_object_add(win, bx0);
+   evas_object_show(bx0);
+
+   fr = elm_frame_add(win);
+   elm_frame_label_set(fr, "Information");
+   elm_box_pack_end(bx0, fr);
+   evas_object_show(fr);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb,
+                      "Please select a test from the list below<br>"
+                      "by clicking the test button to show the<br>"
+                      "test window.");
+   elm_frame_content_set(fr, lb);
+   evas_object_show(lb);
+
+   li = elm_list_add(win);
+   elm_list_always_select_mode_set(li, 1);
+   evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_fill_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx0, li);
+   evas_object_show(li);
+
+   idx = elm_index_add(win);
+   evas_object_smart_callback_add(idx, "delay,changed", index_changed, NULL);
+   evas_object_size_hint_weight_set(idx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, idx);
+   evas_object_show(idx);
+
+   tests = NULL;
+#define ADD_TEST(name_, cb_) elm_test_add(&tests, name_, cb_)
+   ADD_TEST("Bg Plain", test_bg_plain);
+   ADD_TEST("Bg Image", test_bg_image);
+   ADD_TEST("Icon Transparent", test_icon);
+   ADD_TEST("Box Vert", test_box_vert);
+   ADD_TEST("Box Vert 2", test_box_vert2);
+   ADD_TEST("Box Horiz", test_box_horiz);
+   ADD_TEST("Buttons", test_button);
+   ADD_TEST("File Selector Button", test_fileselector_button);
+   ADD_TEST("Toggles", test_toggle);
+   ADD_TEST("Table", test_table);
+   ADD_TEST("Clock", test_clock);
+   ADD_TEST("Layout", test_layout);
+   ADD_TEST("Hover", test_hover);
+   ADD_TEST("Hover 2", test_hover2);
+   ADD_TEST("Entry", test_entry);
+   ADD_TEST("Entry Scrolled", test_entry_scrolled);
+   ADD_TEST("Entry 3", test_entry3);
+   ADD_TEST("Entry 4", test_entry4);
+   ADD_TEST("Entry 5", test_entry5);
+   ADD_TEST("Notepad", test_notepad);
+   ADD_TEST("Anchorview", test_anchorview);
+   ADD_TEST("Anchorblock", test_anchorblock);
+   ADD_TEST("Toolbar", test_toolbar);
+   ADD_TEST("Hoversel", test_hoversel);
+   ADD_TEST("List", test_list);
+   ADD_TEST("List 2", test_list2);
+   ADD_TEST("List 3", test_list3);
+   ADD_TEST("Carousel", test_carousel);
+   ADD_TEST("Inwin", test_inwin);
+   ADD_TEST("Inwin 2", test_inwin2);
+   ADD_TEST("Scaling", test_scaling);
+   ADD_TEST("Scaling 2", test_scaling2);
+   ADD_TEST("Slider", test_slider);
+   ADD_TEST("Genlist", test_genlist);
+   ADD_TEST("Genlist 2", test_genlist2);
+   ADD_TEST("Genlist 3", test_genlist3);
+   ADD_TEST("Genlist 4", test_genlist4);
+   ADD_TEST("Genlist 5", test_genlist5);
+   ADD_TEST("Genlist Tree", test_genlist6);
+   ADD_TEST("Scrolled Grid", test_grid);
+   ADD_TEST("Checks", test_check);
+   ADD_TEST("Radios", test_radio);
+   ADD_TEST("Pager", test_pager);
+   ADD_TEST("Window States", test_win_state);
+   ADD_TEST("Window States 2", test_win_state2);
+   ADD_TEST("Progressbar", test_progressbar);
+   ADD_TEST("File Selector", test_fileselector);
+   ADD_TEST("Separator", test_separator);
+   ADD_TEST("Scroller", test_scroller);
+   ADD_TEST("Scroller 2", test_scroller2);
+   ADD_TEST("Spinner", test_spinner);
+   ADD_TEST("Index", test_index);
+   ADD_TEST("Photocam", test_photocam);
+   ADD_TEST("Photo", test_photo);
+   ADD_TEST("Thumb", test_thumb);
+   ADD_TEST("Icon Desktops", test_icon_desktops);
+   ADD_TEST("Notify", test_notify);
+   ADD_TEST("Slideshow", test_slideshow);
+   ADD_TEST("Menu", test_menu);
+   ADD_TEST("Panel", test_panel);
+   ADD_TEST("Map", test_map);
+   ADD_TEST("Weather", test_weather);
+   ADD_TEST("Flip", test_flip);
+   ADD_TEST("Flip 2", test_flip2);
+   ADD_TEST("Label", test_label);
+   ADD_TEST("Conformant", test_conformant);
+   ADD_TEST("Multi Touch", test_multi);
+   ADD_TEST("Floating Objects", test_floating);
+   ADD_TEST("Launcher", test_launcher);
+   ADD_TEST("Launcher 2", test_launcher2);
+   ADD_TEST("Animation", test_anim);
+#undef ADD_TEST
+
+   if (tests)
+     {
+       char last_letter = 0;
+       struct elm_test *t;
+       EINA_LIST_FREE(tests, t)
+         {
+            Elm_List_Item *it;
+            it = elm_list_item_append(li, t->name, NULL, NULL, t->cb, NULL);
+            if (last_letter != t->name[0])
+              {
+                 char letter[2] = {t->name[0], '\0'};
+                 elm_index_item_append(idx, letter, it);
+                 last_letter = t->name[0];
+              }
+            free(t);
+         }
+       elm_index_item_go(idx, 0);
+     }
+
+   elm_list_go(li);
+
+   /* set an initial window size */
+   evas_object_resize(win, 320, 480);
+   /* show the window */
+   evas_object_show(win);
+}
+
+/* this is your elementary main function - it MUSt be called IMMEDIATELY
+ * after elm_init() and MUSt be passed argc and argv, and MUST be called
+ * elm_main and not be static - must be a visible symbol with EAPI infront */
+EAPI int
+elm_main(int argc, char **argv)
+{
+   /* put ere any init specific to this app like parsing args etc. */
+   my_win_main(); /* create main window */
+   elm_run(); /* and run the program now  and handle all events etc. */
+   /* if the mainloop that elm_run() runs exist - we exit the app */
+   elm_shutdown(); /* clean up and shut down */
+   /* exit code */
+   return 0;
+}
+#endif
+/* all emeentary apps should use this. but it right after elm_main() */
+ELM_MAIN()
diff --git a/src/bin/test_anchorblock.c b/src/bin/test_anchorblock.c
new file mode 100644 (file)
index 0000000..44e5f5f
--- /dev/null
@@ -0,0 +1,230 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+static void
+my_anchorblock_bt(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *av = data;
+   elm_anchorblock_hover_end(av);
+}
+
+static void
+my_anchorblock_anchor(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *av = data;
+   Elm_Entry_Anchorblock_Info *ei = event_info;
+   Evas_Object *bt, *bx;
+
+   bt = elm_button_add(obj);
+   elm_button_label_set(bt, ei->name);
+   elm_hover_content_set(ei->hover, "middle", bt);
+   evas_object_show(bt);
+
+   // hints as to where we probably should put hover contents (buttons etc.).
+   if (ei->hover_top)
+     {
+       bx = elm_box_add(obj);
+       bt = elm_button_add(obj);
+       elm_button_label_set(bt, "Top 1");
+       elm_box_pack_end(bx, bt);
+       evas_object_smart_callback_add(bt, "clicked", my_anchorblock_bt, av);
+       evas_object_show(bt);
+       bt = elm_button_add(obj);
+       elm_button_label_set(bt, "Top 2");
+       elm_box_pack_end(bx, bt);
+       evas_object_smart_callback_add(bt, "clicked", my_anchorblock_bt, av);
+       evas_object_show(bt);
+       bt = elm_button_add(obj);
+       elm_button_label_set(bt, "Top 3");
+       elm_box_pack_end(bx, bt);
+       evas_object_smart_callback_add(bt, "clicked", my_anchorblock_bt, av);
+       evas_object_show(bt);
+       elm_hover_content_set(ei->hover, "top", bx);
+       evas_object_show(bx);
+     }
+   if (ei->hover_bottom)
+     {
+       bt = elm_button_add(obj);
+       elm_button_label_set(bt, "Bot");
+       elm_hover_content_set(ei->hover, "bottom", bt);
+       evas_object_smart_callback_add(bt, "clicked", my_anchorblock_bt, av);
+       evas_object_show(bt);
+     }
+   if (ei->hover_left)
+     {
+       bt = elm_button_add(obj);
+       elm_button_label_set(bt, "Left");
+       elm_hover_content_set(ei->hover, "left", bt);
+       evas_object_smart_callback_add(bt, "clicked", my_anchorblock_bt, av);
+       evas_object_show(bt);
+     }
+   if (ei->hover_right)
+     {
+       bt = elm_button_add(obj);
+       elm_button_label_set(bt, "Right");
+       elm_hover_content_set(ei->hover, "right", bt);
+       evas_object_smart_callback_add(bt, "clicked", my_anchorblock_bt, av);
+       evas_object_show(bt);
+     }
+}
+
+static void
+my_anchorblock_edge_left(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("left\n");
+}
+
+static void
+my_anchorblock_edge_right(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("right\n");
+}
+
+static void
+my_anchorblock_edge_top(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("top\n");
+}
+
+static void
+my_anchorblock_edge_bottom(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("bottom\n");
+}
+
+static void
+my_anchorblock_scroll(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Coord x, y, w, h, vw, vh;
+
+   elm_scroller_region_get(obj, &x, &y, &w, &h);
+   elm_scroller_child_size_get(obj, &vw, &vh);
+   printf("scroll %ix%i +%i+%i in %ix%i\n", w, h, x, y, vw, vh);
+}
+
+void
+test_anchorblock(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *av, *sc, *bx, *bb, *ic;
+   char buf[PATH_MAX];
+
+   win = elm_win_add(NULL, "anchorblock", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Anchorblock");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   sc = elm_scroller_add(win);
+   evas_object_size_hint_weight_set(sc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, sc);
+
+   evas_object_smart_callback_add(sc, "edge_left", my_anchorblock_edge_left, NULL);
+   evas_object_smart_callback_add(sc, "edge_right", my_anchorblock_edge_right, NULL);
+   evas_object_smart_callback_add(sc, "edge_top", my_anchorblock_edge_top, NULL);
+   evas_object_smart_callback_add(sc, "edge_bottom", my_anchorblock_edge_bottom, NULL);
+   evas_object_smart_callback_add(sc, "scroll", my_anchorblock_scroll, NULL);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+
+   bb = elm_bubble_add(win);
+   elm_bubble_label_set(bb, "Message 3");
+   elm_bubble_info_set(bb, "10:32 4/11/2008");
+   elm_bubble_icon_set(bb, ic);
+   evas_object_show(ic);
+   evas_object_size_hint_weight_set(bb, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bb, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   av = elm_anchorblock_add(win);
+   elm_anchorblock_hover_style_set(av, "popout");
+   elm_anchorblock_hover_parent_set(av, win);
+   elm_anchorblock_text_set(av,
+                          "Hi there. This is the most recent message in the "
+                          "list of messages. It has one <a href=tel:+614321234>+61 432 1234</a> "
+                          "(phone number) to click on.");
+   evas_object_smart_callback_add(av, "anchor,clicked", 
+                                  my_anchorblock_anchor, av);
+   elm_bubble_content_set(bb, av);
+   evas_object_show(av);
+   elm_box_pack_end(bx, bb);
+   evas_object_show(bb);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+
+   bb = elm_bubble_add(win);
+   elm_bubble_label_set(bb, "Message 2");
+   elm_bubble_info_set(bb, "7:16 27/10/2008");
+   elm_bubble_icon_set(bb, ic);
+   evas_object_show(ic);
+   evas_object_size_hint_weight_set(bb, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bb, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   av = elm_anchorblock_add(win);
+   elm_anchorblock_hover_style_set(av, "popout");
+   elm_anchorblock_hover_parent_set(av, win);
+   elm_anchorblock_text_set(av,
+                          "Hey what are you doing? This is the second last message "
+                          "Hi there. This is the most recent message in the "
+                          "list. It's a longer one so it can wrap more and "
+                          "contains a <a href=contact:john>John</a> contact "
+                          "link in it to test popups on links. The idea is that "
+                          "all SMS's are scanned for things that look like phone "
+                          "numbers or names that are in your contacts list, and "
+                          "if they are, they become clickable links that pop up "
+                          "a menus of obvious actions to perform on this piece "
+                          "of information. This of course can be later explicitly "
+                          "done by links maybe running local apps or even being "
+                          "web URL's too that launch the web browser and point it "
+                          "to that URL. <item relsize=16x16 vsize=full href=emoticon/omg></item>");
+   evas_object_smart_callback_add(av, "anchor,clicked", my_anchorblock_anchor, av);
+   elm_bubble_content_set(bb, av);
+   evas_object_show(av);
+   elm_box_pack_end(bx, bb);
+   evas_object_show(bb);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+
+   bb = elm_bubble_add(win);
+   elm_bubble_label_set(bb, "Message 1");
+   elm_bubble_info_set(bb, "20:47 18/6/2008");
+   elm_bubble_icon_set(bb, ic);
+   evas_object_show(ic);
+   evas_object_size_hint_weight_set(bb, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bb, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   av = elm_anchorblock_add(win);
+   elm_anchorblock_hover_style_set(av, "popout");
+   elm_anchorblock_hover_parent_set(av, win);
+   elm_anchorblock_text_set(av, "This is a short message. <item relsize=16x16 vsize=full href=emoticon/haha></item>");
+   evas_object_smart_callback_add(av, "anchor,clicked", 
+                                  my_anchorblock_anchor, av);
+   elm_bubble_content_set(bb, av);
+   evas_object_show(av);
+   elm_box_pack_end(bx, bb);
+   evas_object_show(bb);
+
+   elm_scroller_content_set(sc, bx);
+   evas_object_show(bx);
+   
+   evas_object_show(sc);
+
+   evas_object_resize(win, 320, 300);
+
+   elm_object_focus(win);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_anchorview.c b/src/bin/test_anchorview.c
new file mode 100644 (file)
index 0000000..690a448
--- /dev/null
@@ -0,0 +1,105 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+static void
+my_anchorview_bt(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *av = data;
+   elm_anchorview_hover_end(av);
+}
+
+static void
+my_anchorview_anchor(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *av = data;
+   Elm_Entry_Anchorview_Info *ei = event_info;
+   Evas_Object *bt, *bx;
+
+   bt = elm_button_add(obj);
+   elm_button_label_set(bt, ei->name);
+   elm_hover_content_set(ei->hover, "middle", bt);
+   evas_object_show(bt);
+
+   // hints as to where we probably should put hover contents (buttons etc.).
+   if (ei->hover_top)
+     {
+       bx = elm_box_add(obj);
+       bt = elm_button_add(obj);
+       elm_button_label_set(bt, "Top 1");
+       elm_box_pack_end(bx, bt);
+       evas_object_smart_callback_add(bt, "clicked", my_anchorview_bt, av);
+       evas_object_show(bt);
+       bt = elm_button_add(obj);
+       elm_button_label_set(bt, "Top 2");
+       elm_box_pack_end(bx, bt);
+       evas_object_smart_callback_add(bt, "clicked", my_anchorview_bt, av);
+       evas_object_show(bt);
+       bt = elm_button_add(obj);
+       elm_button_label_set(bt, "Top 3");
+       elm_box_pack_end(bx, bt);
+       evas_object_smart_callback_add(bt, "clicked", my_anchorview_bt, av);
+       evas_object_show(bt);
+       elm_hover_content_set(ei->hover, "top", bx);
+       evas_object_show(bx);
+     }
+   if (ei->hover_bottom)
+     {
+       bt = elm_button_add(obj);
+       elm_button_label_set(bt, "Bot");
+       elm_hover_content_set(ei->hover, "bottom", bt);
+       evas_object_smart_callback_add(bt, "clicked", my_anchorview_bt, av);
+       evas_object_show(bt);
+     }
+   if (ei->hover_left)
+     {
+       bt = elm_button_add(obj);
+       elm_button_label_set(bt, "Left");
+       elm_hover_content_set(ei->hover, "left", bt);
+       evas_object_smart_callback_add(bt, "clicked", my_anchorview_bt, av);
+       evas_object_show(bt);
+     }
+   if (ei->hover_right)
+     {
+       bt = elm_button_add(obj);
+       elm_button_label_set(bt, "Right");
+       elm_hover_content_set(ei->hover, "right", bt);
+       evas_object_smart_callback_add(bt, "clicked", my_anchorview_bt, av);
+       evas_object_show(bt);
+     }
+}
+
+void
+test_anchorview(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *av;
+
+   win = elm_win_add(NULL, "anchorview", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Anchorview");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   av = elm_anchorview_add(win);
+   elm_anchorview_hover_style_set(av, "popout");
+   elm_anchorview_hover_parent_set(av, win);
+   elm_anchorview_text_set(av,
+                      "This is an entry widget in this window that<br>"
+                      "uses markup <b>like this</> for styling and<br>"
+                      "formatting <em>like this</>, as well as<br>"
+                      "<a href=X><link>links in the text</></a>, so enter text<br>"
+                      "in here to edit it. By the way, links are<br>"
+                      "called <a href=anc-02>Anchors</a> so you will need<br>"
+                      "to refer to them this way. <item relsize=16x16 vsize=full href=emoticon/guilty-smile></item>");
+   evas_object_size_hint_weight_set(av, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_smart_callback_add(av, "anchor,clicked", my_anchorview_anchor, av);
+   elm_win_resize_object_add(win, av);
+   evas_object_show(av);
+
+   evas_object_resize(win, 320, 300);
+
+   elm_object_focus(win);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_anim.c b/src/bin/test_anim.c
new file mode 100644 (file)
index 0000000..42f220d
--- /dev/null
@@ -0,0 +1,110 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+
+static const char *names[] =
+{
+     "bub1", "sh1",
+     "bub2", "sh2",
+     "bub3", "sh3",
+};
+
+static void
+_del(void *data, Evas *evas, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win = data;
+   Ecore_Animator *ani = evas_object_data_get(win, "animator");
+   
+   ecore_animator_del(ani);
+}
+
+static int
+anim(void *data)
+{
+   Evas_Object *win = data;
+   Evas_Object *bub, *sh;
+   Evas_Coord x, y, w, h, vw, vh;
+   double t, xx, yy, zz, r, fac;
+   double lx, ly;
+   int i;
+   
+   evas_output_viewport_get(evas_object_evas_get(win), 0, 0, &vw, &vh);
+   r = 48;
+   t = ecore_loop_time_get();
+   fac = 2.0 / (double)((sizeof(names) / sizeof(char *) / 2));
+   evas_pointer_canvas_xy_get(evas_object_evas_get(win), &x, &y);
+   lx = x;
+   ly = y;
+   
+   for (i = 0; i < (sizeof(names) / sizeof(char *) / 2); i++)
+     {
+        bub = evas_object_data_get(win, names[i * 2]);
+        sh = evas_object_data_get(win, names[(i * 2) + 1]);
+        zz = (((2 + sin(t * 6 + (M_PI * (i * fac)))) / 3) * 64) * 2;
+        xx = (cos(t * 4 + (M_PI * (i * fac))) * r) * 2;
+        yy = (sin(t * 6 + (M_PI * (i * fac))) * r) * 2;
+        
+        w = zz;
+        h = zz;
+        x = (vw / 2) + xx - (w / 2);
+        y = (vh / 2) + yy - (h / 2);
+        
+        evas_object_move(bub, x, y);
+        evas_object_resize(bub, w, h);
+       
+        x = x - ((lx - (x + (w / 2))) / 4);
+        y = y - ((ly - (y + (h / 2))) / 4);
+        
+        evas_object_move(sh, x, y);
+        evas_object_resize(sh, w, h);
+     }
+   return 1;
+}
+
+void
+test_anim(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bub, *sh;
+   Ecore_Animator *ani;
+   char buf[PATH_MAX];
+   int i;
+   
+   win = elm_win_add(NULL, "animation", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Animation");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/rock_01.jpg", PACKAGE_DATA_DIR);
+   elm_bg_file_set(bg, buf, NULL);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+   
+   snprintf(buf, sizeof(buf), "%s/images/bubble_sh.png", PACKAGE_DATA_DIR);
+   for (i = 0; i < (sizeof(names) / sizeof(char *) / 2); i++)
+     {
+        sh = evas_object_image_filled_add(evas_object_evas_get(win));
+        evas_object_image_file_set(sh, buf, NULL);
+        evas_object_resize(sh, 64, 64);
+        evas_object_show(sh);
+        evas_object_data_set(win, names[(i * 2) + 1], sh);
+     }
+   
+   snprintf(buf, sizeof(buf), "%s/images/bubble.png", PACKAGE_DATA_DIR);
+    for (i = 0; i < (sizeof(names) / sizeof(char *) / 2); i++)
+     {
+        bub = evas_object_image_filled_add(evas_object_evas_get(win));
+        evas_object_image_file_set(bub, buf, NULL);
+        evas_object_resize(bub, 64, 64);
+        evas_object_show(bub);
+        evas_object_data_set(win, names[(i * 2)], bub);
+     }
+   
+   evas_object_resize(win, 480, 800);
+   evas_object_show(win);
+   
+   ani = ecore_animator_add(anim, win);
+   evas_object_data_set(win, "animator", ani);
+   
+   evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _del, win);
+}
+#endif
diff --git a/src/bin/test_bg.c b/src/bin/test_bg.c
new file mode 100644 (file)
index 0000000..764f92b
--- /dev/null
@@ -0,0 +1,55 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+void
+test_bg_plain(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg;
+
+   win = elm_win_add(NULL, "bg-plain", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Bg Plain");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   /* allow bg to expand in x & y */
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+
+   /* set size hints. a minimum size for the bg. this should propagate back
+    * to the window thus limiting its size based off the bg as the bg is one
+    * of the window's resize objects. */
+   evas_object_size_hint_min_set(bg, 160, 160);
+   /* and set a maximum size. not needed very often. normally used together
+    * with evas_object_size_hint_min_set() at the same size to make a
+    * window not resizable */
+   evas_object_size_hint_max_set(bg, 640, 640);
+   /* and now just resize the window to a size you want. normally widgets
+    * will determine the initial size though */
+   evas_object_resize(win, 320, 320);
+   /* and show the window */
+   evas_object_show(win);
+}
+
+void
+test_bg_image(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg;
+   char buf[PATH_MAX];
+
+   win = elm_win_add(NULL, "bg-image", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Bg Image");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/plant_01.jpg", PACKAGE_DATA_DIR);
+   elm_bg_file_set(bg, buf, NULL);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+
+   evas_object_size_hint_min_set(bg, 160, 160);
+   evas_object_size_hint_max_set(bg, 640, 640);
+   evas_object_resize(win, 320, 320);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_box.c b/src/bin/test_box.c
new file mode 100644 (file)
index 0000000..dc8c8a8
--- /dev/null
@@ -0,0 +1,168 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+void
+test_box_vert(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *ic;
+   char buf[PATH_MAX];
+
+   win = elm_win_add(NULL, "box-vert", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Box Vert");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   elm_win_resize_object_add(win, bx);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bx);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   evas_object_size_hint_align_set(ic, 0.5, 0.5);
+   elm_box_pack_end(bx, ic);
+   evas_object_show(ic);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   evas_object_size_hint_align_set(ic, 0.0, 0.5);
+   elm_box_pack_end(bx, ic);
+   evas_object_show(ic);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   evas_object_size_hint_align_set(ic, EVAS_HINT_EXPAND, 0.5);
+   elm_box_pack_end(bx, ic);
+   evas_object_show(ic);
+
+   evas_object_show(win);
+}
+
+static void
+_del_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_box_unpack(data, obj);
+   evas_object_move(obj, 0, 0);
+   evas_object_color_set(obj, 128, 64, 0, 128);
+//   evas_object_del(obj);
+}
+
+void
+test_box_vert2(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *bt;
+
+   win = elm_win_add(NULL, "box-vert2", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Box Vert 2");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   elm_win_resize_object_add(win, bx);
+   evas_object_size_hint_weight_set(bx, 0.0, 0.0);
+   evas_object_show(bx);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button 1");
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, 0.0, 0.0);
+   evas_object_smart_callback_add(bt, "clicked", _del_cb, bx);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button 2");
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, 0.0, 0.0);
+   evas_object_smart_callback_add(bt, "clicked", _del_cb, bx);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button 3");
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, 0.0, 0.0);
+   evas_object_smart_callback_add(bt, "clicked", _del_cb, bx);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button 4");
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, 0.0, 0.0);
+   evas_object_smart_callback_add(bt, "clicked", _del_cb, bx);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button 5");
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, 0.0, 0.0);
+   evas_object_smart_callback_add(bt, "clicked", _del_cb, bx);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   evas_object_show(win);
+}
+
+void
+test_box_horiz(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *ic;
+   char buf[PATH_MAX];
+
+   win = elm_win_add(NULL, "box-horiz", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Box Horiz");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   elm_box_horizontal_set(bx, 1);
+   elm_win_resize_object_add(win, bx);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bx);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   evas_object_size_hint_align_set(ic, 0.5, 0.5);
+   elm_box_pack_end(bx, ic);
+   evas_object_show(ic);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   evas_object_size_hint_align_set(ic, 0.5, 0.0);
+   elm_box_pack_end(bx, ic);
+   evas_object_show(ic);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   evas_object_size_hint_align_set(ic, 0.0, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx, ic);
+   evas_object_show(ic);
+
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_button.c b/src/bin/test_button.c
new file mode 100644 (file)
index 0000000..ea07666
--- /dev/null
@@ -0,0 +1,132 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+static void
+_bt_repeated(void *data, Evas_Object *obj, void *event_info)
+{
+       static int count;
+       char buf[16];
+
+       snprintf(buf, sizeof(buf), "count=%d", count++);
+       if (count >= 10000)
+               count = 0;
+       elm_button_label_set(obj, buf);
+}
+
+void
+test_button(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *ic, *bt;
+   char buf[PATH_MAX];
+
+   win = elm_win_add(NULL, "buttons", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Buttons");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Icon sized to button");
+   elm_button_icon_set(bt, ic);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+   evas_object_show(ic);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Icon no scale");
+   elm_button_icon_set(bt, ic);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+   evas_object_show(ic);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Disabled Button");
+   elm_button_icon_set(bt, ic);
+   elm_object_disabled_set(bt, 1);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+   evas_object_show(ic);
+   
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+   bt = elm_button_add(win);
+   elm_button_icon_set(bt, ic);
+   elm_object_disabled_set(bt, 1);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+   evas_object_show(ic);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Label Only");
+   elm_box_pack_end(bx, bt);
+   evas_object_smart_callback_add(bt, "repeated", _bt_repeated, NULL);
+   elm_button_autorepeat_set(bt, 1);
+   elm_button_autorepeat_initial_timeout_set(bt, 2.0);
+   elm_button_autorepeat_gap_timeout_set(bt, 0.5);
+   evas_object_show(bt);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   bt = elm_button_add(win);
+   elm_button_icon_set(bt, ic);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+   evas_object_show(ic);
+
+
+   bt = elm_button_add(win);
+   elm_object_style_set(bt, "anchor");
+   elm_button_label_set(bt, "Anchor style");
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+   bt = elm_button_add(win);
+   elm_object_style_set(bt, "anchor");
+   elm_button_icon_set(bt, ic);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+   evas_object_show(ic);
+
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+   bt = elm_button_add(win);
+   elm_object_style_set(bt, "anchor");
+   elm_button_icon_set(bt, ic);
+   elm_object_disabled_set(bt, 1);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+   evas_object_show(ic);
+   
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_carousel.c b/src/bin/test_carousel.c
new file mode 100644 (file)
index 0000000..1c09ff8
--- /dev/null
@@ -0,0 +1,20 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+void
+test_carousel(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg;
+
+   win = elm_win_add(NULL, "carousel", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Carousel");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   evas_object_resize(win, 320, 240);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_check.c b/src/bin/test_check.c
new file mode 100644 (file)
index 0000000..f553661
--- /dev/null
@@ -0,0 +1,80 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+void
+test_check(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *ic, *ck;
+   char buf[PATH_MAX];
+
+   win = elm_win_add(NULL, "check", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Checks");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+   ck = elm_check_add(win);
+   evas_object_size_hint_weight_set(ck, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ck, EVAS_HINT_FILL, 0.5);
+   elm_check_label_set(ck, "Icon sized to check");
+   elm_check_icon_set(ck, ic);
+   elm_check_state_set(ck, 1);
+   elm_box_pack_end(bx, ck);
+   evas_object_show(ck);
+   evas_object_show(ic);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   ck = elm_check_add(win);
+   elm_check_label_set(ck, "Icon no scale");
+   elm_check_icon_set(ck, ic);
+   elm_box_pack_end(bx, ck);
+   evas_object_show(ck);
+   evas_object_show(ic);
+
+   ck = elm_check_add(win);
+   elm_check_label_set(ck, "Label Only");
+   elm_box_pack_end(bx, ck);
+   evas_object_show(ck);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+   ck = elm_check_add(win);
+   evas_object_size_hint_weight_set(ck, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ck, EVAS_HINT_FILL, 0.5);
+   elm_check_label_set(ck, "Disabled check");
+   elm_check_icon_set(ck, ic);
+   elm_check_state_set(ck, 1);
+   elm_box_pack_end(bx, ck);
+   elm_object_disabled_set(ck, 1);
+   evas_object_show(ck);
+   evas_object_show(ic);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   ck = elm_check_add(win);
+   elm_check_icon_set(ck, ic);
+   elm_box_pack_end(bx, ck);
+   evas_object_show(ck);
+   evas_object_show(ic);
+
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_clock.c b/src/bin/test_clock.c
new file mode 100644 (file)
index 0000000..0f01d3b
--- /dev/null
@@ -0,0 +1,61 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+void
+test_clock(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *ck;
+   unsigned int digedit;
+
+   win = elm_win_add(NULL, "clock", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Clock");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   ck = elm_clock_add(win);
+   elm_box_pack_end(bx, ck);
+   evas_object_show(ck);
+
+   ck = elm_clock_add(win);
+   elm_clock_show_am_pm_set(ck, 1);
+   elm_box_pack_end(bx, ck);
+   evas_object_show(ck);
+
+   ck = elm_clock_add(win);
+   elm_clock_show_seconds_set(ck, 1);
+   elm_box_pack_end(bx, ck);
+   evas_object_show(ck);
+
+   ck = elm_clock_add(win);
+   elm_clock_show_seconds_set(ck, 1);
+   elm_clock_show_am_pm_set(ck, 1);
+   elm_box_pack_end(bx, ck);
+   evas_object_show(ck);
+
+   ck = elm_clock_add(win);
+   elm_clock_edit_set(ck, 1);
+   elm_clock_show_seconds_set(ck, 1);
+   elm_clock_show_am_pm_set(ck, 1);
+   elm_clock_time_set(ck, 10, 11, 12);
+   elm_box_pack_end(bx, ck);
+   evas_object_show(ck);
+
+   ck = elm_clock_add(win);
+   elm_clock_show_seconds_set(ck, 1);
+   elm_clock_edit_set(ck, 1);
+   digedit = ELM_CLOCK_HOUR_UNIT | ELM_CLOCK_MIN_UNIT | ELM_CLOCK_SEC_UNIT;
+   elm_clock_digit_edit_set(ck, digedit);
+   elm_box_pack_end(bx, ck);
+   evas_object_show(ck);
+
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_conform.c b/src/bin/test_conform.c
new file mode 100644 (file)
index 0000000..8e60281
--- /dev/null
@@ -0,0 +1,84 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+
+void 
+test_conformant(void *data, Evas_Object *obj, void *event) 
+{
+   Evas_Object *win, *bg, *conform, *btn, *bx, *en;
+
+   win = elm_win_add(NULL, "conformant", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Conformant");
+   elm_win_autodel_set(win, 1);
+   elm_win_conformant_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   conform = elm_conformant_add(win);
+   elm_win_resize_object_add(win, conform);
+   evas_object_size_hint_weight_set(conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(conform);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   
+   en = elm_scrolled_entry_add(win);
+   elm_scrolled_entry_single_line_set(en, 1);
+   elm_scrolled_entry_bounce_set(en, 1, 0);
+   elm_scrolled_entry_entry_set(en, "This is the top entry here");
+   evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(en, EVAS_HINT_FILL, 0.5);
+   evas_object_show(en);
+   elm_box_pack_end(bx, en);
+  
+   btn = elm_button_add(win);
+   elm_button_label_set(btn, "Test Conformant");
+   evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx, btn);
+   evas_object_show(btn);
+
+   en = elm_scrolled_entry_add(win);
+   elm_scrolled_entry_single_line_set(en, 1);
+   elm_scrolled_entry_bounce_set(en, 1, 0);
+   elm_scrolled_entry_entry_set(en, "This is the middle entry here");
+   evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(en, EVAS_HINT_FILL, 0.5);
+   evas_object_show(en);
+   elm_box_pack_end(bx, en);
+  
+   btn = elm_button_add(win);
+   elm_button_label_set(btn, "Test Conformant");
+   evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx, btn);
+   evas_object_show(btn);
+
+   en = elm_scrolled_entry_add(win);
+   elm_scrolled_entry_bounce_set(en, 0, 1);
+   elm_scrolled_entry_entry_set(en, 
+                       "This is a multi-line entry at the bottom<br>"
+                       "This can contain more than 1 line of text and be "
+                       "scrolled around to allow for entering of lots of "
+                       "content. It is also to test to see that autoscroll "
+                       "moves to the right part of a larger multi-line "
+                       "text entry that is inside of a scroller than can be "
+                       "scrolled around, thus changing the expected position "
+                       "as well as cursor changes updating auto-scroll when "
+                       "it is enabled.");
+   evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(en, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_show(en);
+   elm_box_pack_end(bx, en);
+  
+   elm_conformant_content_set(conform, bx);
+   evas_object_show(bx);
+   
+   evas_object_resize(win, 240, 240);
+   evas_object_show(win);
+}
+
+#endif
diff --git a/src/bin/test_entry.c b/src/bin/test_entry.c
new file mode 100644 (file)
index 0000000..8583b61
--- /dev/null
@@ -0,0 +1,1500 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+static void
+my_entry_bt_1(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_entry_entry_set(en, "");
+}
+
+static void
+my_entry_bt_2(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   const char *s = elm_entry_entry_get(en);
+   printf("ENTRY:\n");
+   if (s) printf("%s\n", s);
+   printf("ENTRY PLAIN UTF8:\n");
+   if (s)
+     {
+        s = elm_entry_markup_to_utf8(s);
+        if (s)
+          {
+             printf("%s\n", s);
+             free((char *)s);
+          }
+     }
+}
+
+static void
+my_entry_bt_3(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   const char *s = elm_entry_selection_get(en);
+   printf("SELECTION:\n");
+   if (s) printf("%s\n", s);
+   printf("SELECTION PLAIN UTF8:\n");
+   if (s)
+     {
+        s = elm_entry_markup_to_utf8(s);
+        if (s)
+          {
+             printf("%s\n", s);
+             free((char *)s);
+          }
+     }
+}
+
+static void
+my_entry_bt_4(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_entry_entry_insert(en, "Insert some <b>BOLD</> text");
+}
+
+void
+test_entry(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *bx2, *bt, *en;
+
+   win = elm_win_add(NULL, "entry", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Entry");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   en = elm_entry_add(win);
+   elm_entry_line_wrap_set(en, 0);
+   elm_entry_entry_set(en,
+                      "This is an entry widget in this window that<br>"
+                      "uses markup <b>like this</> for styling and<br>"
+                      "formatting <em>like this</>, as well as<br>"
+                      "<a href=X><link>links in the text</></a>, so enter text<br>"
+                      "in here to edit it. By the way, links are<br>"
+                      "called <a href=anc-02>Anchors</a> so you will need<br>"
+                      "to refer to them this way.<br>"
+                       "<br>"
+                       
+                       "Also you can stick in items with (relsize + ascent): "
+                       "<item relsize=16x16 vsize=ascent href=emoticon/evil-laugh></item>"
+                       " (full) "
+                       "<item relsize=16x16 vsize=full href=emoticon/guilty-smile></item>"
+                       " (to the left)<br>"
+                       
+                       "Also (size + ascent): "
+                       "<item size=16x16 vsize=ascent href=emoticon/haha></item>"
+                       " (full) "
+                       "<item size=16x16 vsize=full href=emoticon/happy-panting></item>"
+                       " (before this)<br>"
+                       
+                       "And as well (absize + ascent): "
+                       "<item absize=64x64 vsize=ascent href=emoticon/knowing-grin></item>"
+                       " (full) "
+                       "<item absize=64x64 vsize=full href=emoticon/not-impressed></item>"
+                       " ... end."
+                       );
+   evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(en, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx, en);
+   evas_object_show(en);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Clear");
+   evas_object_smart_callback_add(bt, "clicked", my_entry_bt_1, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Print");
+   evas_object_smart_callback_add(bt, "clicked", my_entry_bt_2, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Selection");
+   evas_object_smart_callback_add(bt, "clicked", my_entry_bt_3, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Insert");
+   evas_object_smart_callback_add(bt, "clicked", my_entry_bt_4, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   elm_object_focus(en);
+   evas_object_show(win);
+}
+
+static void
+my_scrolled_entry_bt_1(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_entry_set(en, "");
+}
+
+static void
+my_scrolled_entry_bt_2(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   const char *s = elm_scrolled_entry_entry_get(en);
+   printf("ENTRY:\n");
+   if (s) printf("%s\n", s);
+   printf("ENTRY PLAIN UTF8:\n");
+   if (s)
+     {
+        s = elm_entry_markup_to_utf8(s);
+        if (s)
+          {
+             printf("%s\n", s);
+             free((char *)s);
+          }
+     }
+}
+
+static void
+my_scrolled_entry_bt_3(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   const char *s = elm_scrolled_entry_selection_get(en);
+   printf("SELECTION:\n");
+   if (s) printf("%s\n", s);
+   printf("SELECTION PLAIN UTF8:\n");
+   if (s)
+     {
+        s = elm_entry_markup_to_utf8(s);
+        if (s)
+          {
+             printf("%s\n", s);
+             free((char *)s);
+          }
+     }
+}
+
+static void
+my_scrolled_entry_bt_4(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_entry_insert(en, "Insert some <b>BOLD</> text");
+}
+
+static void
+my_scrolled_entry_bt_5(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   const char *s = elm_scrolled_entry_entry_get(en);
+   printf("PASSWORD: '%s'\n", s ? s : "");
+}
+
+static void
+scrolled_anchor_test(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_entry_insert(en, "ANCHOR CLICKED");
+}
+
+void
+test_entry_scrolled(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *bx2, *bt, *en, *en_p, *sp;
+
+   win = elm_win_add(NULL, "entry-scrolled", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Entry Scrolled");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   /* disabled entry */
+   en = elm_scrolled_entry_add(win);
+   evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(en, EVAS_HINT_FILL, 0.5);
+   elm_scrolled_entry_scrollbar_policy_set(en, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
+   elm_scrolled_entry_entry_set(en, "Disabled entry");
+   elm_scrolled_entry_single_line_set(en, 1);
+   elm_object_disabled_set(en, 1);
+   evas_object_show(en);
+   elm_box_pack_end(bx, en);
+
+   /* password entry */
+   en = elm_scrolled_entry_add(win);
+   evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(en, EVAS_HINT_FILL, 0.5);
+   elm_scrolled_entry_scrollbar_policy_set(en, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
+   elm_scrolled_entry_password_set(en, 1);
+   elm_scrolled_entry_single_line_set(en, 1);
+   elm_scrolled_entry_entry_set(en, "Access denied, give up!");
+   elm_object_disabled_set(en, 1);
+   evas_object_show(en);
+   elm_box_pack_end(bx, en);
+
+   /* multi-line disable entry */
+   en = elm_scrolled_entry_add(win);
+   evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(en, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_scrolled_entry_scrollbar_policy_set(en, ELM_SCROLLER_POLICY_ON, ELM_SCROLLER_POLICY_ON);
+   elm_object_disabled_set(en, 1);
+   elm_scrolled_entry_context_menu_item_add(en, "Hello", NULL, ELM_ICON_NONE, NULL, NULL);
+   elm_scrolled_entry_context_menu_item_add(en, "World", NULL, ELM_ICON_NONE, NULL, NULL);
+   elm_scrolled_entry_entry_set(en,
+                               "Multi-line disabled entry widget :)<br>"
+                               "We can use markup <b>like this</> for styling and<br>"
+                               "formatting <em>like this</>, as well as<br>"
+                               "<a href=X><link>links in the text</></a>,"
+                               "but it won't be editable or clickable.");
+   evas_object_show(en);
+   elm_box_pack_end(bx, en);
+
+   sp = elm_separator_add(win);
+   elm_separator_horizontal_set(sp, 1);
+   elm_box_pack_end(bx, sp);
+   evas_object_show(sp);
+
+   /* Single line selected entry */
+   en = elm_scrolled_entry_add(win);
+   evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(en, EVAS_HINT_FILL, 0.5);
+   elm_scrolled_entry_scrollbar_policy_set(en, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
+   elm_scrolled_entry_entry_set(en, "This is a single line");
+   elm_scrolled_entry_single_line_set(en, 1);
+   elm_scrolled_entry_select_all(en);
+   evas_object_show(en);
+   elm_box_pack_end(bx, en);
+
+   /* Single line password entry */
+   en_p = elm_scrolled_entry_add(win);
+   evas_object_size_hint_weight_set(en_p, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(en_p, EVAS_HINT_FILL, 0.5);
+   elm_scrolled_entry_scrollbar_policy_set(en_p, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
+   elm_scrolled_entry_entry_set(en_p, "Password here");
+   elm_scrolled_entry_single_line_set(en_p, 1);
+   elm_scrolled_entry_password_set(en_p, 1);
+   evas_object_show(en_p);
+   elm_box_pack_end(bx, en_p);
+
+   /* markup scrolled entry */
+   en = elm_scrolled_entry_add(win);
+   evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(en, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_scrolled_entry_scrollbar_policy_set(en, ELM_SCROLLER_POLICY_ON, ELM_SCROLLER_POLICY_ON);
+   elm_scrolled_entry_entry_set(en,
+                               "This is an entry widget in this window that<br>"
+                               "uses markup <b>like this</> for styling and<br>"
+                               "formatting <em>like this</>, as well as<br>"
+                               "<a href=X><link>links in the text</></a>, so enter text<br>"
+                               "in here to edit it. By them way, links are<br>"
+                               "called <a href=anc-02>Anchors</a> so you will need<br>"
+                               "to refer to them this way. At the end here is a really long "
+                               "line to test line wrapping to see if it works. But just in "
+                               "case this line is not long enough I will add more here to "
+                               "really test it out, as Elementary really needs some "
+                               "good testing to see if entry widgets work as advertised.");
+   evas_object_smart_callback_add(en, "anchor,clicked", scrolled_anchor_test, en);
+   evas_object_show(en);
+   elm_box_pack_end(bx, en);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Clear");
+   evas_object_smart_callback_add(bt, "clicked", my_scrolled_entry_bt_1, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Print");
+   evas_object_smart_callback_add(bt, "clicked", my_scrolled_entry_bt_2, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Print pwd");
+   evas_object_smart_callback_add(bt, "clicked", my_scrolled_entry_bt_5, en_p);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Selection");
+   evas_object_smart_callback_add(bt, "clicked", my_scrolled_entry_bt_3, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Insert");
+   evas_object_smart_callback_add(bt, "clicked", my_scrolled_entry_bt_4, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   evas_object_resize(win, 320, 300);
+
+   elm_object_focus(win);
+   evas_object_show(win);
+}
+
+static void
+my_ent_bt_clr(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_entry_set(en, "");
+}
+
+static void
+my_ent_bt_pri(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   const char *s = elm_scrolled_entry_entry_get(en);
+   printf("ENTRY:\n");
+   if (s) printf("%s\n", s);
+   printf("ENTRY PLAIN UTF8:\n");
+   if (s)
+     {
+        s = elm_entry_markup_to_utf8(s);
+        if (s)
+          {
+             printf("%s\n", s);
+             free((char *)s);
+          }
+     }
+}
+
+static void
+my_ent_bt_sel(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   const char *s = elm_scrolled_entry_selection_get(en);
+   printf("SELECTION:\n");
+   if (s) printf("%s\n", s);
+   printf("SELECTION PLAIN UTF8:\n");
+   if (s)
+     {
+        s = elm_entry_markup_to_utf8(s);
+        if (s)
+          {
+             printf("%s\n", s);
+             free((char *)s);
+          }
+     }
+}
+
+static void
+my_ent_bt_all(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_select_all(en);
+}
+
+static void
+my_ent_bt_non(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_select_none(en);
+}
+
+static void
+my_ent_bt_ins(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_entry_insert(en, "Insert text");
+}
+
+static void
+my_ent_bt_lef(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_cursor_prev(en);
+}
+
+static void
+my_ent_bt_rig(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_cursor_next(en);
+}
+
+static void
+my_ent_bt_up_(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_cursor_up(en);
+}
+
+static void
+my_ent_bt_dow(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_cursor_down(en);
+}
+
+static void
+my_ent_bt_beg(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_cursor_begin_set(en);
+}
+
+static void
+my_ent_bt_end(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_cursor_end_set(en);
+}
+
+static void
+my_ent_bt_lbe(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_cursor_line_begin_set(en);
+}
+
+static void
+my_ent_bt_len(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_cursor_line_end_set(en);
+}
+
+static void
+my_ent_bt_sbe(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_cursor_selection_begin(en);
+}
+
+static void
+my_ent_bt_sen(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_cursor_selection_end(en);
+}
+
+static void
+my_ent_bt_fmt(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   printf("IS FORMAT: %i\n", 
+          (int)elm_scrolled_entry_cursor_is_format_get(en));
+}
+
+static void
+my_ent_bt_vfm(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   printf("IS VISIBLE FORMAT %i\n",
+          (int)elm_scrolled_entry_cursor_is_visible_format_get(en));
+}
+
+static void
+my_ent_bt_chr(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   printf("CHAR '%s'\n", elm_scrolled_entry_cursor_content_get(en));
+}
+
+static void
+my_ent_bt_cut(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_selection_cut(en);
+}
+
+static void
+my_ent_bt_cop(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_selection_copy(en);
+}
+
+static void
+my_ent_bt_pas(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *en = data;
+   elm_scrolled_entry_selection_paste(en);
+}
+
+void
+test_entry3(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *bx2, *bt, *en, *en_p, *sp;
+
+   win = elm_win_add(NULL, "entry3", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Entry 3");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   /* Single line selected entry */
+   en = elm_scrolled_entry_add(win);
+   evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(en, EVAS_HINT_FILL, 0.5);
+   elm_scrolled_entry_scrollbar_policy_set(en, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
+   elm_scrolled_entry_entry_set(en, "This is a single line");
+   elm_scrolled_entry_single_line_set(en, 1);
+   elm_box_pack_end(bx, en);
+   evas_object_show(en);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Clr");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_clr, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Pri");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_pri, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Sel");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_sel, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "All");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_all, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Non");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_non, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Ins");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_ins, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Lef");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_lef, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Rig");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_rig, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Up ");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_up_, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Dow");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_dow, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Beg");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_beg, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "End");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_end, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "LBe");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_lbe, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "LEn");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_len, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "SBe");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_sbe, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "SEn");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_sen, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Fmt");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_fmt, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "VFm");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_vfm, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Chr");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_chr, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Cut");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_cut, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Cop");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_cop, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Pas");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_pas, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   /* markup scrolled entry */
+   en = elm_scrolled_entry_add(win);
+   evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(en, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_scrolled_entry_entry_set(en,
+                               "This is an entry widget in this window that<br>"
+                               "uses markup <b>like this</> for styling and<br>"
+                               "formatting <em>like this</>, as well as<br>"
+                               "<a href=X><link>links in the text</></a>, so enter text<br>"
+                               "in here to edit it. By them way, links are<br>"
+                               "called <a href=anc-02>Anchors</a> so you will need<br>"
+                               "to refer to them this way. At the end here is a really long "
+                               "line to test line wrapping to see if it works. But just in "
+                               "case this line is not long enough I will add more here to "
+                               "really test it out, as Elementary really needs some "
+                               "good testing to see if entry widgets work as advertised."
+                                );
+   evas_object_smart_callback_add(en, "anchor,clicked", scrolled_anchor_test, en);
+   elm_box_pack_end(bx, en);
+   evas_object_show(en);
+   
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Clr");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_clr, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Pri");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_pri, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Sel");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_sel, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "All");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_all, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Non");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_non, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Ins");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_ins, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Lef");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_lef, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Rig");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_rig, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Up ");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_up_, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Dow");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_dow, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Beg");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_beg, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "End");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_end, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "LBe");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_lbe, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "LEn");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_len, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "SBe");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_sbe, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "SEn");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_sen, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Fmt");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_fmt, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "VFm");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_vfm, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Chr");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_chr, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Cut");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_cut, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Cop");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_cop, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Pas");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_pas, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt); 
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   evas_object_resize(win, 320, 480);
+
+   elm_object_focus(win);
+   evas_object_show(win);
+}
+
+void
+test_entry4(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *ly, *en;
+   char buf[PATH_MAX];
+   
+   win = elm_win_add(NULL, "entry4", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Entry 4");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   ly = elm_layout_add(win);
+   snprintf(buf, sizeof(buf), "%s/objects/test.edj", PACKAGE_DATA_DIR);
+   elm_layout_file_set(ly, buf, "layout");
+   evas_object_size_hint_weight_set(ly, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, ly);
+   evas_object_show(ly);
+   
+   en = elm_scrolled_entry_add(win);
+   evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(en, EVAS_HINT_FILL, 0.5);
+   elm_scrolled_entry_scrollbar_policy_set(en, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
+   elm_scrolled_entry_entry_set(en, "This is a single line");
+   elm_scrolled_entry_single_line_set(en, 1);
+   elm_layout_content_set(ly, "element1", en);
+   evas_object_show(en);
+   
+   en = elm_entry_add(win);
+   elm_entry_line_wrap_set(en, 0);
+   elm_entry_entry_set(en,
+                      "This is an entry widget<br>"
+                      "that uses markup<br>"
+                       "<b>like this</> and has<br>"
+                      "no scroller, so you can<br>"
+                      "use it more flexibly.");
+   evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(en, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_layout_content_set(ly, "element2", en);
+   evas_object_show(en);
+
+   en = elm_scrolled_entry_add(win);
+   evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(en, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_scrolled_entry_entry_set(en,
+                               "This is an entry widget in this window that<br>"
+                               "uses markup <b>like this</> for styling and<br>"
+                               "formatting <em>like this</>, as well as<br>"
+                               "<a href=X><link>links in the text</></a>, so enter text<br>"
+                               "in here to edit it. By them way, links are<br>"
+                               "called <a href=anc-02>Anchors</a> so you will need<br>"
+                               "to refer to them this way. At the end here is a really long "
+                               "line to test line wrapping to see if it works. But just in "
+                               "case this line is not long enough I will add more here to "
+                               "really test it out, as Elementary really needs some "
+                               "good testing to see if entry widgets work as advertised."
+                                );
+   evas_object_smart_callback_add(en, "anchor,clicked", scrolled_anchor_test, en);
+   elm_layout_content_set(ly, "element3", en);
+   evas_object_show(en);
+
+   evas_object_show(win);
+}
+
+void
+test_entry5(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *bx2, *bt, *en, *en_p, *sp;
+
+   win = elm_win_add(NULL, "entry5", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Entry 5");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   en = elm_scrolled_entry_add(win);
+   elm_scrolled_entry_line_char_wrap_set(en, 1);
+   evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(en, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_scrolled_entry_entry_set(en,
+                               "This is an entry widget in this window that "
+                               "uses markup like this for styling and "
+                               "formatting like this, as well as "
+                               "to refer to them this way. At the end here is a really long "
+                               "line to test line wrapping to see if it works. But just in "
+                               "case this line is not long enough I will add more here to "
+                               "really test it out, as Elementary really needs some "
+                               "good testing to see if entry widgets work as advertised."
+                                );
+   evas_object_smart_callback_add(en, "anchor,clicked", scrolled_anchor_test, en);
+   elm_box_pack_end(bx, en);
+   evas_object_show(en);
+   
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Clr");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_clr, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Pri");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_pri, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Sel");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_sel, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "All");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_all, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Non");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_non, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Ins");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_ins, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Lef");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_lef, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Rig");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_rig, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Up ");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_up_, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Dow");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_dow, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Beg");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_beg, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "End");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_end, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "LBe");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_lbe, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "LEn");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_len, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "SBe");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_sbe, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "SEn");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_sen, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Fmt");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_fmt, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "VFm");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_vfm, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Chr");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_chr, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Cut");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_cut, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Cop");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_cop, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Pas");
+   evas_object_smart_callback_add(bt, "clicked", my_ent_bt_pas, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt); 
+   evas_object_propagate_events_set(bt, 0);
+   elm_object_focus_allow_set(bt, 0);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   evas_object_resize(win, 320, 480);
+
+   elm_object_focus(win);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_fileselector.c b/src/bin/test_fileselector.c
new file mode 100644 (file)
index 0000000..e5192c4
--- /dev/null
@@ -0,0 +1,109 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+static void
+my_fileselector_done(void *data, Evas_Object *obj, void *event_info)
+{
+   /* event_info conatin the full path of the selected file
+    * or NULL if none is selected or cancel is pressed */
+   const char *selected = event_info;
+
+   if (selected)
+     printf("Selected file: %s\n", selected);
+   else
+     evas_object_del(data); /* delete the test window */
+}
+
+static void
+my_fileselector_selected(void *data, Evas_Object *obj, void *event_info)
+{
+   /* event_info conatin the full path of the selected file */
+   const char *selected = event_info;
+   printf("Selected file: %s\n", selected);
+
+   /* or you can query the selection */
+   printf("or: %s\n", elm_fileselector_selected_get(obj));
+}
+
+static void
+_is_save_clicked(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *fs = data;
+   printf("Toggle Is save\n");
+   if (elm_fileselector_is_save_get(fs))
+      elm_fileselector_is_save_set(fs, EINA_FALSE);
+   else
+      elm_fileselector_is_save_set(fs, EINA_TRUE);
+}
+
+static void
+_sel_get_clicked(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *fs = data;
+   printf("Get Selected: %s\n", elm_fileselector_selected_get(fs));
+}
+
+void
+test_fileselector(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *fs, *bg, *vbox, *hbox, *bt;
+
+   /* Set the locale according to the system pref.
+    * If you dont do so the file selector will order the files list in
+    * a case sensitive manner
+    */
+   setlocale(LC_ALL, "");
+
+   win = elm_win_add(NULL, "fileselector", ELM_WIN_BASIC);
+   elm_win_title_set(win, "File Selector");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   vbox = elm_box_add(win);
+   elm_win_resize_object_add(win, vbox);
+   evas_object_size_hint_weight_set(vbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(vbox);
+
+   fs = elm_fileselector_add(win);
+   /* enable the fs file name entry */
+   elm_fileselector_is_save_set(fs, EINA_TRUE);
+   /* make the file list a tree with dir expandable in place */
+   elm_fileselector_expandable_set(fs, EINA_FALSE);
+   /* start the fileselector in the home dir */
+   elm_fileselector_path_set(fs, getenv("HOME"));
+   /* allow fs to expand in x & y */
+   evas_object_size_hint_weight_set(fs, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(fs, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(vbox, fs);
+   evas_object_show(fs); // TODO fix this is the widget
+   
+   /* the 'done' cb is called when the user press ok/cancel */
+   evas_object_smart_callback_add(fs, "done", my_fileselector_done, win);
+   /* the 'selected' cb is called when the user click on a file/dir */
+   evas_object_smart_callback_add(fs, "selected", my_fileselector_selected, win);
+   
+   /* test buttons */
+   hbox = elm_box_add(win);
+   elm_box_horizontal_set(hbox, EINA_TRUE);
+   elm_box_pack_end(vbox, hbox);
+   evas_object_show(hbox);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Toggle is_save");
+   evas_object_smart_callback_add(bt, "clicked", _is_save_clicked, fs);
+   elm_box_pack_end(hbox, bt);
+   evas_object_show(bt);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "sel get");
+   evas_object_smart_callback_add(bt, "clicked", _sel_get_clicked, fs);
+   elm_box_pack_end(hbox, bt);
+   evas_object_show(bt);
+
+   evas_object_resize(win, 240, 350);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_fileselector_button.c b/src/bin/test_fileselector_button.c
new file mode 100644 (file)
index 0000000..ff1d643
--- /dev/null
@@ -0,0 +1,132 @@
+#include <Elementary.h>
+
+#ifndef ELM_LIB_QUICKLAUNCH
+static void
+_file_chosen(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *entry = data;
+   char *file = event_info;
+   elm_entry_entry_set(entry, file);
+   printf("File chosen: %s\n", file);
+}
+
+static void
+_inwin_mode_toggle(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *fs_bt = data;
+   Eina_Bool value = elm_fileselector_button_inwin_mode_get(fs_bt);
+   elm_fileselector_button_inwin_mode_set(fs_bt, !value);
+   printf("Inwin mode set to: %s\n", value ? "false" : "true");
+}
+
+static void
+_current_sel_toggle(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *fs_bt = data;
+   Eina_Bool value = elm_fileselector_button_folder_only_get(fs_bt);
+   elm_fileselector_button_folder_only_set(fs_bt, !value);
+   printf("Current selection entry display set to: %s\n",
+         value ? "false" : "true");
+}
+
+static void
+_folder_only_toggle(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *fs_bt = data;
+   Eina_Bool value = elm_fileselector_button_folder_only_get(fs_bt);
+   elm_fileselector_button_folder_only_set(fs_bt, !value);
+   printf("Folder only flag set to: %s\n", value ? "false" : "true");
+}
+
+static void
+_expandable_toggle(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *fs_bt = data;
+   Eina_Bool value = elm_fileselector_button_expandable_get(fs_bt);
+   elm_fileselector_button_expandable_set(fs_bt, !value);
+   printf("Expandable flag set to: %s\n", value ? "false" : "true");
+}
+
+void
+test_fileselector_button(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *vbox, *hbox, *ic, *bt, *fs_bt, *en, *lb;
+
+   win = elm_win_add(NULL, "fileselector button", ELM_WIN_BASIC);
+   elm_win_title_set(win, "File Selector Button");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   vbox = elm_box_add(win);
+   elm_win_resize_object_add(win, vbox);
+   evas_object_size_hint_weight_set(vbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(vbox);
+
+   vbox = elm_box_add(win);
+   evas_object_size_hint_weight_set(vbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, vbox);
+   evas_object_show(vbox);
+
+   /* file selector button */
+   ic = elm_icon_add(win);
+   elm_icon_standard_set(ic, "file");
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+   fs_bt = elm_fileselector_button_add(win);
+   elm_fileselector_button_label_set(fs_bt, "Select a file");
+   elm_fileselector_button_icon_set(fs_bt, ic);
+   elm_fileselector_button_inwin_mode_set(fs_bt, EINA_TRUE);
+
+   elm_box_pack_end(vbox, fs_bt);
+   evas_object_show(fs_bt);
+   evas_object_show(ic);
+
+   /* attribute setting buttons */
+   hbox = elm_box_add(win);
+   elm_box_horizontal_set(hbox, EINA_TRUE);
+   elm_box_pack_end(vbox, hbox);
+   evas_object_show(hbox);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Toggle current selection text entry");
+   evas_object_smart_callback_add(bt, "clicked", _current_sel_toggle, fs_bt);
+   elm_box_pack_end(hbox, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Toggle inwin mode");
+   evas_object_smart_callback_add(bt, "clicked", _inwin_mode_toggle, fs_bt);
+   elm_box_pack_end(hbox, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Toggle folder only mode");
+   evas_object_smart_callback_add(bt, "clicked", _folder_only_toggle, fs_bt);
+   elm_box_pack_end(hbox, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Toggle expandable mode");
+   evas_object_smart_callback_add(bt, "clicked", _expandable_toggle, fs_bt);
+   elm_box_pack_end(hbox, bt);
+   evas_object_show(bt);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb, "Last selection:");
+   elm_box_pack_end(vbox, lb);
+   evas_object_show(lb);
+
+   en = elm_entry_add(win);
+   elm_entry_line_wrap_set(en, EINA_FALSE);
+   elm_entry_editable_set(en, EINA_FALSE);
+   evas_object_smart_callback_add(fs_bt, "file,chosen", _file_chosen, en);
+   elm_box_pack_end(vbox, en);
+   evas_object_show(en);
+
+   evas_object_resize(win, 400, 400);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_flip.c b/src/bin/test_flip.c
new file mode 100644 (file)
index 0000000..42eee41
--- /dev/null
@@ -0,0 +1,274 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+
+void
+my_fl_1(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *fl = data;
+   elm_flip_go(fl, ELM_FLIP_ROTATE_Y_CENTER_AXIS);
+}
+
+void
+my_fl_2(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *fl = data;
+   elm_flip_go(fl, ELM_FLIP_ROTATE_X_CENTER_AXIS);
+}
+
+void
+my_fl_3(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *fl = data;
+   elm_flip_go(fl, ELM_FLIP_ROTATE_XZ_CENTER_AXIS);
+}
+
+void
+my_fl_4(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *fl = data;
+   elm_flip_go(fl, ELM_FLIP_ROTATE_YZ_CENTER_AXIS);
+}
+
+void
+test_flip(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *bx2, *fl, *o, *bt, *ly;
+   char buf[PATH_MAX];
+   
+   win = elm_win_add(NULL, "flip", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Flip");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+   
+   fl = elm_flip_add(win);
+   evas_object_size_hint_align_set(fl, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(fl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx, fl);
+
+   o = elm_bg_add(win);
+   evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   snprintf(buf, sizeof(buf), "%s/images/%s", PACKAGE_DATA_DIR, "sky_01.jpg");
+   elm_bg_file_set(o, buf, NULL);
+   elm_flip_content_front_set(fl, o);
+   evas_object_show(o);
+   
+   ly = elm_layout_add(win);
+   snprintf(buf, sizeof(buf), "%s/objects/test.edj", PACKAGE_DATA_DIR);
+   elm_layout_file_set(ly, buf, "layout");
+   evas_object_size_hint_align_set(ly, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(ly, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_flip_content_back_set(fl, ly);
+   evas_object_show(ly);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button 1");
+   elm_layout_content_set(ly, "element1", bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button 2");
+   elm_layout_content_set(ly, "element2", bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button 3");
+   elm_layout_content_set(ly, "element3", bt);
+   evas_object_show(bt);
+
+   evas_object_show(fl);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "1");
+   evas_object_smart_callback_add(bt, "clicked", my_fl_1, fl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "2");
+   evas_object_smart_callback_add(bt, "clicked", my_fl_2, fl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "3");
+   evas_object_smart_callback_add(bt, "clicked", my_fl_3, fl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "4");
+   evas_object_smart_callback_add(bt, "clicked", my_fl_4, fl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+   
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   evas_object_resize(win, 320, 480);
+   evas_object_show(win);
+}
+
+void
+test_flip2(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *bx2, *fl, *o, *bt, *tb, *ic, *li;
+   char buf[PATH_MAX];
+   
+   win = elm_win_add(NULL, "flip2", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Flip 2");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/%s", PACKAGE_DATA_DIR, "sky_01.jpg");
+   elm_bg_file_set(bg, buf, NULL);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+   
+   fl = elm_flip_add(win);
+   evas_object_size_hint_align_set(fl, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(fl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx, fl);
+
+   o = elm_box_add(win);
+   evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   
+   tb = elm_toolbar_add(win);
+   elm_toolbar_homogenous_set(tb, 0);
+   evas_object_size_hint_weight_set(tb, 0.0, 0.0);
+   evas_object_size_hint_align_set(tb, EVAS_HINT_FILL, 0.0);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_toolbar_item_add(tb, ic, "Hello", NULL, NULL);
+   
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_toolbar_item_add(tb, ic, "Out", NULL, NULL);
+   
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_toolbar_item_add(tb, ic, "There", NULL, NULL);
+   
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_toolbar_item_add(tb, ic, "World", NULL, NULL);
+   
+   elm_box_pack_end(o, tb);
+   evas_object_show(tb);
+   
+   li = elm_list_add(win);
+   evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   
+   elm_list_item_append(li, "This is a list", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "Second item", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "3rd", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "Fourth", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "Number five is alive!", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "The quick brown fox jumps over the lazy dog", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "Booyah", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "And another item", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "More of them", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "Get with it", NULL, NULL,  NULL, NULL);
+   
+   elm_list_go(li);
+   
+   elm_box_pack_end(o, li);
+   evas_object_show(li);
+   
+   elm_flip_content_front_set(fl, o);
+   evas_object_show(o);
+   
+   li = elm_list_add(win);
+   evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   
+   elm_list_item_append(li, "This is a list", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "Second item", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "3rd", NULL, NULL,  NULL, NULL);
+   
+   elm_list_go(li);
+   
+   elm_flip_content_back_set(fl, li);
+   evas_object_show(li);
+
+   evas_object_show(fl);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "1");
+   evas_object_smart_callback_add(bt, "clicked", my_fl_1, fl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "2");
+   evas_object_smart_callback_add(bt, "clicked", my_fl_2, fl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "3");
+   evas_object_smart_callback_add(bt, "clicked", my_fl_3, fl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "4");
+   evas_object_smart_callback_add(bt, "clicked", my_fl_4, fl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+   
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   evas_object_resize(win, 320, 480);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_floating.c b/src/bin/test_floating.c
new file mode 100644 (file)
index 0000000..28abf34
--- /dev/null
@@ -0,0 +1,107 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+typedef struct _Testitem
+{
+   Elm_Genlist_Item *item;
+   int mode;
+   int onoff;
+} Testitem;
+
+
+static Elm_Genlist_Item_Class itc1;
+static char *glf_label_get(const void *data, Evas_Object *obj, const char *part)
+{
+   char buf[256];
+   snprintf(buf, sizeof(buf), "Item # %i", (int)data);
+   return strdup(buf);
+}
+
+static Evas_Object *glf_icon_get(const void *data, Evas_Object *obj, const char *part)
+{
+   char buf[PATH_MAX];
+   Evas_Object *ic = elm_icon_add(obj);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+   return ic;
+}
+static Eina_Bool glf_state_get(const void *data, Evas_Object *obj, const char *part)
+{
+   return EINA_FALSE;
+}
+static void glf_del(const void *data, Evas_Object *obj)
+{
+}
+
+static void
+gl_sel(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("sel item data [%p] on genlist obj [%p], item pointer [%p]\n", data, obj, event_info);
+}
+
+static int
+anim(void *data)
+{
+   Evas_Object *gl = data;
+   Evas_Coord x, y;
+   
+   y = 0;
+   x = (sin(ecore_loop_time_get()) * 500);
+   evas_object_move(gl, x, y);
+   return 1;
+}
+
+static void
+_del(void *data, Evas *evas, Evas_Object *obj, void *event_info)
+{
+   Ecore_Animator *ani = data;
+   
+   ecore_animator_del(ani);
+}
+
+void
+test_floating(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *gl;
+   Elm_Genlist_Item *gli;
+   int i;
+   Ecore_Animator *ani;
+
+   win = elm_win_add(NULL, "floating", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Floaating");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   gl = elm_genlist_add(win);
+   evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_move(gl, 800, 0);
+   evas_object_resize(gl, 480, 800);
+   evas_object_show(gl);
+
+   itc1.item_style     = "default";
+   itc1.func.label_get = glf_label_get;
+   itc1.func.icon_get  = glf_icon_get;
+   itc1.func.state_get = glf_state_get;
+   itc1.func.del       = glf_del;
+
+   for (i = 0; i < 20; i++)
+     {
+        gli = elm_genlist_item_append(gl, &itc1,
+                                      (void *)i/* item data */,
+                                      NULL/* parent */,
+                                      ELM_GENLIST_ITEM_NONE,
+                                      gl_sel/* func */,
+                                      (void *)(i * 10)/* func data */);
+     }
+   evas_object_resize(win, 480, 800);
+   evas_object_show(win);
+   
+   ani = ecore_animator_add(anim, gl);
+   evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _del, ani);
+}
+#endif
diff --git a/src/bin/test_genlist.c b/src/bin/test_genlist.c
new file mode 100644 (file)
index 0000000..4f783c4
--- /dev/null
@@ -0,0 +1,1162 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+typedef struct _Testitem
+{
+   Elm_Genlist_Item *item;
+   int mode;
+   int onoff;
+} Testitem;
+
+
+static Elm_Genlist_Item_Class itc1;
+char *gl_label_get(const void *data, Evas_Object *obj, const char *part)
+{
+   char buf[256];
+   snprintf(buf, sizeof(buf), "Item # %i", (int)data);
+   return strdup(buf);
+}
+
+Evas_Object *gl_icon_get(const void *data, Evas_Object *obj, const char *part)
+{
+   char buf[PATH_MAX];
+   Evas_Object *ic = elm_icon_add(obj);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+   return ic;
+}
+Eina_Bool gl_state_get(const void *data, Evas_Object *obj, const char *part)
+{
+   return EINA_FALSE;
+}
+void gl_del(const void *data, Evas_Object *obj)
+{
+}
+
+static void
+gl_sel(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("sel item data [%p] on genlist obj [%p], item pointer [%p]\n", data, obj, event_info);
+}
+
+static void
+_move(void *data, Evas *evas, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *gl = data;
+   Evas_Event_Mouse_Move *ev = event_info;
+   int where = 0;
+   Elm_Genlist_Item *gli;
+   gli = elm_genlist_at_xy_item_get(gl, ev->cur.canvas.x, ev->cur.canvas.y, &where);
+   if (gli)
+     printf("over %p, where %i\n", elm_genlist_item_data_get(gli), where);
+   else
+     printf("over none, where %i\n", where);
+}
+
+static void
+_bt50_cb(void *data, Evas_Object *obj, void *event_info)
+{
+    elm_genlist_item_bring_in(data);
+}
+
+static void
+_bt1500_cb(void *data, Evas_Object *obj, void *event_info)
+{
+    elm_genlist_item_middle_bring_in(data);
+}
+
+static void
+_gl_selected(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("selected: %p\n", event_info);
+}
+
+static void
+_gl_clicked(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("clicked: %p\n", event_info);
+}
+
+static void
+_gl_longpress(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("longpress %p\n", event_info);
+}
+
+void
+test_genlist(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *gl, *bt_50, *bt_1500, *bx;
+   Evas_Object *over;
+   Elm_Genlist_Item *gli;
+   int i;
+
+   win = elm_win_add(NULL, "genlist", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Genlist");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   gl = elm_genlist_add(win);
+   evas_object_smart_callback_add(gl, "selected", _gl_selected, NULL);
+   evas_object_smart_callback_add(gl, "clicked", _gl_clicked, NULL);
+   evas_object_smart_callback_add(gl, "longpressed", _gl_longpress, NULL);
+   // FIXME: This causes genlist to resize the horiz axis very slowly :(
+   // Reenable this and resize the window horizontally, then try to resize it back
+   //elm_genlist_horizontal_mode_set(gl, ELM_LIST_LIMIT);
+   evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx, gl);
+   evas_object_show(gl);
+
+   over = evas_object_rectangle_add(evas_object_evas_get(win));
+   evas_object_color_set(over, 0, 0, 0, 0);
+   evas_object_event_callback_add(over, EVAS_CALLBACK_MOUSE_MOVE, _move, gl);
+   evas_object_repeat_events_set(over, 1);
+   evas_object_show(over);
+   evas_object_size_hint_weight_set(over, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, over);
+
+   itc1.item_style     = "default";
+   itc1.func.label_get = gl_label_get;
+   itc1.func.icon_get  = gl_icon_get;
+   itc1.func.state_get = gl_state_get;
+   itc1.func.del       = gl_del;
+
+   bt_50 = elm_button_add(win);
+   elm_button_label_set(bt_50, "Go to 50");
+   evas_object_show(bt_50);
+   elm_box_pack_end(bx, bt_50);
+
+   bt_1500 = elm_button_add(win);
+   elm_button_label_set(bt_1500, "Go to 1500");
+   evas_object_show(bt_1500);
+   elm_box_pack_end(bx, bt_1500);
+
+   for (i = 0; i < 2000; i++)
+     {
+        gli = elm_genlist_item_append(gl, &itc1,
+                                      (void *)i/* item data */,
+                                      NULL/* parent */,
+                                      ELM_GENLIST_ITEM_NONE,
+                                      gl_sel/* func */,
+                                      (void *)(i * 10)/* func data */);
+        if (i == 50)
+          evas_object_smart_callback_add(bt_50, "clicked", _bt50_cb, gli);
+        else if (i == 1500)
+          evas_object_smart_callback_add(bt_1500, "clicked", _bt1500_cb, gli);
+     }
+   evas_object_resize(win, 480, 800);
+   evas_object_show(win);
+}
+
+/*************/
+
+static void
+my_gl_clear(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *gl = data;
+   elm_genlist_clear(gl);
+}
+
+static void
+my_gl_add(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *gl = data;
+   Elm_Genlist_Item *gli;
+   static int i = 0;
+
+   itc1.item_style     = "default";
+   itc1.func.label_get = gl_label_get;
+   itc1.func.icon_get  = gl_icon_get;
+   itc1.func.state_get = gl_state_get;
+   itc1.func.del       = gl_del;
+
+   gli = elm_genlist_item_append(gl, &itc1,
+                                (void *)i/* item data */,
+                                NULL/* parent */,
+                                ELM_GENLIST_ITEM_NONE,
+                                gl_sel/* func */,
+                                (void *)(i * 10)/* func data */);
+   i++;
+}
+
+static void
+my_gl_insert_before(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *gl = data;
+   Elm_Genlist_Item *gli;
+   static int i = 0;
+   Elm_Genlist_Item *gli_selected;
+
+   itc1.item_style     = "default";
+   itc1.func.label_get = gl_label_get;
+   itc1.func.icon_get  = gl_icon_get;
+   itc1.func.state_get = gl_state_get;
+   itc1.func.del       = gl_del;
+
+   gli_selected = elm_genlist_selected_item_get(gl);
+   if(!gli_selected)
+   {
+       printf("no item selected\n");
+       return ;
+   }
+
+   gli = elm_genlist_item_insert_before(gl, &itc1,
+                                (void *)i/* item data */,
+                                gli_selected /* item before */,
+                                ELM_GENLIST_ITEM_NONE,
+                                gl_sel/* func */,
+                                (void *)(i * 10)/* func data */);
+   i++;
+}
+
+static void
+my_gl_insert_after(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *gl = data;
+   Elm_Genlist_Item *gli;
+   static int i = 0;
+   Elm_Genlist_Item *gli_selected;
+
+   itc1.item_style     = "default";
+   itc1.func.label_get = gl_label_get;
+   itc1.func.icon_get  = gl_icon_get;
+   itc1.func.state_get = gl_state_get;
+   itc1.func.del       = gl_del;
+
+   gli_selected = elm_genlist_selected_item_get(gl);
+   if(!gli_selected)
+   {
+       printf("no item selected\n");
+       return ;
+   }
+
+   gli = elm_genlist_item_insert_after(gl, &itc1,
+                                (void *)i/* item data */,
+                                gli_selected /* item after */,
+                                ELM_GENLIST_ITEM_NONE,
+                                gl_sel/* func */,
+                                (void *)(i * 10)/* func data */);
+   i++;
+}
+
+static void
+my_gl_del(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *gl = data;
+   Elm_Genlist_Item *gli = elm_genlist_selected_item_get(gl);
+   if (!gli)
+     {
+       printf("no item selected\n");
+       return;
+     }
+   elm_genlist_item_del(gli);
+}
+
+static void
+my_gl_disable(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *gl = data;
+   Elm_Genlist_Item *gli = elm_genlist_selected_item_get(gl);
+   if (!gli)
+     {
+       printf("no item selected\n");
+       return;
+     }
+   elm_genlist_item_disabled_set(gli, 1);
+   elm_genlist_item_selected_set(gli, 0);
+   elm_genlist_item_update(gli);
+}
+
+static void
+my_gl_update_all(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *gl = data;
+   int i = 0;
+   Elm_Genlist_Item *it = elm_genlist_first_item_get(gl);
+   while (it)
+     {
+       elm_genlist_item_update(it);
+       printf("%i\n", i);
+       i++;
+       it = elm_genlist_item_next_get(it);
+     }
+}
+
+static void
+my_gl_first(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *gl = data;
+   Elm_Genlist_Item *gli = elm_genlist_first_item_get(gl);
+   if (!gli) return;
+   elm_genlist_item_show(gli);
+   elm_genlist_item_selected_set(gli, 1);
+}
+
+static void
+my_gl_last(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *gl = data;
+   Elm_Genlist_Item *gli = elm_genlist_last_item_get(gl);
+   if (!gli) return;
+   elm_genlist_item_show(gli);
+   elm_genlist_item_selected_set(gli, 1);
+}
+
+static int
+my_gl_flush_delay(void *data)
+{
+   elm_all_flush();
+   return 0;
+}
+
+static void
+my_gl_flush(void *data, Evas_Object *obj, void *event_info)
+{
+   ecore_timer_add(1.2, my_gl_flush_delay, NULL);
+}
+
+void
+test_genlist2(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *gl, *bx, *bx2, *bx3, *bt;
+   Elm_Genlist_Item *gli[10];
+   char buf[PATH_MAX];
+
+   win = elm_win_add(NULL, "genlist-2", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Genlist 2");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/plant_01.jpg", PACKAGE_DATA_DIR);
+   elm_bg_file_set(bg, buf, NULL);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   gl = elm_genlist_add(win);
+   evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(gl);
+
+   itc1.item_style     = "default";
+   itc1.func.label_get = gl_label_get;
+   itc1.func.icon_get  = gl_icon_get;
+   itc1.func.state_get = gl_state_get;
+   itc1.func.del       = gl_del;
+
+   gli[0] = elm_genlist_item_append(gl, &itc1,
+                                   (void *)1001/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, gl_sel/* func */,
+                                   (void *)1001/* func data */);
+   gli[1] = elm_genlist_item_append(gl, &itc1,
+                                   (void *)1002/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, gl_sel/* func */,
+                                   (void *)1002/* func data */);
+   gli[2] = elm_genlist_item_append(gl, &itc1,
+                                   (void *)1003/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, gl_sel/* func */,
+                                   (void *)1003/* func data */);
+   gli[3] = elm_genlist_item_prepend(gl, &itc1,
+                                    (void *)1004/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, gl_sel/* func */,
+                                    (void *)1004/* func data */);
+   gli[4] = elm_genlist_item_prepend(gl, &itc1,
+                                    (void *)1005/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, gl_sel/* func */,
+                                    (void *)1005/* func data */);
+   gli[5] = elm_genlist_item_insert_before(gl, &itc1,
+                                          (void *)1006/* item data */, gli[2]/* rel */, ELM_GENLIST_ITEM_NONE, gl_sel/* func */,
+                                          (void *)1006/* func data */);
+   gli[6] = elm_genlist_item_insert_after(gl, &itc1,
+                                         (void *)1007/* item data */, gli[2]/* rel */, ELM_GENLIST_ITEM_NONE, gl_sel/* func */,
+                                         (void *)1007/* func data */);
+
+   elm_box_pack_end(bx, gl);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   elm_box_homogenous_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "/\\");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_first, gl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "\\/");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_last, gl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "#");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_disable, gl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "U");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_update_all, gl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   elm_box_homogenous_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "X");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_clear, gl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "+");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_add, gl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "-");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_del, gl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   bx3 = elm_box_add(win);
+   elm_box_horizontal_set(bx3, 1);
+   elm_box_homogenous_set(bx3, 1);
+   evas_object_size_hint_weight_set(bx3, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx3, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "+ before");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_insert_before, gl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx3, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "+ after");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_insert_after, gl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx3, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Flush");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_flush, gl);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx3, bt);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx3);
+   evas_object_show(bx3);
+
+
+   evas_object_resize(win, 320, 320);
+   evas_object_show(win);
+}
+
+/*************/
+
+static Elm_Genlist_Item_Class itc2;
+char *gl2_label_get(const void *data, Evas_Object *obj, const char *part)
+{
+   const Testitem *tit = data;
+   char buf[256];
+   snprintf(buf, sizeof(buf), "Item mode %i", tit->mode);
+   return strdup(buf);
+}
+Evas_Object *gl2_icon_get(const void *data, Evas_Object *obj, const char *part)
+{
+   const Testitem *tit = data;
+   char buf[PATH_MAX];
+   Evas_Object *ic = elm_icon_add(obj);
+   if (!strcmp(part, "elm.swallow.icon"))
+     {
+       if ((tit->mode & 0x3) == 0)
+         snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+       else if ((tit->mode & 0x3) == 1)
+         snprintf(buf, sizeof(buf), "%s/images/logo.png", PACKAGE_DATA_DIR);
+       else if ((tit->mode & 0x3) == 2)
+         snprintf(buf, sizeof(buf), "%s/images/panel_01.jpg", PACKAGE_DATA_DIR);
+       else if ((tit->mode & 0x3) == 3)
+         snprintf(buf, sizeof(buf), "%s/images/rock_01.jpg", PACKAGE_DATA_DIR);
+       elm_icon_file_set(ic, buf, NULL);
+     }
+   else if (!strcmp(part, "elm.swallow.end"))
+     {
+       if ((tit->mode & 0x3) == 0)
+         snprintf(buf, sizeof(buf), "%s/images/sky_01.jpg", PACKAGE_DATA_DIR);
+       else if ((tit->mode & 0x3) == 1)
+         snprintf(buf, sizeof(buf), "%s/images/sky_02.jpg", PACKAGE_DATA_DIR);
+       else if ((tit->mode & 0x3) == 2)
+         snprintf(buf, sizeof(buf), "%s/images/sky_03.jpg", PACKAGE_DATA_DIR);
+       else if ((tit->mode & 0x3) == 3)
+         snprintf(buf, sizeof(buf), "%s/images/sky_04.jpg", PACKAGE_DATA_DIR);
+       elm_icon_file_set(ic, buf, NULL);
+     }
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+   return ic;
+}
+Eina_Bool gl2_state_get(const void *data, Evas_Object *obj, const char *part)
+{
+   return EINA_FALSE;
+}
+void gl2_del(const void *data, Evas_Object *obj)
+{
+}
+
+static void
+my_gl_update(void *data, Evas_Object *obj, void *event_info)
+{
+   Testitem *tit = data;
+   tit->mode++;
+   elm_genlist_item_update(tit->item);
+}
+
+void
+test_genlist3(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *gl, *bx, *bx2, *bt;
+   static Testitem tit[3];
+
+   win = elm_win_add(NULL, "genlist-3", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Genlist 3");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   gl = elm_genlist_add(win);
+   evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(gl);
+
+   itc2.item_style     = "default";
+   itc2.func.label_get = gl2_label_get;
+   itc2.func.icon_get  = gl2_icon_get;
+   itc2.func.state_get = gl2_state_get;
+   itc2.func.del       = gl2_del;
+
+   tit[0].mode = 0;
+   tit[0].item = elm_genlist_item_append(gl, &itc2,
+                                        &(tit[0])/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, gl_sel/* func */,
+                                        NULL/* func data */);
+   tit[1].mode = 1;
+   tit[1].item = elm_genlist_item_append(gl, &itc2,
+                                        &(tit[1])/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, gl_sel/* func */,
+                                        NULL/* func data */);
+   tit[2].mode = 2;
+   tit[2].item = elm_genlist_item_append(gl, &itc2,
+                                        &(tit[2])/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, gl_sel/* func */,
+                                        NULL/* func data */);
+
+   elm_box_pack_end(bx, gl);
+   evas_object_show(bx);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   elm_box_homogenous_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "[1]");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_update, &(tit[0]));
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "[2]");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_update, &(tit[1]));
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "[3]");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_update, &(tit[2]));
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   evas_object_resize(win, 320, 320);
+   evas_object_show(win);
+}
+
+/*************/
+
+static void
+my_gl_item_check_changed(void *data, Evas_Object *obj, void *event_info)
+{
+   Testitem *tit = data;
+   tit->onoff = elm_check_state_get(obj);
+   printf("item %p onoff = %i\n", tit, tit->onoff);
+}
+
+static Elm_Genlist_Item_Class itc3;
+char *gl3_label_get(const void *data, Evas_Object *obj, const char *part)
+{
+   const Testitem *tit = data;
+   char buf[256];
+   snprintf(buf, sizeof(buf), "Item mode %i", tit->mode);
+   return strdup(buf);
+}
+Evas_Object *gl3_icon_get(const void *data, Evas_Object *obj, const char *part)
+{
+   const Testitem *tit = data;
+   char buf[PATH_MAX];
+   if (!strcmp(part, "elm.swallow.icon"))
+     {
+        Evas_Object *lb;
+        
+        lb = elm_label_add(obj);
+        elm_label_line_wrap_set(lb, 1);
+        elm_label_wrap_width_set(lb, 201);
+        elm_label_label_set(lb, "ashj ascjscjh n asjkl hcjlh ls hzshnn zjh sh zxjcjsnd h dfw sdv edev efe fwefvv vsd cvs ws wf  fvwf wd fwe f  we wef we wfe rfwewef wfv wswf wefg sdfws w wsdcfwcf wsc vdv  sdsd sdcd cv wsc sdcv wsc d sdcdcsd sdcdsc wdvd sdcsd wscxcv wssvd sd");
+        evas_object_show(lb);
+        return lb;
+        
+       Evas_Object *bx = elm_box_add(obj);
+       Evas_Object *ic;
+       ic = elm_icon_add(obj);
+       snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+       elm_icon_file_set(ic, buf, NULL);
+       elm_icon_scale_set(ic, 0, 0);
+       evas_object_show(ic);
+       elm_box_pack_end(bx, ic);
+       ic = elm_icon_add(obj);
+       elm_icon_file_set(ic, buf, NULL);
+       elm_icon_scale_set(ic, 0, 0);
+       evas_object_show(ic);
+       elm_box_pack_end(bx, ic);
+        elm_box_horizontal_set(bx, 1);
+       evas_object_show(bx);
+       return bx;
+     }
+   else if (!strcmp(part, "elm.swallow.end"))
+     {
+       Evas_Object *ck;
+       ck = elm_check_add(obj);
+       evas_object_propagate_events_set(ck, 0);
+       elm_check_state_set(ck, tit->onoff);
+       evas_object_smart_callback_add(ck, "changed", my_gl_item_check_changed, data);
+       evas_object_show(ck);
+       return ck;
+     }
+   return NULL;
+}
+Eina_Bool gl3_state_get(const void *data, Evas_Object *obj, const char *part)
+{
+   return EINA_FALSE;
+}
+void gl3_del(const void *data, Evas_Object *obj)
+{
+}
+
+void
+test_genlist4(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *gl, *bx, *bx2, *bt;
+   static Testitem tit[3];
+
+   win = elm_win_add(NULL, "genlist-4", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Genlist 4");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   gl = elm_genlist_add(win);
+   elm_genlist_multi_select_set(gl, 1);
+   evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(gl);
+
+   itc3.item_style     = "default";
+   itc3.func.label_get = gl3_label_get;
+   itc3.func.icon_get  = gl3_icon_get;
+   itc3.func.state_get = gl3_state_get;
+   itc3.func.del       = gl3_del;
+
+   tit[0].mode = 0;
+   tit[0].item = elm_genlist_item_append(gl, &itc3,
+                                        &(tit[0])/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, gl_sel/* func */,
+                                        NULL/* func data */);
+   tit[1].mode = 1;
+   tit[1].item = elm_genlist_item_append(gl, &itc3,
+                                        &(tit[1])/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, gl_sel/* func */,
+                                        NULL/* func data */);
+   tit[2].mode = 2;
+   tit[2].item = elm_genlist_item_append(gl, &itc3,
+                                        &(tit[2])/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, gl_sel/* func */,
+                                        NULL/* func data */);
+
+   elm_box_pack_end(bx, gl);
+   evas_object_show(bx);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   elm_box_homogenous_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "[1]");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_update, &(tit[0]));
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "[2]");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_update, &(tit[1]));
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "[3]");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_update, &(tit[2]));
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   evas_object_resize(win, 320, 320);
+   evas_object_show(win);
+}
+
+
+/*************/
+static void
+my_gl_item_check_changed2(void *data, Evas_Object *obj, void *event_info)
+{
+   Testitem *tit = data;
+   tit->onoff = elm_check_state_get(obj);
+   printf("item %p onoff = %i\n", tit, tit->onoff);
+}
+
+static Elm_Genlist_Item_Class itc5;
+char *gl5_label_get(const void *data, Evas_Object *obj, const char *part)
+{
+   const Testitem *tit = data;
+   char buf[256];
+   if (!strcmp(part, "elm.text"))
+     {
+       snprintf(buf, sizeof(buf), "Item mode %i", tit->mode);
+     }
+   else if (!strcmp(part, "elm.text.sub"))
+     {
+       snprintf(buf, sizeof(buf), "%i bottles on the wall", tit->mode);
+     }
+   return strdup(buf);
+}
+Evas_Object *gl5_icon_get(const void *data, Evas_Object *obj, const char *part)
+{
+   const Testitem *tit = data;
+   char buf[PATH_MAX];
+   if (!strcmp(part, "elm.swallow.icon"))
+     {
+       Evas_Object *bx = elm_box_add(obj);
+       Evas_Object *ic;
+       elm_box_horizontal_set(bx, 1);
+       ic = elm_icon_add(obj);
+       snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+       elm_icon_file_set(ic, buf, NULL);
+       elm_icon_scale_set(ic, 0, 0);
+       evas_object_show(ic);
+       elm_box_pack_end(bx, ic);
+       ic = elm_icon_add(obj);
+       elm_icon_file_set(ic, buf, NULL);
+       elm_icon_scale_set(ic, 0, 0);
+       evas_object_show(ic);
+       elm_box_pack_end(bx, ic);
+        elm_box_horizontal_set(bx, 1);
+       evas_object_show(bx);
+       return bx;
+     }
+   else if (!strcmp(part, "elm.swallow.end"))
+     {
+       Evas_Object *ck;
+       ck = elm_check_add(obj);
+       evas_object_propagate_events_set(ck, 0);
+       elm_check_state_set(ck, tit->onoff);
+       evas_object_smart_callback_add(ck, "changed", my_gl_item_check_changed2, data);
+       evas_object_show(ck);
+       return ck;
+     }
+   return NULL;
+}
+Eina_Bool gl5_state_get(const void *data, Evas_Object *obj, const char *part)
+{
+   return EINA_FALSE;
+}
+void gl5_del(const void *data, Evas_Object *obj)
+{
+}
+
+static void
+item_drag_up(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("drag up\n");
+}
+
+static void
+item_drag_down(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("drag down\n");
+}
+
+static void
+item_drag_left(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("drag left\n");
+}
+
+static void
+item_drag_right(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("drag right\n");
+}
+
+static void
+item_drag(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("drag\n");
+}
+
+static void
+item_drag_stop(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("drag stop\n");
+}
+
+static void
+item_longpress(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("longpress\n");
+}
+
+void
+test_genlist5(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *gl, *bx, *bx2, *bt;
+   static Testitem tit[3];
+
+   win = elm_win_add(NULL, "genlist-5", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Genlist 5");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   gl = elm_genlist_add(win);
+   elm_genlist_always_select_mode_set(gl, 1);
+   evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(gl);
+   itc5.item_style     = "double_label";
+   itc5.func.label_get = gl5_label_get;
+   itc5.func.icon_get  = gl5_icon_get;
+   itc5.func.state_get = gl5_state_get;
+   itc5.func.del       = gl5_del;
+
+   tit[0].mode = 0;
+   tit[0].item = elm_genlist_item_append(gl, &itc5,
+                                        &(tit[0])/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, gl_sel/* func */,
+                                        NULL/* func data */);
+   tit[1].mode = 1;
+   tit[1].item = elm_genlist_item_append(gl, &itc5,
+                                        &(tit[1])/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, gl_sel/* func */,
+                                        NULL/* func data */);
+   tit[2].mode = 2;
+   tit[2].item = elm_genlist_item_append(gl, &itc5,
+                                        &(tit[2])/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, gl_sel/* func */,
+                                        NULL/* func data */);
+
+   elm_box_pack_end(bx, gl);
+   evas_object_show(bx);
+
+   evas_object_smart_callback_add(gl, "drag,start,up", item_drag_up, NULL);
+   evas_object_smart_callback_add(gl, "drag,start,down", item_drag_down, NULL);
+   evas_object_smart_callback_add(gl, "drag,start,left", item_drag_left, NULL);
+   evas_object_smart_callback_add(gl, "drag,start,right", item_drag_right, NULL);
+   evas_object_smart_callback_add(gl, "drag", item_drag, NULL);
+   evas_object_smart_callback_add(gl, "drag,stop", item_drag_stop, NULL);
+   evas_object_smart_callback_add(gl, "longpressed", item_longpress, NULL);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   elm_box_homogenous_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "[1]");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_update, &(tit[0]));
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "[2]");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_update, &(tit[1]));
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "[3]");
+   evas_object_smart_callback_add(bt, "clicked", my_gl_update, &(tit[2]));
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   evas_object_resize(win, 320, 320);
+   evas_object_show(win);
+}
+
+/*************/
+
+static Elm_Genlist_Item_Class itc4;
+
+static void
+gl4_sel(void *data, Evas_Object *obj, void *event_info)
+{
+}
+static void
+gl4_exp(void *data, Evas_Object *obj, void *event_info)
+{
+   Elm_Genlist_Item *it = event_info;
+   Evas_Object *gl = elm_genlist_item_genlist_get(it);
+   int val = (int)elm_genlist_item_data_get(it);
+   val *= 10;
+   elm_genlist_item_append(gl, &itc4,
+                          (void *)(val + 1)/* item data */, it/* parent */, ELM_GENLIST_ITEM_NONE, gl4_sel/* func */,
+                          NULL/* func data */);
+   elm_genlist_item_append(gl, &itc4,
+                          (void *)(val + 2)/* item data */, it/* parent */, ELM_GENLIST_ITEM_NONE, gl4_sel/* func */,
+                          NULL/* func data */);
+   elm_genlist_item_append(gl, &itc4,
+                          (void *)(val + 3)/* item data */, it/* parent */, ELM_GENLIST_ITEM_SUBITEMS, gl4_sel/* func */,
+                          NULL/* func data */);
+}
+static void
+gl4_con(void *data, Evas_Object *obj, void *event_info)
+{
+   Elm_Genlist_Item *it = event_info;
+   elm_genlist_item_subitems_clear(it);
+}
+
+static void
+gl4_exp_req(void *data, Evas_Object *obj, void *event_info)
+{
+   Elm_Genlist_Item *it = event_info;
+   elm_genlist_item_expanded_set(it, 1);
+}
+static void
+gl4_con_req(void *data, Evas_Object *obj, void *event_info)
+{
+   Elm_Genlist_Item *it = event_info;
+   elm_genlist_item_expanded_set(it, 0);
+}
+
+char *gl4_label_get(const void *data, Evas_Object *obj, const char *part)
+{
+   char buf[256];
+   snprintf(buf, sizeof(buf), "Item mode %i", (int)data);
+   return strdup(buf);
+}
+Evas_Object *gl4_icon_get(const void *data, Evas_Object *obj, const char *part)
+{
+   char buf[PATH_MAX];
+   if (!strcmp(part, "elm.swallow.icon"))
+     {
+       Evas_Object *ic = elm_icon_add(obj);
+       snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+       elm_icon_file_set(ic, buf, NULL);
+       evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+       evas_object_show(ic);
+       return ic;
+     }
+   else if (!strcmp(part, "elm.swallow.end"))
+     {
+       Evas_Object *ck;
+       ck = elm_check_add(obj);
+       evas_object_show(ck);
+       return ck;
+     }
+   return NULL;
+}
+Eina_Bool gl4_state_get(const void *data, Evas_Object *obj, const char *part)
+{
+   return EINA_FALSE;
+}
+void gl4_del(const void *data, Evas_Object *obj)
+{
+}
+
+void
+test_genlist6(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *gl, *bx, *bx2, *bt;
+
+   win = elm_win_add(NULL, "genlist-tree", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Genlist Tree");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   gl = elm_genlist_add(win);
+   evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(gl);
+
+   itc4.item_style     = "default";
+   itc4.func.label_get = gl4_label_get;
+   itc4.func.icon_get  = gl4_icon_get;
+   itc4.func.state_get = gl4_state_get;
+   itc4.func.del       = gl4_del;
+
+   elm_genlist_item_append(gl, &itc4,
+                          (void *)1/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_SUBITEMS, gl4_sel/* func */,
+                          NULL/* func data */);
+   elm_genlist_item_append(gl, &itc4,
+                          (void *)2/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_SUBITEMS, gl4_sel/* func */,
+                          NULL/* func data */);
+   elm_genlist_item_append(gl, &itc4,
+                          (void *)3/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, gl4_sel/* func */,
+                          NULL/* func data */);
+
+   evas_object_smart_callback_add(gl, "expand,request", gl4_exp_req, gl);
+   evas_object_smart_callback_add(gl, "contract,request", gl4_con_req, gl);
+   evas_object_smart_callback_add(gl, "expanded", gl4_exp, gl);
+   evas_object_smart_callback_add(gl, "contracted", gl4_con, gl);
+
+   elm_box_pack_end(bx, gl);
+   evas_object_show(bx);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   elm_box_homogenous_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "[1]");
+//   evas_object_smart_callback_add(bt, "clicked", my_gl_update, &(tit[0]));
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "[2]");
+//   evas_object_smart_callback_add(bt, "clicked", my_gl_update, &(tit[1]));
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "[3]");
+//   evas_object_smart_callback_add(bt, "clicked", my_gl_update, &(tit[2]));
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   evas_object_resize(win, 320, 320);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_grid.c b/src/bin/test_grid.c
new file mode 100644 (file)
index 0000000..b8006b1
--- /dev/null
@@ -0,0 +1,187 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+typedef struct _Testitem
+{
+   Elm_Grid_Cell *cell;
+   const char *path;
+   int mode;
+   int onoff;
+} Testitem;
+
+static Elm_Grid_Cell_Class gcc;
+
+static void
+grid_drag_up(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("Drag up: %p\n", event_info);
+}
+
+static void
+grid_drag_right(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("Drag right: %p\n", event_info);
+}
+
+static void
+grid_drag_down(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("Drag down: %p\n", event_info);
+}
+
+static void
+grid_drag_left(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("Drag left: %p\n", event_info);
+}
+
+static void
+grid_drag_stop(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("Drag stop: %p\n", event_info);
+}
+
+static void
+grid_selected(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("Selected: %p\n", event_info);
+}
+
+static void
+grid_clicked(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("Clicked: %p\n", event_info);
+}
+
+static void
+grid_longpress(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("longpress %p\n", event_info);
+}
+
+static void
+grid_cell_check_changed(void *data, Evas_Object *obj, void *event_info)
+{
+   Testitem *tit = data;
+   tit->onoff = elm_check_state_get(obj);
+   printf("cell %p onoff = %i\n", tit, tit->onoff);
+}
+
+char *
+grid_label_get(const void *data, Evas_Object *obj, const char *part)
+{
+   const Testitem *tit = data;
+   char buf[256];
+   snprintf(buf, sizeof(buf), "Photo %s", tit->path);
+   return strdup(buf);
+}
+
+Evas_Object *
+grid_icon_get(const void *data, Evas_Object *obj, const char *part)
+{
+   const Testitem *tit = data;
+   if (!strcmp(part, "elm.swallow.icon"))
+     {
+
+       Evas_Object *icon = elm_bg_add(obj);
+       elm_bg_file_set(icon, tit->path, NULL);
+       evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+       evas_object_show(icon);
+       return icon;
+     }
+   else if (!strcmp(part, "elm.swallow.end"))
+     {
+       Evas_Object *ck;
+       ck = elm_check_add(obj);
+       evas_object_propagate_events_set(ck, 0);
+       elm_check_state_set(ck, tit->onoff);
+       evas_object_smart_callback_add(ck, "changed", grid_cell_check_changed, data);
+       evas_object_show(ck);
+       return ck;
+     }
+   return NULL;
+}
+
+Eina_Bool
+grid_state_get(const void *data, Evas_Object *obj, const char *part)
+{
+   return EINA_FALSE;
+}
+
+void
+grid_del(const void *data, Evas_Object *obj)
+{
+}
+
+static void
+grid_sel(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("sel item data [%p] on grid obj [%p], pointer [%p]\n", data, obj, event_info);
+}
+
+void
+test_grid(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *grid;
+   static Testitem item[144];
+   int i, j, n;
+   char buf[PATH_MAX];
+   const char *img[9] =
+     {
+       "panel_01.jpg",
+       "plant_01.jpg",
+       "rock_01.jpg",
+       "rock_02.jpg",
+       "sky_01.jpg",
+       "sky_02.jpg",
+       "sky_03.jpg",
+       "sky_04.jpg",
+       "wood_01.jpg",
+     };
+
+   win = elm_win_add(NULL, "grid", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Grid");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+
+   grid = elm_scrolled_grid_add(win);
+   elm_scrolled_grid_cell_size_set(grid, 150, 150);
+   elm_scrolled_grid_horizontal_set(grid, EINA_FALSE);
+   elm_scrolled_grid_multi_select_set(grid, EINA_TRUE);
+   evas_object_smart_callback_add(grid, "selected", grid_selected, NULL);
+   evas_object_smart_callback_add(grid, "clicked", grid_clicked, NULL);
+   evas_object_smart_callback_add(grid, "longpressed", grid_longpress, NULL);
+   evas_object_smart_callback_add(grid, "drag,start,up", grid_drag_up, NULL);
+   evas_object_smart_callback_add(grid, "drag,start,right", grid_drag_right, NULL);
+   evas_object_smart_callback_add(grid, "drag,start,down", grid_drag_down, NULL);
+   evas_object_smart_callback_add(grid, "drag,start,left", grid_drag_left, NULL);
+   evas_object_smart_callback_add(grid, "drag,stop", grid_drag_stop, NULL);
+   evas_object_size_hint_weight_set(grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+   gcc.item_style = "default";
+   gcc.func.label_get = grid_label_get;
+   gcc.func.icon_get = grid_icon_get;
+   gcc.func.state_get = grid_state_get;
+   gcc.func.del = grid_del;
+
+   n = 0;
+   for (i = 0; i < 12 * 12; i++)
+     {
+       snprintf(buf, sizeof(buf), "%s/images/%s", PACKAGE_DATA_DIR,
+             img[n]);
+       n = (n + 1) % 9;
+       item[i].mode = i;
+       item[i].path = eina_stringshare_add(buf);
+       item[i].cell = elm_scrolled_grid_cell_add(grid, &gcc, &(item[i]), grid_sel, NULL);
+     }
+
+   evas_object_show(grid);
+   elm_win_resize_object_add(win, grid);
+
+   evas_object_resize(win, 600, 600);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_hover.c b/src/bin/test_hover.c
new file mode 100644 (file)
index 0000000..51e97f3
--- /dev/null
@@ -0,0 +1,171 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+static void
+my_hover_bt(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *hv = data;
+
+   evas_object_show(hv);
+}
+
+void
+test_hover(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *bt, *hv, *ic;
+   char buf[PATH_MAX];
+
+   win = elm_win_add(NULL, "hover", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Hover");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   hv = elm_hover_add(win);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button");
+   evas_object_smart_callback_add(bt, "clicked", my_hover_bt, hv);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+   elm_hover_parent_set(hv, win);
+   elm_hover_target_set(hv, bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Popup");
+   elm_hover_content_set(hv, "middle", bt);
+   evas_object_show(bt);
+
+   bx = elm_box_add(win);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   elm_box_pack_end(bx, ic);
+   evas_object_show(ic);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Top 1");
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Top 2");
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Top 3");
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   evas_object_show(bx);
+   elm_hover_content_set(hv, "top", bx);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Bottom");
+   elm_hover_content_set(hv, "bottom", bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Left");
+   elm_hover_content_set(hv, "left", bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Right");
+   elm_hover_content_set(hv, "right", bt);
+   evas_object_show(bt);
+
+   evas_object_size_hint_min_set(bg, 160, 160);
+   evas_object_size_hint_max_set(bg, 640, 640);
+   evas_object_resize(win, 320, 320);
+   evas_object_show(win);
+}
+
+void
+test_hover2(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *bt, *hv, *ic;
+   char buf[PATH_MAX];
+
+   win = elm_win_add(NULL, "hover2", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Hover 2");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   hv = elm_hover_add(win);
+   elm_object_style_set(hv, "popout");
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button");
+   evas_object_smart_callback_add(bt, "clicked", my_hover_bt, hv);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+   elm_hover_parent_set(hv, win);
+   elm_hover_target_set(hv, bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Popup");
+   elm_hover_content_set(hv, "middle", bt);
+   evas_object_show(bt);
+
+   bx = elm_box_add(win);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   elm_box_pack_end(bx, ic);
+   evas_object_show(ic);
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Top 1");
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Top 2");
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Top 3");
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+   evas_object_show(bx);
+   elm_hover_content_set(hv, "top", bx);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Bot");
+   elm_hover_content_set(hv, "bottom", bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Left");
+   elm_hover_content_set(hv, "left", bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Right");
+   elm_hover_content_set(hv, "right", bt);
+   evas_object_show(bt);
+
+   evas_object_size_hint_min_set(bg, 160, 160);
+   evas_object_size_hint_max_set(bg, 640, 640);
+   evas_object_resize(win, 320, 320);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_hoversel.c b/src/bin/test_hoversel.c
new file mode 100644 (file)
index 0000000..cf8f3da
--- /dev/null
@@ -0,0 +1,106 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+void
+test_hoversel(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *bt, *ic;
+   char buf[PATH_MAX];
+
+   win = elm_win_add(NULL, "hoversel", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Hoversel");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   elm_win_resize_object_add(win, bx);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bx);
+
+   bt = elm_hoversel_add(win);
+   elm_hoversel_hover_parent_set(bt, win);
+   elm_hoversel_label_set(bt, "Labels");
+   elm_hoversel_item_add(bt, "Item 1", NULL, ELM_ICON_NONE, NULL, NULL);
+   elm_hoversel_item_add(bt, "Item 2", NULL, ELM_ICON_NONE, NULL, NULL);
+   elm_hoversel_item_add(bt, "Item 3", NULL, ELM_ICON_NONE, NULL, NULL);
+   elm_hoversel_item_add(bt, "Item 4 - Long Label Here", NULL, ELM_ICON_NONE, NULL, NULL);
+   evas_object_size_hint_weight_set(bt, 0.0, 0.0);
+   evas_object_size_hint_align_set(bt, 0.5, 0.5);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_hoversel_add(win);
+   elm_hoversel_hover_parent_set(bt, win);
+   elm_hoversel_label_set(bt, "Some Icons");
+   elm_hoversel_item_add(bt, "Item 1", NULL, ELM_ICON_NONE, NULL, NULL);
+   elm_hoversel_item_add(bt, "Item 2", NULL, ELM_ICON_NONE, NULL, NULL);
+   elm_hoversel_item_add(bt, "Item 3", "home", ELM_ICON_STANDARD, NULL, NULL);
+   elm_hoversel_item_add(bt, "Item 4", "close", ELM_ICON_STANDARD, NULL, NULL);
+   evas_object_size_hint_weight_set(bt, 0.0, 0.0);
+   evas_object_size_hint_align_set(bt, 0.5, 0.5);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_hoversel_add(win);
+   elm_hoversel_hover_parent_set(bt, win);
+   elm_hoversel_label_set(bt, "All Icons");
+   elm_hoversel_item_add(bt, "Item 1", "apps", ELM_ICON_STANDARD, NULL, NULL);
+   elm_hoversel_item_add(bt, "Item 2", "arrow_down", ELM_ICON_STANDARD, NULL, NULL);
+   elm_hoversel_item_add(bt, "Item 3", "home", ELM_ICON_STANDARD, NULL, NULL);
+   elm_hoversel_item_add(bt, "Item 4", "close", ELM_ICON_STANDARD, NULL, NULL);
+   evas_object_size_hint_weight_set(bt, 0.0, 0.0);
+   evas_object_size_hint_align_set(bt, 0.5, 0.5);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_hoversel_add(win);
+   elm_hoversel_hover_parent_set(bt, win);
+   elm_hoversel_label_set(bt, "All Icons");
+   elm_hoversel_item_add(bt, "Item 1", "apps", ELM_ICON_STANDARD, NULL, NULL);
+   snprintf(buf, sizeof(buf), "%s/images/sky_02.jpg", PACKAGE_DATA_DIR);
+   elm_hoversel_item_add(bt, "Item 2", buf, ELM_ICON_FILE, NULL, NULL);
+   elm_hoversel_item_add(bt, "Item 3", "home", ELM_ICON_STANDARD, NULL, NULL);
+   elm_hoversel_item_add(bt, "Item 4", "close", ELM_ICON_STANDARD, NULL, NULL);
+   evas_object_size_hint_weight_set(bt, 0.0, 0.0);
+   evas_object_size_hint_align_set(bt, 0.5, 0.5);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_hoversel_add(win);
+   elm_hoversel_hover_parent_set(bt, win);
+   elm_hoversel_label_set(bt, "Disabled Hoversel");
+   elm_hoversel_item_add(bt, "Item 1", "apps", ELM_ICON_STANDARD, NULL, NULL);
+   elm_hoversel_item_add(bt, "Item 2", "close", ELM_ICON_STANDARD, NULL, NULL);
+   elm_object_disabled_set(bt, 1);
+   evas_object_size_hint_weight_set(bt, 0.0, 0.0);
+   evas_object_size_hint_align_set(bt, 0.5, 0.5);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_hoversel_add(win);
+   elm_hoversel_hover_parent_set(bt, win);
+   elm_hoversel_label_set(bt, "Icon + Label");
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/sky_03.jpg", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_hoversel_icon_set(bt, ic);
+   evas_object_show(ic);
+
+   elm_hoversel_item_add(bt, "Item 1", "apps", ELM_ICON_STANDARD, NULL, NULL);
+   elm_hoversel_item_add(bt, "Item 2", "arrow_down", ELM_ICON_STANDARD, NULL, NULL);
+   elm_hoversel_item_add(bt, "Item 3", "home", ELM_ICON_STANDARD, NULL, NULL);
+   elm_hoversel_item_add(bt, "Item 4", "close", ELM_ICON_STANDARD, NULL, NULL);
+   evas_object_size_hint_weight_set(bt, 0.0, 0.0);
+   evas_object_size_hint_align_set(bt, 0.5, 0.5);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   evas_object_resize(win, 320, 300);
+
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_icon.c b/src/bin/test_icon.c
new file mode 100644 (file)
index 0000000..9101225
--- /dev/null
@@ -0,0 +1,34 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+static void
+icon_clicked(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("clicked!\n");
+}
+
+void
+test_icon(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *ic;
+   char buf[PATH_MAX];
+
+   win = elm_win_add(NULL, "icon-transparent", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Icon Transparent");
+   elm_win_autodel_set(win, 1);
+   elm_win_alpha_set(win, 1);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   elm_icon_no_scale_set(ic, 1);
+   evas_object_size_hint_weight_set(ic, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_fill_set(ic, 0.5, 0.5);
+   elm_win_resize_object_add(win, ic);
+   evas_object_show(ic);
+
+   evas_object_smart_callback_add(ic, "clicked", icon_clicked, NULL);
+   
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_icon_desktops.c b/src/bin/test_icon_desktops.c
new file mode 100644 (file)
index 0000000..3a63ad0
--- /dev/null
@@ -0,0 +1,109 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+static Elm_Genlist_Item_Class it_desk;
+
+static char *
+desk_gl_label_get(const void *data, Evas_Object *obj, const char *part)
+{
+#ifdef ELM_EFREET   
+   Efreet_Desktop *d = (Efreet_Desktop *)data;
+   return strdup(d->name);
+#else
+   return NULL;
+#endif   
+}
+static Evas_Object *
+desk_gl_icon_get(const void *data, Evas_Object *obj, const char *part)
+{
+   // FIXME: elm_icon should grok this
+#ifdef ELM_EFREET   
+   Efreet_Desktop *d = (Efreet_Desktop *)data;
+   char *path;
+   Evas_Object *ic;
+   ic = elm_icon_add(obj);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+   if (!(!strcmp(part, "elm.swallow.icon"))) return ic;
+   if (!d->icon) return ic;
+   path = efreet_icon_path_find("default", d->icon, 48);
+   if (!path)
+     {
+        path = efreet_icon_path_find("hicolor", d->icon, 48);
+        if (!path)
+          {
+             path = efreet_icon_path_find("gnome", d->icon, 48);
+             if (!path)
+               {
+                  path = efreet_icon_path_find("Human", d->icon, 48);
+               }
+          }
+     }
+   if (path)
+     {
+        elm_icon_file_set(ic, path, NULL);
+        free(path);
+        return ic;
+     }
+   return ic;
+#else
+   return NULL;
+#endif   
+}
+static void
+desk_gl_del(const void *data, Evas_Object *obj)
+{
+#ifdef ELM_EFREET   
+   Efreet_Desktop *d = (Efreet_Desktop *)data;
+   efreet_desktop_free(d);
+#endif   
+}
+
+static void
+desktop_sel(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("sel\n");
+}
+
+void
+test_icon_desktops(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *gl;
+   Eina_List *desktops;
+
+   win = elm_win_add(NULL, "icon_desktops", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Icon Desktops");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+
+   it_desk.item_style     = "default";
+   it_desk.func.label_get = desk_gl_label_get;
+   it_desk.func.icon_get  = desk_gl_icon_get;
+   it_desk.func.state_get = NULL;
+   it_desk.func.del       = desk_gl_del;
+
+   gl = elm_genlist_add(win);
+   evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, gl);
+   evas_object_show(gl);
+
+#ifdef ELM_EFREET
+   elm_need_efreet();
+   desktops = efreet_util_desktop_name_glob_list("*");
+   if (desktops)
+     {
+        Efreet_Desktop *d;
+
+        EINA_LIST_FREE(desktops, d)
+         elm_genlist_item_append(gl, &it_desk, d,
+                                 NULL, ELM_GENLIST_ITEM_NONE,
+                                 desktop_sel, NULL);
+     }
+#endif
+
+   evas_object_resize(win, 320, 480);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_index.c b/src/bin/test_index.c
new file mode 100644 (file)
index 0000000..955f0b7
--- /dev/null
@@ -0,0 +1,93 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+static Elm_Genlist_Item_Class itci;
+char *gli_label_get(const void *data, Evas_Object *obj, const char *part)
+{
+   char buf[256];
+   int j = (int)data;
+   snprintf(buf, sizeof(buf), "%c%c", 
+            'A' + ((j >> 4) & 0xf),
+            'a' + ((j     ) & 0xf)
+            );
+   return strdup(buf);
+}
+
+void
+index_changed2(void *data, Evas_Object *obj, void *event_info)
+{
+   // called on a change but delayed in case multiple changes happen in a
+   // short timespan
+   elm_genlist_item_top_bring_in(event_info);
+}
+
+void
+index_changed(void *data, Evas_Object *obj, void *event_info)
+{
+   // this is calld on every change, no matter how often
+   // elm_genlist_item_bring_in(event_info);
+}
+
+void
+index_selected(void *data, Evas_Object *obj, void *event_info)
+{
+   // called on final select
+   elm_genlist_item_top_bring_in(event_info);
+}
+
+void
+test_index(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *gl, *id;
+   Elm_Genlist_Item *it;
+   int i, j;
+
+   win = elm_win_add(NULL, "index", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Index");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   gl = elm_genlist_add(win);
+   evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, gl);
+   evas_object_show(gl);
+   
+   id = elm_index_add(win);
+   evas_object_size_hint_weight_set(id, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, id);
+   
+   evas_object_show(id);
+
+   itci.item_style     = "default";
+   itci.func.label_get = gli_label_get;
+   itci.func.icon_get  = NULL;
+   itci.func.state_get = NULL;
+   itci.func.del       = NULL;
+
+   j = 0;
+   for (i = 0; i < 100; i++)
+     {
+        it = elm_genlist_item_append(gl, &itci,
+                                     (void *)j/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, NULL/* func */,
+                                     NULL/* func data */);
+        if ((j & 0xf) == 0)
+          {
+             char buf[32];
+             
+             snprintf(buf, sizeof(buf), "%c", 'A' + ((j >> 4) & 0xf));
+             elm_index_item_append(id, buf, it);
+          }
+        j += 2;
+     }
+   evas_object_smart_callback_add(id, "delay,changed", index_changed2, NULL);
+   evas_object_smart_callback_add(id, "changed", index_changed, NULL);
+   evas_object_smart_callback_add(id, "selected", index_selected, NULL);
+   elm_index_item_go(id, 0);
+
+   evas_object_resize(win, 320, 480);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_inwin.c b/src/bin/test_inwin.c
new file mode 100644 (file)
index 0000000..959057b
--- /dev/null
@@ -0,0 +1,68 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+void
+test_inwin(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *inwin, *lb;
+
+   win = elm_win_add(NULL, "inwin", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Inwin");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   inwin = elm_win_inwin_add(win);
+   evas_object_show(inwin);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb,
+                      "This is an \"inwin\" - a window in a<br>"
+                      "window. This is handy for quick popups<br>"
+                      "you want centered, taking over the window<br>"
+                      "until dismissed somehow. Unlike hovers they<br>"
+                      "don't hover over their target.");
+   elm_win_inwin_content_set(inwin, lb);
+   evas_object_show(lb);
+
+   evas_object_resize(win, 320, 240);
+   evas_object_show(win);
+}
+
+void
+test_inwin2(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *inwin, *lb;
+
+   win = elm_win_add(NULL, "inwin", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Inwin");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   inwin = elm_win_inwin_add(win);
+   elm_object_style_set(inwin, "minimal_vertical");
+   evas_object_show(inwin);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb,
+                      "This is an \"inwin\" - a window in a<br>"
+                      "window. This is handy for quick popups<br>"
+                      "you want centered, taking over the window<br>"
+                      "until dismissed somehow. Unlike hovers they<br>"
+                      "don't hover over their target.<br>"
+                      "<br>"
+                      "This inwin style compacts itself vertically<br>"
+                      "to the size of its contents minimum size.");
+   elm_win_inwin_content_set(inwin, lb);
+   evas_object_show(lb);
+
+   evas_object_resize(win, 320, 240);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_label.c b/src/bin/test_label.c
new file mode 100644 (file)
index 0000000..633474f
--- /dev/null
@@ -0,0 +1,75 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+
+void
+test_label(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *lb;
+
+   win = elm_win_add(NULL, "label", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Label");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb, 
+                       "<b>This is a small label</b>"
+                       );
+   evas_object_size_hint_weight_set(lb, 0.0, 0.0);
+   evas_object_size_hint_align_set(lb, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx, lb);
+   evas_object_show(lb);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb, 
+                       "This is a larger label with newlines<br>"
+                       "to make it bigger, bit it won't expand or wrap<br>"
+                       "just be a block of text that can't change its<br>"
+                       "formatting as it's fixed based on text<br>"
+                       );
+   evas_object_size_hint_weight_set(lb, 0.0, 0.0);
+   evas_object_size_hint_align_set(lb, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx, lb);
+   evas_object_show(lb);
+
+   lb = elm_label_add(win);
+   elm_label_line_wrap_set(lb, 1);
+   elm_label_label_set(lb,
+                       "<b>"
+                       "This is more text designed to line-wrap here as "
+                       "This object is resized horizontally. As it is "
+                       "resized vertically though, nothing should change. "
+                       "The amount of space allocated vertically should "
+                       "change as horizontal size changes."
+                       "</b>"
+                       );
+   evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(lb, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx, lb);
+   evas_object_show(lb);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb, 
+                       "This small label set to wrap"
+                       );
+   evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(lb, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx, lb);
+   evas_object_show(lb);
+
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+   
+   evas_object_resize(win, 320, 300);
+
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_launcher.c b/src/bin/test_launcher.c
new file mode 100644 (file)
index 0000000..d184dc2
--- /dev/null
@@ -0,0 +1,376 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+
+static void
+mode_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win = data;
+   Evas_Object *mb;
+   Eina_List *mbs, *l;
+   
+   mbs = evas_object_data_get(win, "mbs");
+   EINA_LIST_FOREACH(mbs, l, mb)
+     {
+        if (elm_mapbuf_enabled_get(mb))
+          elm_mapbuf_enabled_set(mb, 0);
+        else
+          elm_mapbuf_enabled_set(mb, 1);
+     }
+}
+
+static void
+full_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win = data;
+   elm_win_fullscreen_set(win, !elm_win_fullscreen_get(win));
+}
+
+static void
+alpha_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win = data;
+   Evas_Object *mb;
+   Eina_List *mbs, *l;
+   
+   mbs = evas_object_data_get(win, "mbs");
+   EINA_LIST_FOREACH(mbs, l, mb)
+     {
+        elm_mapbuf_alpha_set(mb, elm_check_state_get(obj));
+     }
+}
+
+static void
+smooth_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win = data;
+   Evas_Object *mb;
+   Eina_List *mbs, *l;
+   
+   mbs = evas_object_data_get(win, "mbs");
+   EINA_LIST_FOREACH(mbs, l, mb)
+     {
+        elm_mapbuf_smooth_set(mb, elm_check_state_get(obj));
+     }
+}
+
+static void
+close_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   evas_object_del(data);
+}
+
+static void
+ic_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+   evas_object_color_set(data, 128, 0, 0, 128);
+}
+
+static void
+ic_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+   evas_object_color_set(data, 255, 255, 255, 255);
+}
+
+void
+test_launcher(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *sc, *tb, *pad, *bt, *ic, *lb, *tb2, *mb, *ck, *bx, *rc;
+   int i, j, k, n, m;
+   char buf[PATH_MAX];
+   const char *names[] =
+     {
+        "Hello",    "World",    "Spam",  "Egg", 
+        "Ham",      "Good",     "Bad",   "Milk", 
+        "Smell",    "Of",       "Sky",   "Gold",
+        "Hole",     "Pig",      "And",   "Calm"
+     };
+   Eina_List *mbs = NULL;
+   
+   win = elm_win_add(NULL, "launcher", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Launcher");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/sky_04.jpg", PACKAGE_DATA_DIR);
+   elm_bg_file_set(bg, buf, NULL);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+   
+   bx = elm_box_add(win);
+   elm_box_homogenous_set(bx, 1);
+   elm_box_horizontal_set(bx, 1);
+   
+   n = 0; m = 0;
+   for (k = 0 ; k < 8; k++)
+     {
+        tb = elm_table_add(win);
+        evas_object_size_hint_weight_set(tb, 0.0, 0.0);
+        evas_object_size_hint_align_set(tb, 0.5, 0.5);
+
+        pad = evas_object_rectangle_add(evas_object_evas_get(win));
+        evas_object_size_hint_min_set(pad, 470, 4);
+        evas_object_size_hint_weight_set(pad, 0.0, 0.0);
+        evas_object_size_hint_align_set(pad, EVAS_HINT_FILL, EVAS_HINT_FILL);
+        elm_table_pack(tb, pad, 1, 0, 5, 1);
+        
+        pad = evas_object_rectangle_add(evas_object_evas_get(win));
+        evas_object_size_hint_min_set(pad, 470, 4);
+        evas_object_size_hint_weight_set(pad, 0.0, 0.0);
+        evas_object_size_hint_align_set(pad, EVAS_HINT_FILL, EVAS_HINT_FILL);
+        elm_table_pack(tb, pad, 1, 11, 5, 1);
+        
+        pad = evas_object_rectangle_add(evas_object_evas_get(win));
+        evas_object_size_hint_min_set(pad, 4, 4);
+        evas_object_size_hint_weight_set(pad, 0.0, 0.0);
+        evas_object_size_hint_align_set(pad, EVAS_HINT_FILL, EVAS_HINT_FILL);
+        elm_table_pack(tb, pad, 0, 1, 1, 10);
+        
+        pad = evas_object_rectangle_add(evas_object_evas_get(win));
+        evas_object_size_hint_min_set(pad, 4, 4);
+        evas_object_size_hint_weight_set(pad, 0.0, 0.0);
+        evas_object_size_hint_align_set(pad, EVAS_HINT_FILL, EVAS_HINT_FILL);
+        elm_table_pack(tb, pad, 6, 1, 1, 10);
+
+        for (j = 0; j < 5; j++)
+          {
+             for (i = 0; i < 5; i++)
+               {
+                  ic = elm_icon_add(win);
+                  elm_object_scale_set(ic, 0.5);
+                  snprintf(buf, sizeof(buf), "%s/images/icon_%02i.png", PACKAGE_DATA_DIR, n);
+                  elm_icon_file_set(ic, buf, NULL);
+                  elm_icon_scale_set(ic, 0, 0);
+                  evas_object_size_hint_weight_set(ic, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+                  evas_object_size_hint_align_set(ic, 0.5, 0.5);
+                  elm_table_pack(tb, ic, 1 + i, 1 + (j * 2), 1, 1);
+                  evas_object_show(ic);
+                  
+                  lb = elm_label_add(win);
+                  elm_object_style_set(lb, "marker");
+                  elm_label_label_set(lb, names[m]);
+                  evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+                  evas_object_size_hint_align_set(lb, 0.5, 0.5);
+                  elm_table_pack(tb, lb, 1 + i, 1 + (j * 2) + 1, 1, 1);
+                  evas_object_show(lb);
+                  
+                  rc = evas_object_rectangle_add(evas_object_evas_get(win));
+                  evas_object_color_set(rc, 0, 0, 0, 0);
+                  evas_object_size_hint_weight_set(rc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+                  evas_object_size_hint_align_set(rc, EVAS_HINT_FILL, EVAS_HINT_FILL);
+                  elm_table_pack(tb, rc, 1 + i, 1 + (j * 2), 1, 2);
+                  evas_object_show(rc);
+                  
+                  evas_object_event_callback_add(rc, EVAS_CALLBACK_MOUSE_DOWN, ic_down_cb, lb);
+                  evas_object_event_callback_add(rc, EVAS_CALLBACK_MOUSE_UP,   ic_up_cb,   lb);
+                  
+                  evas_object_event_callback_add(rc, EVAS_CALLBACK_MOUSE_DOWN, ic_down_cb, ic);
+                  evas_object_event_callback_add(rc, EVAS_CALLBACK_MOUSE_UP,   ic_up_cb,   ic);
+                  
+                  n++; if (n > 23) n = 0;
+                  m++; if (m > 15) m = 0;
+               }
+          }
+        mb = elm_mapbuf_add(win);
+        elm_mapbuf_content_set(mb, tb);
+        evas_object_show(tb);
+        
+        elm_box_pack_end(bx, mb);
+        evas_object_show(mb);
+        
+        mbs = eina_list_append(mbs, mb);
+     }
+
+   // fixme: free mbs
+   evas_object_data_set(win, "mbs", mbs);
+   
+   sc = elm_scroller_add(win);
+   elm_scroller_bounce_set(sc, 1, 0);
+   elm_scroller_policy_set(sc, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
+   evas_object_size_hint_weight_set(sc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, sc);
+   
+   elm_scroller_content_set(sc, bx);
+   evas_object_show(bx);
+   
+   elm_scroller_page_relative_set(sc, 1.0, 1.0);
+   evas_object_show(sc);
+
+   tb2 = elm_table_add(win);
+   evas_object_size_hint_weight_set(tb2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, tb2);
+   
+   ck = elm_check_add(win);
+   elm_check_label_set(ck, "Map");
+   elm_check_state_set(ck, 0);
+   evas_object_smart_callback_add(ck, "changed", mode_cb, win);
+   evas_object_size_hint_weight_set(ck, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ck, 0.05, 0.99);
+   elm_table_pack(tb2, ck, 0, 0, 1, 1);
+   evas_object_show(ck);
+   
+   ck = elm_check_add(win);
+   elm_check_label_set(ck, "A");
+   elm_check_state_set(ck, 1);
+   evas_object_smart_callback_add(ck, "changed", alpha_cb, win);
+   evas_object_size_hint_weight_set(ck, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ck, 0.20, 0.99);
+   elm_table_pack(tb2, ck, 1, 0, 1, 1);
+   evas_object_show(ck);
+   
+   ck = elm_check_add(win);
+   elm_check_label_set(ck, "Smo");
+   elm_check_state_set(ck, 1);
+   evas_object_smart_callback_add(ck, "changed", smooth_cb, win);
+   evas_object_size_hint_weight_set(ck, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ck, 0.40, 0.99);
+   elm_table_pack(tb2, ck, 2, 0, 1, 1);
+   evas_object_show(ck);
+   
+   ck = elm_check_add(win);
+   elm_check_label_set(ck, "FS");
+   elm_check_state_set(ck, 0);
+   evas_object_smart_callback_add(ck, "changed", full_cb, win);
+   evas_object_size_hint_weight_set(ck, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ck, 0.5, 0.99);
+   elm_table_pack(tb2, ck, 3, 0, 1, 1);
+   evas_object_show(ck);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Close");
+   evas_object_smart_callback_add(bt, "clicked", close_cb, win);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.95, 0.99);
+   elm_table_pack(tb2, bt, 4, 0, 1, 1);
+   evas_object_show(bt);
+   
+   evas_object_show(tb2);
+
+   evas_object_resize(win, 480, 800);
+   evas_object_show(win);
+}
+
+void
+test_launcher2(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *sc, *tb, *pad, *bt, *ic, *lb, *tb2, *mb, *ck, *bx, *rc, *ly;
+   int i, j, k, n, m;
+   char buf[PATH_MAX];
+   Eina_List *mbs = NULL;
+   
+   win = elm_win_add(NULL, "launcher", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Launcher");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/sky_03.jpg", PACKAGE_DATA_DIR);
+   elm_bg_file_set(bg, buf, NULL);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+   
+   bx = elm_box_add(win);
+   elm_box_homogenous_set(bx, 1);
+   elm_box_horizontal_set(bx, 1);
+   
+   for (k = 0 ; k < 8; k++)
+     {
+        ly = elm_layout_add(win);
+        snprintf(buf, sizeof(buf), "%s/objects/test.edj", PACKAGE_DATA_DIR);
+        elm_layout_file_set(ly, buf, "layout");
+        evas_object_size_hint_weight_set(ly, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Button 1");
+        elm_layout_content_set(ly, "element1", bt);
+        evas_object_show(bt);
+        
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Button 2");
+        elm_layout_content_set(ly, "element2", bt);
+        evas_object_show(bt);
+        
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Button 3");
+        elm_layout_content_set(ly, "element3", bt);
+        evas_object_show(bt);
+        
+        mb = elm_mapbuf_add(win);
+        elm_mapbuf_content_set(mb, ly);
+        evas_object_show(ly);
+        
+        elm_box_pack_end(bx, mb);
+        evas_object_show(mb);
+        
+        mbs = eina_list_append(mbs, mb);
+     }
+
+   // fixme: free mbs
+   evas_object_data_set(win, "mbs", mbs);
+   
+   sc = elm_scroller_add(win);
+   elm_scroller_bounce_set(sc, 1, 0);
+   elm_scroller_policy_set(sc, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
+   evas_object_size_hint_weight_set(sc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, sc);
+   
+   elm_scroller_content_set(sc, bx);
+   evas_object_show(bx);
+   
+   elm_scroller_page_relative_set(sc, 1.0, 1.0);
+   evas_object_show(sc);
+
+   tb2 = elm_table_add(win);
+   evas_object_size_hint_weight_set(tb2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, tb2);
+   
+   ck = elm_check_add(win);
+   elm_check_label_set(ck, "Map");
+   elm_check_state_set(ck, 0);
+   evas_object_smart_callback_add(ck, "changed", mode_cb, win);
+   evas_object_size_hint_weight_set(ck, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ck, 0.05, 0.99);
+   elm_table_pack(tb2, ck, 0, 0, 1, 1);
+   evas_object_show(ck);
+   
+   ck = elm_check_add(win);
+   elm_check_label_set(ck, "A");
+   elm_check_state_set(ck, 1);
+   evas_object_smart_callback_add(ck, "changed", alpha_cb, win);
+   evas_object_size_hint_weight_set(ck, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ck, 0.20, 0.99);
+   elm_table_pack(tb2, ck, 1, 0, 1, 1);
+   evas_object_show(ck);
+   
+   ck = elm_check_add(win);
+   elm_check_label_set(ck, "Smo");
+   elm_check_state_set(ck, 1);
+   evas_object_smart_callback_add(ck, "changed", smooth_cb, win);
+   evas_object_size_hint_weight_set(ck, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ck, 0.40, 0.99);
+   elm_table_pack(tb2, ck, 2, 0, 1, 1);
+   evas_object_show(ck);
+   
+   ck = elm_check_add(win);
+   elm_check_label_set(ck, "FS");
+   elm_check_state_set(ck, 0);
+   evas_object_smart_callback_add(ck, "changed", full_cb, win);
+   evas_object_size_hint_weight_set(ck, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ck, 0.5, 0.99);
+   elm_table_pack(tb2, ck, 3, 0, 1, 1);
+   evas_object_show(ck);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Close");
+   evas_object_smart_callback_add(bt, "clicked", close_cb, win);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.95, 0.99);
+   elm_table_pack(tb2, bt, 4, 0, 1, 1);
+   evas_object_show(bt);
+   
+   evas_object_show(tb2);
+
+   evas_object_resize(win, 480, 800);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_layout.c b/src/bin/test_layout.c
new file mode 100644 (file)
index 0000000..728ed24
--- /dev/null
@@ -0,0 +1,42 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+void
+test_layout(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *ly, *bt;
+   char buf[PATH_MAX];
+
+   win = elm_win_add(NULL, "layout", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Layout");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   ly = elm_layout_add(win);
+   snprintf(buf, sizeof(buf), "%s/objects/test.edj", PACKAGE_DATA_DIR);
+   elm_layout_file_set(ly, buf, "layout");
+   evas_object_size_hint_weight_set(ly, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, ly);
+   evas_object_show(ly);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button 1");
+   elm_layout_content_set(ly, "element1", bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button 2");
+   elm_layout_content_set(ly, "element2", bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button 3");
+   elm_layout_content_set(ly, "element3", bt);
+   evas_object_show(bt);
+
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_list.c b/src/bin/test_list.c
new file mode 100644 (file)
index 0000000..af5282b
--- /dev/null
@@ -0,0 +1,368 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+static void
+my_show_it(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_list_item_show(data);
+}
+
+void
+test_list(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *li, *ic, *ic2, *bx, *tb2, *bt;
+   char buf[PATH_MAX];
+   Elm_List_Item *it1, *it2, *it3, *it4, *it5;
+
+   win = elm_win_add(NULL, "list", ELM_WIN_BASIC);
+   elm_win_title_set(win, "List");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   li = elm_list_add(win);
+   elm_win_resize_object_add(win, li);
+   evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 1, 1);
+   it1 = elm_list_item_append(li, "Hello", ic, NULL,  NULL, NULL);
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_scale_set(ic, 0, 0);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_list_item_append(li, "world", ic, NULL,  NULL, NULL);
+   ic = elm_icon_add(win);
+   elm_icon_standard_set(ic, "edit");
+   elm_icon_scale_set(ic, 0, 0);
+   elm_list_item_append(li, ".", ic, NULL,  NULL, NULL);
+
+   ic = elm_icon_add(win);
+   elm_icon_standard_set(ic, "delete");
+   elm_icon_scale_set(ic, 0, 0);
+   ic2 = elm_icon_add(win);
+   elm_icon_standard_set(ic2, "clock");
+   elm_icon_scale_set(ic2, 0, 0);
+   it2 = elm_list_item_append(li, "How", ic, ic2,  NULL, NULL);
+
+   bx = elm_box_add(win);
+   elm_box_horizontal_set(bx, 1);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   evas_object_size_hint_align_set(ic, 0.5, 0.5);
+   elm_box_pack_end(bx, ic);
+   evas_object_show(ic);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   evas_object_size_hint_align_set(ic, 0.5, 0.0);
+   elm_box_pack_end(bx, ic);
+   evas_object_show(ic);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   evas_object_size_hint_align_set(ic, 0.0, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx, ic);
+   evas_object_show(ic);
+   elm_list_item_append(li, "are", bx, NULL,  NULL, NULL);
+
+   elm_list_item_append(li, "you", NULL, NULL,  NULL, NULL);
+   it3 = elm_list_item_append(li, "doing", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "out", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "there", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "today", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "?", NULL, NULL,  NULL, NULL);
+   it4 = elm_list_item_append(li, "Here", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "are", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "some", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "more", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "items", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "Is this label long enough?", NULL, NULL,  NULL, NULL);
+   it5 = elm_list_item_append(li, "Maybe this one is even longer so we can test long long items.", NULL, NULL,  NULL, NULL);
+
+   elm_list_go(li);
+
+   evas_object_show(li);
+   
+   tb2 = elm_table_add(win);
+   evas_object_size_hint_weight_set(tb2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, tb2);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Hello");
+   evas_object_smart_callback_add(bt, "clicked", my_show_it, it1);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.9, 0.5);
+   elm_table_pack(tb2, bt, 0, 0, 1, 1);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "How");
+   evas_object_smart_callback_add(bt, "clicked", my_show_it, it2);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.9, 0.5);
+   elm_table_pack(tb2, bt, 0, 1, 1, 1);
+   evas_object_show(bt);   
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "doing");
+   evas_object_smart_callback_add(bt, "clicked", my_show_it, it3);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.9, 0.5);
+   elm_table_pack(tb2, bt, 0, 2, 1, 1);
+   evas_object_show(bt);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Here");
+   evas_object_smart_callback_add(bt, "clicked", my_show_it, it4);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.9, 0.5);
+   elm_table_pack(tb2, bt, 0, 3, 1, 1);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Maybe this...");
+   evas_object_smart_callback_add(bt, "clicked", my_show_it, it5);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.9, 0.5);
+   elm_table_pack(tb2, bt, 0, 4, 1, 1);
+   evas_object_show(bt);
+
+   evas_object_show(tb2);
+   
+   evas_object_resize(win, 320, 300);
+   evas_object_show(win);
+}
+
+/***********/
+
+static void
+my_li2_clear(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_list_clear(data);
+}
+
+static void
+my_li2_sel(void *data, Evas_Object *obj, void *event_info)
+{
+   Elm_List_Item *it = elm_list_selected_item_get(obj);
+   elm_list_item_selected_set(it, 0);
+//   elm_list_item_selected_set(event_info, 0);
+}
+
+void
+test_list2(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *li, *ic, *ic2, *bx, *bx2, *bt;
+   char buf[PATH_MAX];
+   Elm_List_Item *it;
+
+   win = elm_win_add(NULL, "list-2", ELM_WIN_BASIC);
+   elm_win_title_set(win, "List 2");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/plant_01.jpg", PACKAGE_DATA_DIR);
+   elm_bg_file_set(bg, buf, NULL);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   li = elm_list_add(win);
+   evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_list_horizontal_mode_set(li, ELM_LIST_LIMIT);
+//   elm_list_multi_select_set(li, 1);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   it = elm_list_item_append(li, "Hello", ic, NULL,  my_li2_sel, NULL);
+   elm_list_item_selected_set(it, 1);
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_scale_set(ic, 0, 0);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_list_item_append(li, "world", ic, NULL,  NULL, NULL);
+   ic = elm_icon_add(win);
+   elm_icon_standard_set(ic, "edit");
+   elm_icon_scale_set(ic, 0, 0);
+   elm_list_item_append(li, ".", ic, NULL,  NULL, NULL);
+
+   ic = elm_icon_add(win);
+   elm_icon_standard_set(ic, "delete");
+   elm_icon_scale_set(ic, 0, 0);
+   ic2 = elm_icon_add(win);
+   elm_icon_standard_set(ic2, "clock");
+   elm_icon_scale_set(ic2, 0, 0);
+   elm_list_item_append(li, "How", ic, ic2,  NULL, NULL);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   evas_object_size_hint_align_set(ic, 0.5, 0.5);
+   elm_box_pack_end(bx2, ic);
+   evas_object_show(ic);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   evas_object_size_hint_align_set(ic, 0.5, 0.0);
+   elm_box_pack_end(bx2, ic);
+   evas_object_show(ic);
+   elm_list_item_append(li, "are", bx2, NULL, NULL, NULL);
+
+   elm_list_item_append(li, "you", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "doing", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "out", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "there", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "today", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "?", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "Here", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "are", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "some", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "more", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "items", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "Longer label.", NULL, NULL,  NULL, NULL);
+
+   elm_list_go(li);
+
+   elm_box_pack_end(bx, li);
+   evas_object_show(li);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   elm_box_homogenous_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Clear");
+   evas_object_smart_callback_add(bt, "clicked", my_li2_clear, li);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   evas_object_resize(win, 320, 300);
+   evas_object_show(win);
+}
+
+/***********/
+
+void
+test_list3(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *li, *ic, *ic2, *bx;
+   char buf[PATH_MAX];
+
+   win = elm_win_add(NULL, "list-3", ELM_WIN_BASIC);
+   elm_win_title_set(win, "List 3");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   li = elm_list_add(win);
+   elm_win_resize_object_add(win, li);
+   evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_list_horizontal_mode_set(li, ELM_LIST_COMPRESS);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_list_item_append(li, "Hello", ic, NULL,  NULL, NULL);
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_scale_set(ic, 0, 0);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_list_item_append(li, "world", ic, NULL,  NULL, NULL);
+   ic = elm_icon_add(win);
+   elm_icon_standard_set(ic, "edit");
+   elm_icon_scale_set(ic, 0, 0);
+   elm_list_item_append(li, ".", ic, NULL,  NULL, NULL);
+
+   ic = elm_icon_add(win);
+   elm_icon_standard_set(ic, "delete");
+   elm_icon_scale_set(ic, 0, 0);
+   ic2 = elm_icon_add(win);
+   elm_icon_standard_set(ic2, "clock");
+   elm_icon_scale_set(ic2, 0, 0);
+   elm_list_item_append(li, "How", ic, ic2,  NULL, NULL);
+
+   bx = elm_box_add(win);
+   elm_box_horizontal_set(bx, 1);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   evas_object_size_hint_align_set(ic, 0.5, 0.5);
+   elm_box_pack_end(bx, ic);
+   evas_object_show(ic);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   evas_object_size_hint_align_set(ic, 0.5, 0.0);
+   elm_box_pack_end(bx, ic);
+   evas_object_show(ic);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+   evas_object_size_hint_align_set(ic, 0.0, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx, ic);
+   evas_object_show(ic);
+
+   elm_list_item_append(li, "are", bx, NULL,  NULL, NULL);
+   elm_list_item_append(li, "you", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "doing", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "out", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "there", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "today", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "?", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "Here", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "are", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "some", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "more", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "items", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "Is this label long enough?", NULL, NULL,  NULL, NULL);
+   elm_list_item_append(li, "Maybe this one is even longer so we can test long long items.", NULL, NULL,  NULL, NULL);
+
+   elm_list_go(li);
+
+   evas_object_show(li);
+
+   evas_object_resize(win, 320, 300);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_map.c b/src/bin/test_map.c
new file mode 100644 (file)
index 0000000..4adbb1f
--- /dev/null
@@ -0,0 +1,610 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+
+typedef struct Marker_Data
+{
+    const char *file;
+} Marker_Data;
+
+
+static Elm_Map_Marker_Class *itc1, *itc2, *itc_parking;
+static Elm_Map_Group_Class *itc_group1, *itc_group2, *itc_group_parking;
+
+static Evas_Object *rect;
+static int nb_elts;
+
+Marker_Data data1 = {PACKAGE_DATA_DIR"/images/logo.png"};
+Marker_Data data2 = {PACKAGE_DATA_DIR"/images/logo_small.png"};
+Marker_Data data3 = {PACKAGE_DATA_DIR"/images/panel_01.jpg"};
+Marker_Data data4 = {PACKAGE_DATA_DIR"/images/plant_01.jpg"};
+Marker_Data data5 = {PACKAGE_DATA_DIR"/images/rock_01.jpg"};
+Marker_Data data6 = {PACKAGE_DATA_DIR"/images/rock_02.jpg"};
+Marker_Data data7 = {PACKAGE_DATA_DIR"/images/sky_01.jpg"};
+Marker_Data data8 = {PACKAGE_DATA_DIR"/images/sky_02.jpg"};
+Marker_Data data9 = {PACKAGE_DATA_DIR"/images/sky_03.jpg"};
+Marker_Data data10 = {PACKAGE_DATA_DIR"/images/sky_03.jpg"};
+Marker_Data data11= {PACKAGE_DATA_DIR"/images/wood_01.jpg"};
+
+Marker_Data data_parking= {PACKAGE_DATA_DIR"/images/parking.png"};
+
+static void
+my_map_clicked(void *data, Evas_Object *obj, void *event_info)
+{
+   //Evas_Object *win = data;
+   printf("clicked\n");
+}
+
+static void
+my_map_press(void *data, Evas_Object *obj, void *event_info)
+{
+   //Evas_Object *win = data;
+   printf("press\n");
+}
+
+static void
+my_map_longpressed(void *data, Evas_Object *obj, void *event_info)
+{
+   //Evas_Object *win = data;
+   printf("longpressed\n");
+}
+
+static void
+my_map_clicked_double(void *data, Evas_Object *obj, void *event_info)
+{
+   //Evas_Object *win = data;
+   printf("clicked,double\n");
+}
+
+static void
+my_map_load(void *data, Evas_Object *obj, void *event_info)
+{
+   //Evas_Object *win = data;
+   printf("load\n");
+}
+
+static void
+my_map_loaded(void *data, Evas_Object *obj, void *event_info)
+{
+   //Evas_Object *win = data;
+   printf("loaded\n");
+}
+
+static void
+my_map_load_details(void *data, Evas_Object *obj, void *event_info)
+{
+   //Evas_Object *win = data;
+   printf("load,details\n");
+}
+
+static void
+my_map_loaded_details(void *data, Evas_Object *obj, void *event_info)
+{
+   //Evas_Object *win = data;
+   printf("loaded,details\n");
+}
+
+static void
+my_map_zoom_start(void *data, Evas_Object *obj, void *event_info)
+{
+   //Evas_Object *win = data;
+   printf("zoom,start\n");
+}
+
+static void
+my_map_zoom_stop(void *data, Evas_Object *obj, void *event_info)
+{
+   //Evas_Object *win = data;
+   printf("zoom,stop\n");
+}
+
+static void
+my_map_zoom_change(void *data, Evas_Object *obj, void *event_info)
+{
+   //Evas_Object *win = data;
+   printf("zoom,change\n");
+}
+
+static void
+my_map_anim_start(void *data, Evas_Object *obj, void *event_info)
+{
+   //Evas_Object *win = data;
+   printf("anim,start\n");
+}
+
+static void
+my_map_anim_stop(void *data, Evas_Object *obj, void *event_info)
+{
+   //Evas_Object *win = data;
+   printf("anim,stop\n");
+}
+
+static void
+my_map_drag_start(void *data, Evas_Object *obj, void *event_info)
+{
+   //Evas_Object *win = data;
+   printf("drag,start\n");
+}
+
+static void
+my_map_drag_stop(void *data, Evas_Object *obj, void *event_info)
+{
+   //Evas_Object *win = data;
+   printf("drag_stop\n");
+}
+
+static void
+my_map_scroll(void *data, Evas_Object *obj, void *event_info)
+{
+   //Evas_Object *win = data;
+   double lon, lat;
+   elm_map_geo_region_get(obj, &lon, &lat);
+   printf("scroll longitude : %f latitude : %f\n", lon, lat);
+}
+
+static void
+my_bt_show_reg(void *data, Evas_Object *obj, void *event_info)
+{
+   Eina_Bool b = elm_map_paused_get(data);
+   elm_map_paused_set(data, EINA_TRUE);
+   elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL);
+   elm_map_geo_region_show(data, 2.352, 48.857);
+   elm_map_zoom_set(data, 18);
+   elm_map_paused_set(data, b);
+}
+
+static void
+my_bt_bring_reg(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_map_geo_region_bring_in(data, 2.352, 48.857);
+}
+
+static void
+my_bt_zoom_in(void *data, Evas_Object *obj, void *event_info)
+{
+   double zoom;
+
+   zoom = elm_map_zoom_get(data);
+   zoom += 1;
+   elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL);
+   if (zoom >= (1.0 / 32.0)) elm_map_zoom_set(data, zoom);
+}
+
+static void
+my_bt_zoom_out(void *data, Evas_Object *obj, void *event_info)
+{
+   double zoom;
+
+   zoom = elm_map_zoom_get(data);
+   zoom -= 1;
+   elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL);
+   if (zoom <= 256.0) elm_map_zoom_set(data, zoom);
+}
+
+static void
+my_bt_pause(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_map_paused_set(data, !elm_map_paused_get(data));
+}
+
+static void
+my_bt_markers_pause(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_map_paused_markers_set(data, !elm_map_paused_markers_get(data));
+}
+
+static void
+my_bt_zoom_fit(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_AUTO_FIT);
+}
+
+static void
+my_bt_zoom_fill(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_AUTO_FILL);
+}
+
+static void
+my_bt_source_mapnik(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_map_source_set(data, ELM_MAP_SOURCE_MAPNIK);
+}
+
+static void
+my_bt_source_osmarender(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_map_source_set(data, ELM_MAP_SOURCE_OSMARENDER);
+}
+
+static void
+my_bt_source_cyclemap(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_map_source_set(data, ELM_MAP_SOURCE_CYCLEMAP);
+}
+
+static void
+my_bt_source_maplint(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_map_source_set(data, ELM_MAP_SOURCE_MAPLINT);
+}
+
+static void
+my_bt_add(void *data, Evas_Object *obj, void *event_info)
+{
+    int i;
+    Elm_Map_Group_Class *g_clas;
+    Elm_Map_Marker_Class *m_clas;
+    Marker_Data *d = &data7;
+
+    for(i =0; i<1000; i++)
+    {
+        d = &data7;
+
+        int r1 = rand() % (180*2*100);
+        if(r1<=180) r1 = -r1;
+        else r1 = r1 - 180*100;
+
+        int r2 = rand() % (85*2*100);
+        if(r2<=85) r2 = -r2;
+        else r2 = r2 - 85*100;
+
+        int style = rand() % 3;
+        if(!style)
+            m_clas = itc1;
+        else if(style == 1)
+            m_clas = itc2;
+        else
+        {
+            m_clas = itc_parking;
+            g_clas = itc_group_parking;
+            d = &data_parking;
+        }
+
+       style = rand() % 2;
+       if (!style)
+         g_clas = itc_group1;
+       else
+         g_clas = itc_group2;
+
+       elm_map_marker_add(data, r1/100., r2/100., m_clas, g_clas, d); 
+    }
+    nb_elts+=1000;
+    printf("nb elements: %d\n", nb_elts);
+}
+
+static Evas_Object *
+_marker_get(Evas_Object *obj, Elm_Map_Marker *marker, void *data)
+{
+    Marker_Data *d = data;
+
+    Evas_Object *bx = elm_box_add(obj);
+    evas_object_show(bx);
+
+    if(d == &data3)
+    {
+        Evas_Object *icon = elm_icon_add(obj);
+        elm_icon_file_set(icon, d->file, NULL);
+        evas_object_show(icon);
+
+        Evas_Object *o = elm_button_add(obj);
+        elm_button_icon_set(o, icon);
+        evas_object_show(o);
+        elm_box_pack_end(bx, o);
+    }
+    else
+    {
+        Evas_Object *o = evas_object_image_add(evas_object_evas_get(obj));
+        evas_object_image_file_set(o, d->file, NULL);
+        evas_object_image_filled_set(o, EINA_TRUE);
+        evas_object_size_hint_min_set(o, 64, 64);
+        evas_object_show(o);
+        elm_box_pack_end(bx, o);
+
+        Evas_Object *lbl = elm_label_add(obj);
+        elm_label_label_set(lbl, "Wolves Go !");
+        evas_object_show(lbl);
+        elm_box_pack_end(bx, lbl);
+    }
+
+    return bx;
+}
+
+static Evas_Object *
+_icon_get(Evas_Object *obj, Elm_Map_Marker *marker, void *data)
+{
+    Marker_Data *d = data;
+
+    Evas_Object *icon = elm_icon_add(obj);
+    elm_icon_file_set(icon, d->file, NULL);
+    evas_object_show(icon);
+
+    return icon;
+}
+
+static Evas_Object *
+_group_icon_get(Evas_Object *obj, void *data)
+{
+    char *file = data;
+
+    Evas_Object *icon = elm_icon_add(obj);
+    elm_icon_file_set(icon, file, NULL);
+    evas_object_show(icon);
+
+    return icon;
+}
+
+static void
+_map_mouse_wheel_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *map = data;
+   Evas_Event_Mouse_Wheel *ev = (Evas_Event_Mouse_Wheel*) event_info;
+   int zoom;
+   //unset the mouse wheel
+   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+
+   zoom = elm_map_zoom_get(map);
+
+   if (ev->z > 0)
+     zoom--;
+   else
+     zoom++;
+
+   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_MANUAL);
+   if (zoom >= 0 && zoom <= 18) elm_map_zoom_set(map, zoom);
+}
+
+static void 
+_map_move_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+   int x,y,w,h;
+
+   evas_object_geometry_get(data,&x,&y,&w,&h);
+   evas_object_resize(rect,w,h);
+   evas_object_move(rect,x,y);
+}
+
+void
+test_map(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *map, *tb2, *bt, *bx;
+
+   win = elm_win_add(NULL, "map", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Map");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+
+   map = elm_map_add(win);
+   if (map) 
+     {
+        srand( time(NULL) );
+
+        evas_object_size_hint_weight_set(map, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        elm_win_resize_object_add(win, map);
+        evas_object_data_set(map, "window", win);
+
+        //
+        itc1 = elm_map_marker_class_new(map);
+        elm_map_marker_class_get_cb_set(itc1, _marker_get);
+        elm_map_marker_class_del_cb_set(itc1, NULL);
+        itc2 = elm_map_marker_class_new(map);
+        elm_map_marker_class_get_cb_set(itc2, _marker_get);
+        elm_map_marker_class_del_cb_set(itc2, NULL);
+        elm_map_marker_class_style_set(itc2, "radio2");
+
+        itc_parking = elm_map_marker_class_new(map);
+        elm_map_marker_class_get_cb_set(itc_parking, _marker_get);
+        elm_map_marker_class_del_cb_set(itc_parking, NULL);
+        elm_map_marker_class_icon_cb_set(itc_parking, _icon_get);
+        elm_map_marker_class_style_set(itc_parking, "empty");
+        //
+
+        //
+        itc_group1 = elm_map_group_class_new(map);
+        elm_map_group_class_data_set(itc_group1, PACKAGE_DATA_DIR"/images/plant_01.jpg");
+
+        itc_group2 = elm_map_group_class_new(map);
+        elm_map_group_class_style_set(itc_group2, "radio2");
+        elm_map_group_class_zoom_displayed_set(itc_group1, 3);
+
+        itc_group_parking = elm_map_group_class_new(map);
+        elm_map_group_class_icon_cb_set(itc_group_parking, _group_icon_get);
+        elm_map_group_class_data_set(itc_group_parking,  PACKAGE_DATA_DIR"/images/parking.png");
+        elm_map_group_class_style_set(itc_group_parking, "empty");
+        elm_map_group_class_zoom_displayed_set(itc_group_parking, 5);
+        //
+
+
+        rect = evas_object_rectangle_add(evas_object_evas_get(win));
+        evas_object_color_set(rect, 0, 0, 0, 0);
+        evas_object_repeat_events_set(rect,1);
+        evas_object_show(rect);
+        evas_object_event_callback_add(rect, EVAS_CALLBACK_MOUSE_WHEEL, 
+                                       _map_mouse_wheel_cb, map);
+        evas_object_raise(rect);
+
+        evas_object_event_callback_add(map, EVAS_CALLBACK_RESIZE, 
+                                       _map_move_resize_cb, map);
+        evas_object_event_callback_add(map, EVAS_CALLBACK_MOVE, 
+                                       _map_move_resize_cb, map);
+
+        Elm_Map_Marker *marker = 
+          elm_map_marker_add(map, 2.352, 48.857, itc1, itc_group1, &data1);
+        marker = elm_map_marker_add(map, 2.355, 48.857, itc1, itc_group1, &data3);
+        marker = elm_map_marker_add(map, 3, 48.857, itc2, itc_group1, &data2);
+        marker = elm_map_marker_add(map, 2.352, 49, itc2, itc_group1, &data1);
+
+        marker = elm_map_marker_add(map, 7.31451, 48.857127, itc1, itc_group1, &data10);
+        marker = elm_map_marker_add(map, 7.314704, 48.857119, itc1, itc_group1, &data4);
+        marker = elm_map_marker_add(map, 7.314704, 48.857119, itc2, itc_group1, &data5);
+        marker = elm_map_marker_add(map, 7.31432, 48.856785, itc2, itc_group1, &data6);
+        marker = elm_map_marker_add(map, 7.3148, 48.85725, itc1, itc_group2, &data7);
+        marker = elm_map_marker_add(map, 7.316445, 48.8572210000694, itc1, itc_group1, &data8);
+        marker = elm_map_marker_add(map, 7.316527000125, 48.85609, itc2, itc_group2, &data9);
+        marker = elm_map_marker_add(map, 7.3165409990833, 48.856078, itc2, itc_group1, &data11);
+        marker = elm_map_marker_add(map, 7.319812, 48.856561, itc2, itc_group2, &data10);
+
+        nb_elts = 13;
+
+        evas_object_smart_callback_add(map, "clicked", my_map_clicked, win);
+        evas_object_smart_callback_add(map, "press", my_map_press, win);
+        evas_object_smart_callback_add(map, "longpressed", my_map_longpressed, win);
+        evas_object_smart_callback_add(map, "clicked,double", my_map_clicked_double, win);
+        evas_object_smart_callback_add(map, "load", my_map_load, win);
+        evas_object_smart_callback_add(map, "loaded", my_map_loaded, win);
+        evas_object_smart_callback_add(map, "load,details", my_map_load_details, win);
+        evas_object_smart_callback_add(map, "loaded,details", my_map_loaded_details, win);
+        evas_object_smart_callback_add(map, "zoom,start", my_map_zoom_start, win);
+        evas_object_smart_callback_add(map, "zoom,stop", my_map_zoom_stop, win);
+        evas_object_smart_callback_add(map, "zoom,change", my_map_zoom_change, win);
+        evas_object_smart_callback_add(map, "scroll,anim,start", my_map_anim_start, win);
+        evas_object_smart_callback_add(map, "scroll,anim,stop", my_map_anim_stop, win);
+        evas_object_smart_callback_add(map, "scroll,drag,start", my_map_drag_start, win);
+        evas_object_smart_callback_add(map, "scroll,drag,stop", my_map_drag_stop, win);
+        evas_object_smart_callback_add(map, "scroll", my_map_scroll, win);
+
+        evas_object_show(map);
+
+        tb2 = elm_table_add(win);
+        evas_object_size_hint_weight_set(tb2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        elm_win_resize_object_add(win, tb2);
+
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Z -");
+        evas_object_smart_callback_add(bt, "clicked", my_bt_zoom_out, map);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(bt, 0.1, 0.1);
+        elm_table_pack(tb2, bt, 0, 0, 1, 1);
+        evas_object_show(bt);
+
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Add 1000 markers");
+        evas_object_smart_callback_add(bt, "clicked", my_bt_add, map);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(bt, 0.5, 0.1);
+        elm_table_pack(tb2, bt, 1, 0, 1, 1);
+        evas_object_show(bt);
+
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Z +");
+        evas_object_smart_callback_add(bt, "clicked", my_bt_zoom_in, map);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(bt, 0.9, 0.1);
+        elm_table_pack(tb2, bt, 2, 0, 1, 1);
+        evas_object_show(bt);
+
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Show Paris");
+        evas_object_smart_callback_add(bt, "clicked", my_bt_show_reg, map);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(bt, 0.1, 0.5);
+        elm_table_pack(tb2, bt, 0, 1, 1, 1);
+        evas_object_show(bt);
+
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Bring Paris");
+        evas_object_smart_callback_add(bt, "clicked", my_bt_bring_reg, map);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(bt, 0.9, 0.5);
+        elm_table_pack(tb2, bt, 2, 1, 1, 1);
+        evas_object_show(bt);
+
+        //
+        bx = elm_box_add(win);
+        evas_object_show(bx);
+        evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(bx, 0.1, 0.9);
+        elm_table_pack(tb2, bx, 0, 2, 1, 1);
+
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Pause On/Off");
+        evas_object_smart_callback_add(bt, "clicked", my_bt_pause, map);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(bt, 0.1, 0.9);
+        evas_object_show(bt);
+        elm_box_pack_end(bx, bt);
+
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Markers pause On/Off");
+        evas_object_smart_callback_add(bt, "clicked", my_bt_markers_pause, map);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(bt, 0.1, 0.9);
+        evas_object_show(bt);
+        elm_box_pack_end(bx, bt);
+        //
+
+        //
+        bx = elm_box_add(win);
+        evas_object_show(bx);
+        evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(bx, 0.5, 0.9);
+        elm_table_pack(tb2, bx, 1, 2, 1, 1);
+
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Fit");
+        evas_object_smart_callback_add(bt, "clicked", my_bt_zoom_fit, map);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(bt, 0.5, 0.9);
+        evas_object_show(bt);
+        elm_box_pack_end(bx, bt);
+
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Fill");
+        evas_object_smart_callback_add(bt, "clicked", my_bt_zoom_fill, map);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(bt, 0.5, 0.9);
+        evas_object_show(bt);
+        elm_box_pack_end(bx, bt);
+        //
+
+        //
+        bx = elm_box_add(win);
+        evas_object_show(bx);
+        evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(bx, 1.0, 0.9);
+        elm_table_pack(tb2, bx, 2, 2, 1, 1);
+
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Mapnik");
+        evas_object_smart_callback_add(bt, "clicked", my_bt_source_mapnik, map);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(bt, 1.0, 0.9);
+        evas_object_show(bt);
+        elm_box_pack_end(bx, bt);
+
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Osmarender");
+        evas_object_smart_callback_add(bt, "clicked", my_bt_source_osmarender, map);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(bt, 1.0, 0.9);
+        evas_object_show(bt);
+        elm_box_pack_end(bx, bt);
+
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Cycle Map");
+        evas_object_smart_callback_add(bt, "clicked", my_bt_source_cyclemap, map);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(bt, 1.0, 0.9);
+        evas_object_show(bt);
+        elm_box_pack_end(bx, bt);
+
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Maplint");
+        evas_object_smart_callback_add(bt, "clicked", my_bt_source_maplint, map);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(bt, 1.0, 0.9);
+        evas_object_show(bt);
+        elm_box_pack_end(bx, bt);
+        //
+
+        evas_object_show(tb2);
+     }
+
+   evas_object_resize(win, 800, 800);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_menu.c b/src/bin/test_menu.c
new file mode 100644 (file)
index 0000000..3330b63
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+
+static Evas_Object *win, *bg, *menu, *rect, *ic;;
+static char buf[PATH_MAX];
+
+static void
+_show(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+   Evas_Event_Mouse_Down *ev = event_info; 
+   elm_menu_move(data, ev->canvas.x, ev->canvas.y);
+   evas_object_show(data);
+}
+
+static void 
+_populate_4(Elm_Menu_Item *item)
+{
+   Evas_Object *ic;
+   Elm_Menu_Item *item2, *item3;
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_menu_item_add(menu, item, ic, "menu 2", NULL, NULL);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+
+   item2 = elm_menu_item_add(menu, item, ic, "menu 3", NULL, NULL);
+   
+   elm_menu_item_separator_add(menu, item);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   item3 = elm_menu_item_add(menu, item, ic, "Disabled item", NULL, NULL);
+   elm_menu_item_disabled_set(item3, 1);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   item3 = elm_menu_item_add(menu, item, ic, "Disabled item", NULL, NULL);
+   elm_menu_item_disabled_set(item3, 1);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   item3 = elm_menu_item_add(menu, item, ic, "Disabled item", NULL, NULL);
+   elm_menu_item_disabled_set(item3, 1);
+}
+
+static void 
+_populate_3(Elm_Menu_Item *item)
+{
+   Evas_Object *ic;
+   Elm_Menu_Item *item2, *item3;
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_menu_item_add(menu, item, ic, "menu 2", NULL, NULL);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+
+   item2 = elm_menu_item_add(menu, item, ic, "menu 3", NULL, NULL);
+   
+   elm_menu_item_separator_add(menu,item);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   item3 = elm_menu_item_add(menu, item, ic, "Disabled item", NULL, NULL);
+   elm_menu_item_disabled_set(item3, 1);
+}
+
+static void 
+_populate_2(Elm_Menu_Item *item)
+{
+   Evas_Object *ic;
+   Elm_Menu_Item *item2, *item3;
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_menu_item_add(menu, item, ic, "menu 2", NULL, NULL);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+
+   item2 = elm_menu_item_add(menu, item, ic, "menu 3", NULL, NULL);
+   
+   _populate_3(item2);
+
+   elm_menu_item_separator_add(menu,item);
+   elm_menu_item_separator_add(menu,item);
+   elm_menu_item_separator_add(menu,item);
+   elm_menu_item_separator_add(menu,item);
+   elm_menu_item_separator_add(menu,item);
+   elm_menu_item_separator_add(menu,item);
+   elm_menu_item_separator_add(menu,item);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+
+   item2 = elm_menu_item_add(menu, item, ic, "menu 2", NULL, NULL);
+
+   elm_menu_item_separator_add(menu,item);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   item3 = elm_menu_item_add(menu, item, ic, "Disabled item", NULL, NULL);
+   elm_menu_item_disabled_set(item3, 1);
+
+   _populate_4(item2);
+}
+
+static void 
+_populate_1(Elm_Menu_Item *item)
+{
+   Elm_Menu_Item *item2;
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   item2 = elm_menu_item_add(menu, item, ic, "menu 1", NULL, NULL);
+
+   _populate_2(item2);
+}
+
+void
+test_menu(void *data, Evas_Object *obj, void *event_info)
+{
+   Elm_Menu_Item *item;
+
+   win = elm_win_add(NULL, "Menu", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Menu");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   rect = evas_object_rectangle_add(evas_object_evas_get(win));
+   elm_win_resize_object_add(win, rect);
+   evas_object_color_set(rect, 0, 0, 0, 0);
+   evas_object_show(rect);
+
+   menu = elm_menu_add(win);
+   item = elm_menu_item_add(menu, NULL, NULL, "first item", NULL, NULL);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+
+   item = elm_menu_item_add(menu, NULL, ic, "second item", NULL, NULL);
+   _populate_1(item);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_menu_item_add(menu, item, ic, "sub menu", NULL, NULL);
+
+   evas_object_event_callback_add(rect, EVAS_CALLBACK_MOUSE_DOWN, _show, menu);
+
+   evas_object_resize(win, 350, 200);
+   evas_object_show(win);
+}
+
+#endif
diff --git a/src/bin/test_multi.c b/src/bin/test_multi.c
new file mode 100644 (file)
index 0000000..b8ab882
--- /dev/null
@@ -0,0 +1,122 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+
+#define IND_NUM 20
+
+static Evas_Object *indicator[IND_NUM];
+
+static void
+_mouse_down(void *data, Evas *e, Evas_Object *o, void *event_info)
+{
+   Evas_Event_Mouse_Down *ev = event_info;
+//   Evas_Object *win = data;
+   
+   if (ev->button != 1) return;
+   printf("MOUSE: down @ %4i %4i\n", ev->canvas.x, ev->canvas.y);
+   evas_object_move(indicator[0], ev->canvas.x, ev->canvas.y);
+   evas_object_resize(indicator[0], 1, 1);
+   evas_object_show(indicator[0]);
+}
+
+static void
+_mouse_up(void *data, Evas *e, Evas_Object *o, void *event_info)
+{
+   Evas_Event_Mouse_Up *ev = event_info;
+//   Evas_Object *win = data;
+   if (ev->button != 1) return;
+   printf("MOUSE: up   @ %4i %4i\n", ev->canvas.x, ev->canvas.y);
+   evas_object_hide(indicator[0]);
+}
+
+static void
+_mouse_move(void *data, Evas *e, Evas_Object *o, void *event_info)
+{
+   Evas_Event_Mouse_Move *ev = event_info;
+//   Evas_Object *win = data;
+   printf("MOUSE: move @ %4i %4i\n", ev->cur.canvas.x, ev->cur.canvas.y);
+   evas_object_move(indicator[0], ev->cur.canvas.x, ev->cur.canvas.y);
+   evas_object_resize(indicator[0], 1, 1);
+}
+
+
+
+
+static void
+_multi_down(void *data, Evas *e, Evas_Object *o, void *event_info)
+{
+   Evas_Event_Multi_Down *ev = event_info;
+//   Evas_Object *win = data;
+   printf("MULTI: down @ %4i %4i | dev: %i\n", ev->canvas.x, ev->canvas.y, ev->device);
+   if (ev->device >= IND_NUM) return;
+   evas_object_move(indicator[ev->device], ev->canvas.x, ev->canvas.y);
+   evas_object_resize(indicator[ev->device], 1, 1);
+   evas_object_show(indicator[ev->device]);
+}
+
+static void
+_multi_up(void *data, Evas *e, Evas_Object *o, void *event_info)
+{
+   Evas_Event_Multi_Up *ev = event_info;
+//   Evas_Object *win = data;
+   printf("MULTI: up    @ %4i %4i | dev: %i\n", ev->canvas.x, ev->canvas.y, ev->device);
+   if (ev->device >= IND_NUM) return;
+   evas_object_hide(indicator[ev->device]);
+}
+
+static void
+_multi_move(void *data, Evas *e, Evas_Object *o, void *event_info)
+{
+   Evas_Event_Multi_Move *ev = event_info;
+//   Evas_Object *win = data;
+   printf("MULTI: move @ %4i %4i | dev: %i\n", ev->cur.canvas.x, ev->cur.canvas.y, ev->device);
+   if (ev->device >= IND_NUM) return;
+   evas_object_move(indicator[ev->device], ev->cur.canvas.x, ev->cur.canvas.y);
+   evas_object_resize(indicator[ev->device], 1, 1);
+}
+
+
+
+
+void
+test_multi(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *r;
+   int i;
+
+   win = elm_win_add(NULL, "bg-plain", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Bg Plain");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+
+   r = evas_object_rectangle_add(evas_object_evas_get(win));
+   evas_object_color_set(r, 0, 0, 0, 0);
+   elm_win_resize_object_add(win, r);
+   evas_object_show(r);
+   
+   for (i = 0; i < IND_NUM; i++)
+     {
+        char buf[PATH_MAX];
+        
+        snprintf(buf, sizeof(buf), "%s/objects/multip.edj", PACKAGE_DATA_DIR);
+        indicator[i] = edje_object_add(evas_object_evas_get(win));
+        edje_object_file_set(indicator[i], buf, "point");
+     }
+   
+   evas_object_event_callback_add(r, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, win);
+   evas_object_event_callback_add(r, EVAS_CALLBACK_MOUSE_UP, _mouse_up, win);
+   evas_object_event_callback_add(r, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, win);
+   evas_object_event_callback_add(r, EVAS_CALLBACK_MULTI_DOWN, _multi_down, win);
+   evas_object_event_callback_add(r, EVAS_CALLBACK_MULTI_UP, _multi_up, win);
+   evas_object_event_callback_add(r, EVAS_CALLBACK_MULTI_MOVE, _multi_move, win);
+
+   evas_object_size_hint_min_set(bg, 160, 160);
+   evas_object_resize(win, 480, 800);
+   
+   evas_object_show(win);
+}
+
+#endif
diff --git a/src/bin/test_notepad.c b/src/bin/test_notepad.c
new file mode 100644 (file)
index 0000000..5576b15
--- /dev/null
@@ -0,0 +1,97 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+static void
+my_notepad_bt_1(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *np = data;
+}
+
+static void
+my_notepad_bt_2(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *np = data;
+}
+
+static void
+my_notepad_bt_3(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *np = data;
+}
+
+void
+test_notepad(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *bx2, *bt, *ic, *np;
+
+   win = elm_win_add(NULL, "notepad", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Notepad");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   np = elm_notepad_add(win);
+   elm_notepad_file_set(np, "note.txt", ELM_TEXT_FORMAT_PLAIN_UTF8);
+   evas_object_size_hint_weight_set(np, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(np, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx, np);
+   evas_object_show(np);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   elm_box_homogenous_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   ic = elm_icon_add(win);
+   elm_icon_standard_set(ic, "arrow_left");
+   elm_icon_scale_set(ic, 1, 0);
+   elm_button_icon_set(bt, ic);
+   evas_object_show(ic);
+   evas_object_smart_callback_add(bt, "clicked", my_notepad_bt_1, np);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   ic = elm_icon_add(win);
+   elm_icon_standard_set(ic, "close");
+   elm_icon_scale_set(ic, 1, 0);
+   elm_button_icon_set(bt, ic);
+   evas_object_show(ic);
+   evas_object_smart_callback_add(bt, "clicked", my_notepad_bt_2, np);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   ic = elm_icon_add(win);
+   elm_icon_standard_set(ic, "arrow_right");
+   elm_icon_scale_set(ic, 1, 0);
+   elm_button_icon_set(bt, ic);
+   evas_object_show(ic);
+   evas_object_smart_callback_add(bt, "clicked", my_notepad_bt_3, np);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   evas_object_resize(win, 320, 300);
+
+   elm_object_focus(win);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_notify.c b/src/bin/test_notify.c
new file mode 100644 (file)
index 0000000..d1b38ef
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+
+static void
+_bt(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *notify = data;
+   evas_object_show(notify);
+}
+
+static void
+_bt_close(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *notify = data;
+   evas_object_hide(notify);
+}
+
+void
+test_notify(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *tb, *notify, *bt, *lb;
+
+   win = elm_win_add(NULL, "Notify", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Notify");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   tb = elm_table_add(win);
+   elm_win_resize_object_add(win, tb);
+   evas_object_size_hint_weight_set(tb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(tb);
+
+   notify = elm_notify_add(win);
+   evas_object_size_hint_weight_set(notify, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+   bx = elm_box_add(win);
+   elm_notify_content_set(notify, bx);
+   elm_box_horizontal_set(bx, 1);
+   evas_object_show(bx);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb, "This position is the default.");
+   elm_box_pack_end(bx, lb);
+   evas_object_show(lb);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Close");
+   evas_object_smart_callback_add(bt, "clicked", _bt_close, notify);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Top");
+   evas_object_smart_callback_add(bt, "clicked", _bt, notify);
+   elm_table_pack(tb, bt, 1, 0, 1, 1);
+   evas_object_show(bt);
+
+   notify = elm_notify_add(win);
+   elm_notify_repeat_events_set(notify, EINA_FALSE);
+   evas_object_size_hint_weight_set(notify, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_notify_orient_set(notify, ELM_NOTIFY_ORIENT_BOTTOM);
+   elm_notify_timeout_set(notify, 5);
+
+   bx = elm_box_add(win);
+   elm_notify_content_set(notify, bx);
+   elm_box_horizontal_set(bx, 1);
+   evas_object_show(bx);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb, "Bottom position. This notify use a timeout of 5 sec.<br>"
+        "<b>The events outside the window are blocked.</b>");
+   elm_box_pack_end(bx, lb);
+   evas_object_show(lb);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Close");
+   evas_object_smart_callback_add(bt, "clicked", _bt_close, notify);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Bottom");
+   evas_object_smart_callback_add(bt, "clicked", _bt, notify);
+   elm_table_pack(tb, bt, 1, 2, 1, 1);
+   evas_object_show(bt);
+
+   notify = elm_notify_add(win);
+   evas_object_size_hint_weight_set(notify, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_notify_orient_set(notify, ELM_NOTIFY_ORIENT_LEFT);
+   elm_notify_timeout_set(notify, 10);
+
+   bx = elm_box_add(win);
+   elm_notify_content_set(notify, bx);
+   elm_box_horizontal_set(bx, 1);
+   evas_object_show(bx);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb, "Left position. This notify use a timeout of 10 sec.");
+   elm_box_pack_end(bx, lb);
+   evas_object_show(lb);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Close");
+   evas_object_smart_callback_add(bt, "clicked", _bt_close, notify);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Left");
+   evas_object_smart_callback_add(bt, "clicked", _bt, notify);
+   elm_table_pack(tb, bt, 0, 1, 1, 1);
+   evas_object_show(bt);
+
+   notify = elm_notify_add(win);
+   evas_object_size_hint_weight_set(notify, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_notify_orient_set(notify, ELM_NOTIFY_ORIENT_CENTER);
+   elm_notify_timeout_set(notify, 10);
+
+   bx = elm_box_add(win);
+   elm_notify_content_set(notify, bx);
+   elm_box_horizontal_set(bx, 1);
+   evas_object_show(bx);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb, "Center position. This notify use a timeout of 10 sec.");
+   elm_box_pack_end(bx, lb);
+   evas_object_show(lb);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Close");
+   evas_object_smart_callback_add(bt, "clicked", _bt_close, notify);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Center");
+   evas_object_smart_callback_add(bt, "clicked", _bt, notify);
+   elm_table_pack(tb, bt, 1, 1, 1, 1);
+   evas_object_show(bt);
+
+   notify = elm_notify_add(win);
+   evas_object_size_hint_weight_set(notify, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_notify_orient_set(notify, ELM_NOTIFY_ORIENT_RIGHT);
+
+   bx = elm_box_add(win);
+   elm_notify_content_set(notify, bx);
+   elm_box_horizontal_set(bx, 1);
+   evas_object_show(bx);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb, "Right position.");
+   elm_box_pack_end(bx, lb);
+   evas_object_show(lb);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Close");
+   evas_object_smart_callback_add(bt, "clicked", _bt_close, notify);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Right");
+   evas_object_smart_callback_add(bt, "clicked", _bt, notify);
+   elm_table_pack(tb, bt, 2, 1, 1, 1);
+   evas_object_show(bt);
+
+   notify = elm_notify_add(win);
+   evas_object_size_hint_weight_set(notify, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_notify_orient_set(notify, ELM_NOTIFY_ORIENT_TOP_LEFT);
+
+   bx = elm_box_add(win);
+   elm_notify_content_set(notify, bx);
+   elm_box_horizontal_set(bx, 1);
+   evas_object_show(bx);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb, "Top Left position.");
+   elm_box_pack_end(bx, lb);
+   evas_object_show(lb);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Close");
+   evas_object_smart_callback_add(bt, "clicked", _bt_close, notify);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Top Left");
+   evas_object_smart_callback_add(bt, "clicked", _bt, notify);
+   elm_table_pack(tb, bt, 0, 0, 1, 1);
+   evas_object_show(bt);
+
+   notify = elm_notify_add(win);
+   evas_object_size_hint_weight_set(notify, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_notify_orient_set(notify, ELM_NOTIFY_ORIENT_TOP_RIGHT);
+
+   bx = elm_box_add(win);
+   elm_notify_content_set(notify, bx);
+   elm_box_horizontal_set(bx, 1);
+   evas_object_show(bx);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb, "Top Right position.");
+   elm_box_pack_end(bx, lb);
+   evas_object_show(lb);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Close");
+   evas_object_smart_callback_add(bt, "clicked", _bt_close, notify);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Top Right");
+   evas_object_smart_callback_add(bt, "clicked", _bt, notify);
+   elm_table_pack(tb, bt, 2, 0, 1, 1);
+   evas_object_show(bt);
+
+   notify = elm_notify_add(win);
+   evas_object_size_hint_weight_set(notify, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_notify_orient_set(notify, ELM_NOTIFY_ORIENT_BOTTOM_LEFT);
+
+   bx = elm_box_add(win);
+   elm_notify_content_set(notify, bx);
+   elm_box_horizontal_set(bx, 1);
+   evas_object_show(bx);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb, "Bottom Left position.");
+   elm_box_pack_end(bx, lb);
+   evas_object_show(lb);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Close");
+   evas_object_smart_callback_add(bt, "clicked", _bt_close, notify);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Bottom Left");
+   evas_object_smart_callback_add(bt, "clicked", _bt, notify);
+   elm_table_pack(tb, bt, 0, 2, 1, 1);
+   evas_object_show(bt);
+
+   notify = elm_notify_add(win);
+   evas_object_size_hint_weight_set(notify, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_notify_orient_set(notify, ELM_NOTIFY_ORIENT_BOTTOM_RIGHT);
+
+   bx = elm_box_add(win);
+   elm_notify_content_set(notify, bx);
+   elm_box_horizontal_set(bx, 1);
+   evas_object_show(bx);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb, "Bottom Right position.");
+   elm_box_pack_end(bx, lb);
+   evas_object_show(lb);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Close");
+   evas_object_smart_callback_add(bt, "clicked", _bt_close, notify);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Bottom Right");
+   evas_object_smart_callback_add(bt, "clicked", _bt, notify);
+   elm_table_pack(tb, bt, 2, 2, 1, 1);
+   evas_object_show(bt);
+
+   evas_object_show(win);
+   evas_object_resize(win, 300, 350);
+}
+
+#endif
+
diff --git a/src/bin/test_pager.c b/src/bin/test_pager.c
new file mode 100644 (file)
index 0000000..477fc9a
--- /dev/null
@@ -0,0 +1,151 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+typedef struct _Pginfo Pginfo;
+
+struct _Pginfo
+{
+   Evas_Object *pager, *pg1, *pg2, *pg3;
+};
+
+static void
+my_pager_1(void *data, Evas_Object *obj, void *event_info)
+{
+   Pginfo *info = data;
+   elm_pager_content_promote(info->pager, info->pg2);
+}
+
+static void
+my_pager_2(void *data, Evas_Object *obj, void *event_info)
+{
+   Pginfo *info = data;
+   elm_pager_content_promote(info->pager, info->pg3);
+}
+
+static void
+my_pager_3(void *data, Evas_Object *obj, void *event_info)
+{
+   Pginfo *info = data;
+   elm_pager_content_promote(info->pager, info->pg1);
+}
+
+static void
+my_pager_pop(void *data, Evas_Object *obj, void *event_info)
+{
+   Pginfo *info = data;
+   elm_pager_content_pop(info->pager);
+}
+
+void
+test_pager(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *pg, *bx, *lb, *bt;
+   static Pginfo info;
+
+   win = elm_win_add(NULL, "pager", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Pager");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   pg = elm_pager_add(win);
+   elm_win_resize_object_add(win, pg);
+   evas_object_show(pg);
+
+   info.pager = pg;
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bx);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb,
+                      "This is page 1 in a pager stack.<br>"
+                      "<br>"
+                      "So what is a pager stack? It is a stack<br>"
+                      "of pages that hold widgets in it. The<br>"
+                      "pages can be pushed and popped on and<br>"
+                      "off the stack, activated and otherwise<br>"
+                      "activated if already in the stack<br>"
+                      "(activated means promoted to the top of<br>"
+                      "the stack).<br>"
+                      "<br>"
+                      "The theme may define the animation how<br>"
+                      "show and hide of pages.");
+   elm_box_pack_end(bx, lb);
+   evas_object_show(lb);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Flip to 2");
+   evas_object_smart_callback_add(bt, "clicked", my_pager_1, &info);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Popme");
+   evas_object_smart_callback_add(bt, "clicked", my_pager_pop, &info);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+   elm_pager_content_push(pg, bx);
+   info.pg1 = bx;
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bx);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb,
+                      "This is page 2 in a pager stack.<br>"
+                      "<br>"
+                      "This is just like the previous page in<br>"
+                      "the pager stack."
+                      );
+   elm_box_pack_end(bx, lb);
+   evas_object_show(lb);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Flip to 3");
+   evas_object_smart_callback_add(bt, "clicked", my_pager_2, &info);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Popme");
+   evas_object_smart_callback_add(bt, "clicked", my_pager_pop, &info);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+   elm_pager_content_push(pg, bx);
+   info.pg2 = bx;
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bx);
+
+   lb = elm_label_add(win);
+   elm_label_label_set(lb,
+                      "This is page 3 in a pager stack.<br>"
+                      "<br>"
+                      "This is just like the previous page in<br>"
+                      "the pager stack.");
+   elm_box_pack_end(bx, lb);
+   evas_object_show(lb);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Flip to 1");
+   evas_object_smart_callback_add(bt, "clicked", my_pager_3, &info);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Popme");
+   evas_object_smart_callback_add(bt, "clicked", my_pager_pop, &info);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+   elm_pager_content_push(pg, bx);
+   info.pg3 = bx;
+
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_panel.c b/src/bin/test_panel.c
new file mode 100644 (file)
index 0000000..2e736f9
--- /dev/null
@@ -0,0 +1,163 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+
+static Elm_Genlist_Item_Class itc;
+
+static char *_label_get(const void *data, Evas_Object *obj, const char *source);
+static Evas_Object *_icon_get(const void *data, Evas_Object *obj, const char *source);
+static Eina_Bool _state_get(const void *data, Evas_Object *obj, const char *source);
+static void _item_del(const void *data, Evas_Object *obj);
+static void _fill_list(Evas_Object *obj);
+static Eina_Bool _dir_has_subs(const char *path);
+
+void 
+test_panel(void *data, Evas_Object *obj, void *event_info) 
+{
+   Evas_Object *win, *bg, *panel, *bx;
+   Evas_Object *list;
+
+   win = elm_win_add(NULL, "panel", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Panel");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   elm_win_resize_object_add(win, bx);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bx);
+
+   panel = elm_panel_add(win);
+   elm_panel_orient_set(panel, ELM_PANEL_ORIENT_LEFT);
+   evas_object_size_hint_weight_set(panel, 0.0, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(panel, 0.0, EVAS_HINT_FILL);
+
+   itc.item_style = "default";
+   itc.func.label_get = _label_get;
+   itc.func.icon_get = _icon_get;
+   itc.func.state_get = _state_get;
+   itc.func.del = _item_del;
+
+   list = elm_genlist_add(win);
+   evas_object_size_hint_min_set(list, 100, -1);
+   evas_object_size_hint_weight_set(list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(list, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_show(list);
+
+   elm_panel_content_set(panel, list);
+
+   elm_box_pack_end(bx, panel);
+   evas_object_show(panel);
+
+   _fill_list(list);
+
+   evas_object_resize(win, 300, 300);
+   evas_object_show(win);
+}
+
+static char *
+_label_get(const void *data, Evas_Object *obj, const char *source) 
+{
+   return strdup(ecore_file_file_get(data));
+}
+
+static Evas_Object *
+_icon_get(const void *data, Evas_Object *obj, const char *source) 
+{
+   if (!strcmp(source, "elm.swallow.icon")) 
+     {
+        Evas_Object *ic;
+
+        ic = elm_icon_add(obj);
+        if (ecore_file_is_dir((char *)data))
+          elm_icon_standard_set(ic, "folder");
+        else
+          elm_icon_standard_set(ic, "file");
+        evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+        evas_object_show(ic);
+        return ic;
+     }
+   return NULL;
+}
+
+static Eina_Bool 
+_state_get(const void *data, Evas_Object *obj, const char *source) 
+{
+   return EINA_FALSE;
+}
+
+static void 
+_item_del(const void *data, Evas_Object *obj) 
+{
+   eina_stringshare_del(data);
+}
+
+static void 
+_fill_list(Evas_Object *obj) 
+{
+   DIR *d;
+   struct dirent *de;
+   Eina_List *dirs = NULL, *l;
+   char *real;
+
+   if (!(d = opendir(getenv("HOME")))) return;
+   while ((de = readdir(d)) != NULL) 
+     {
+        char buff[PATH_MAX];
+
+        if (de->d_name[0] == '.') continue;
+        snprintf(buff, sizeof(buff), "%s/%s", getenv("HOME"), de->d_name);
+        if (!ecore_file_is_dir(buff)) continue;
+        real = ecore_file_realpath(buff);
+        dirs = eina_list_append(dirs, real);
+     }
+   closedir(d);
+
+   dirs = eina_list_sort(dirs, eina_list_count(dirs), EINA_COMPARE_CB(strcoll));
+
+   EINA_LIST_FOREACH(dirs, l, real) 
+     {
+        Eina_Bool result = EINA_FALSE;
+
+        result = _dir_has_subs(real);
+        if (!result) 
+          elm_genlist_item_append(obj, &itc, eina_stringshare_add(real), 
+                                  NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
+        else 
+          elm_genlist_item_append(obj, &itc, eina_stringshare_add(real), 
+                                  NULL, ELM_GENLIST_ITEM_SUBITEMS, 
+                                  NULL, NULL);
+        free(real);
+     }
+   eina_list_free(dirs);
+}
+
+static Eina_Bool 
+_dir_has_subs(const char *path) 
+{
+   DIR *d;
+   struct dirent *de;
+   Eina_Bool result = EINA_FALSE;
+
+   if (!path) return result;
+   if (!(d = opendir(path))) return result;
+   while ((de = readdir(d)) != NULL) 
+     {
+        char buff[PATH_MAX];
+
+        if (de->d_name[0] == '.') continue;
+        snprintf(buff, sizeof(buff), "%s/%s", path, de->d_name);
+        if (ecore_file_is_dir(buff)) 
+          {
+             result = EINA_TRUE;
+             break;
+          }
+     }
+   closedir(d);
+   return result;
+}
+
+#endif
diff --git a/src/bin/test_photo.c b/src/bin/test_photo.c
new file mode 100644 (file)
index 0000000..8c82d57
--- /dev/null
@@ -0,0 +1,66 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+void
+test_photo(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *sc, *tb, *ph;
+   int i, j, n;
+   char buf[PATH_MAX];
+   const char *img[9] =
+     {
+        "panel_01.jpg", 
+          "plant_01.jpg", 
+          "rock_01.jpg", 
+          "rock_02.jpg",
+          "sky_01.jpg", 
+          "sky_02.jpg", 
+          "sky_03.jpg", 
+          "sky_04.jpg",
+          "wood_01.jpg"
+     };
+
+   win = elm_win_add(NULL, "photo", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Photo");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+
+   tb = elm_table_add(win);
+   evas_object_size_hint_weight_set(tb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   
+   n = 0;
+   for (j = 0; j < 12; j++)
+     {
+        for (i = 0; i < 12; i++)
+          {
+             ph = elm_photo_add(win);
+             snprintf(buf, sizeof(buf), "%s/images/%s",
+                      PACKAGE_DATA_DIR, img[n]);
+             n++;
+             if (n >= 9) n = 0;
+             elm_photo_file_set(ph, buf);
+             evas_object_size_hint_weight_set(ph, EVAS_HINT_EXPAND, 
+                                              EVAS_HINT_EXPAND);
+             evas_object_size_hint_align_set(ph, EVAS_HINT_FILL, 
+                                             EVAS_HINT_FILL);
+             elm_photo_size_set(ph, 80);
+             elm_table_pack(tb, ph, i, j, 1, 1);
+             evas_object_show(ph);
+          }
+     }
+   
+   sc = elm_scroller_add(win);
+   evas_object_size_hint_weight_set(sc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, sc);
+   
+   elm_scroller_content_set(sc, tb);
+   evas_object_show(tb);
+   evas_object_show(sc);
+   
+   evas_object_resize(win, 300, 300);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_photocam.c b/src/bin/test_photocam.c
new file mode 100644 (file)
index 0000000..6b12b47
--- /dev/null
@@ -0,0 +1,380 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+
+static Evas_Object *rect;
+
+static void
+my_ph_clicked(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *win = data;
+   printf("clicked\n");
+}
+
+static void
+my_ph_press(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *win = data;
+   printf("press\n");
+}
+
+static void
+my_ph_longpressed(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *win = data;
+   printf("longpressed\n");
+}
+
+static void
+my_ph_clicked_double(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *win = data;
+   printf("clicked,double\n");
+}
+
+static void
+my_ph_load(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *win = data;
+   printf("load\n");
+}
+
+static void
+my_ph_loaded(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *win = data;
+   printf("loaded\n");
+}
+
+static void
+my_ph_load_details(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *win = data;
+   printf("load,details\n");
+}
+
+static void
+my_ph_loaded_details(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *win = data;
+   printf("loaded,details\n");
+}
+
+static void
+my_ph_zoom_start(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *win = data;
+   printf("zoom,start\n");
+}
+
+static void
+my_ph_zoom_stop(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *win = data;
+   printf("zoom,stop\n");
+}
+
+static void
+my_ph_zoom_change(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *win = data;
+   printf("zoom,change\n");
+}
+
+static void
+my_ph_anim_start(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *win = data;
+   printf("anim,start\n");
+}
+
+static void
+my_ph_anim_stop(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *win = data;
+   printf("anim,stop\n");
+}
+
+static void
+my_ph_drag_start(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *win = data;
+   printf("drag,start\n");
+}
+
+static void
+my_ph_drag_stop(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *win = data;
+   printf("drag_stop\n");
+}
+
+static void
+my_ph_scroll(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *win = data;
+   int x, y, w, h;
+   elm_photocam_region_get(obj, &x, &y, &w, &h);
+   printf("scroll %i %i %ix%i\n", x, y, w, h);
+}
+
+static void
+sel_done(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *ph, *iw;
+
+   ph = data;
+   iw = evas_object_data_get(ph, "inwin");
+   elm_photocam_file_set(ph, elm_fileselector_selected_get(obj));
+   evas_object_del(iw);
+}
+
+static void
+my_bt_open(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *ph, *win;
+   Evas_Object *iw, *fs;
+   
+   ph = data;
+   win = evas_object_data_get(ph, "window");
+   iw = elm_win_inwin_add(win);
+   
+   fs = elm_fileselector_add(win);
+   elm_fileselector_expandable_set(fs, EINA_TRUE);
+   elm_fileselector_path_set(fs, getenv("HOME"));
+   evas_object_smart_callback_add(fs, "done", sel_done, ph);
+
+   evas_object_data_set(ph, "inwin", iw);
+   
+   elm_win_inwin_content_set(iw, fs);
+   evas_object_show(fs);
+   elm_win_inwin_activate(iw);
+}
+
+static void
+my_bt_show_reg(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_photocam_image_region_show(data, 30, 50, 500, 300);
+}
+
+static void
+my_bt_bring_reg(void *data, Evas_Object *obj, void *event_info)
+
+{
+   elm_photocam_image_region_bring_in(data, 800, 300, 500, 300);
+}
+
+static void
+my_bt_zoom_in(void *data, Evas_Object *obj, void *event_info)
+{
+   double zoom;
+   
+   zoom = elm_photocam_zoom_get(data);
+   zoom -= 0.5;
+   elm_photocam_zoom_mode_set(data, ELM_PHOTOCAM_ZOOM_MODE_MANUAL);
+   if (zoom >= (1.0 / 32.0)) elm_photocam_zoom_set(data, zoom);
+}
+
+static void
+my_bt_zoom_out(void *data, Evas_Object *obj, void *event_info)
+{
+   double zoom;
+   
+   zoom = elm_photocam_zoom_get(data);
+   zoom += 0.5;
+   elm_photocam_zoom_mode_set(data, ELM_PHOTOCAM_ZOOM_MODE_MANUAL);
+   if (zoom <= 256.0) elm_photocam_zoom_set(data, zoom);
+}
+
+static void
+my_bt_pause(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_photocam_paused_set(data, !elm_photocam_paused_get(data));
+}
+
+static void
+my_bt_zoom_fit(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_photocam_zoom_mode_set(data, ELM_PHOTOCAM_ZOOM_MODE_AUTO_FIT);
+}
+
+static void
+my_bt_zoom_fill(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_photocam_zoom_mode_set(data, ELM_PHOTOCAM_ZOOM_MODE_AUTO_FILL);
+}
+
+static void
+_photocam_mouse_wheel_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *photocam = data;
+   Evas_Event_Mouse_Wheel *ev = (Evas_Event_Mouse_Wheel*) event_info;
+   int zoom;
+   double val;
+   //unset the mouse wheel
+   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+
+   zoom = elm_photocam_zoom_get(photocam);
+   if (ev->z>0 && zoom == 1) return;
+
+   if (ev->z > 0)
+     zoom /= 2;
+   else
+     zoom *= 2;
+
+   val = 1;
+   int _zoom = zoom;
+   while(_zoom>1)
+     {
+       _zoom /= 2;
+       val++;
+     }
+
+   elm_photocam_zoom_mode_set(photocam, ELM_PHOTOCAM_ZOOM_MODE_MANUAL);
+   if (zoom >= 1) elm_photocam_zoom_set(photocam, zoom);
+}
+
+   static void
+_photocam_move_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+   int x,y,w,h;
+
+   evas_object_geometry_get(data,&x,&y,&w,&h);
+   evas_object_resize(rect,w,h);
+   evas_object_move(rect,x,y);
+}
+
+void
+test_photocam(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *ph, *tb2, *bt;
+   // these were just testing - use the "select photo" browser to select one
+   const char *img[5] =
+     {
+        "/home/raster/t1.jpg",  //   5 mpixel
+        "/home/raster/t2.jpg",  //  18 mpixel
+        "/home/raster/t3.jpg",  //  39 mpixel
+        "/home/raster/t4.jpg",  // 192 mpixel
+        "/home/raster/t5.jpg"   // 466 mpixel
+     };
+
+   win = elm_win_add(NULL, "photocam", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Photocam");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+
+   ph = elm_photocam_add(win);
+   evas_object_size_hint_weight_set(ph, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, ph);
+   evas_object_data_set(ph, "window", win);
+   rect = evas_object_rectangle_add(evas_object_evas_get(win));
+   evas_object_color_set(rect, 0, 0, 0, 0);
+   evas_object_repeat_events_set(rect,1);
+   evas_object_show(rect);
+   evas_object_event_callback_add(rect, EVAS_CALLBACK_MOUSE_WHEEL, _photocam_mouse_wheel_cb, ph);
+   evas_object_raise(rect);
+
+   evas_object_event_callback_add(ph, EVAS_CALLBACK_RESIZE, _photocam_move_resize_cb, ph);
+   evas_object_event_callback_add(ph, EVAS_CALLBACK_MOVE, _photocam_move_resize_cb, ph);
+
+   evas_object_smart_callback_add(ph, "clicked", my_ph_clicked, win);
+   evas_object_smart_callback_add(ph, "press", my_ph_press, win);
+   evas_object_smart_callback_add(ph, "longpressed", my_ph_longpressed, win);
+   evas_object_smart_callback_add(ph, "clicked,double", my_ph_clicked_double, win);
+   evas_object_smart_callback_add(ph, "load", my_ph_load, win);
+   evas_object_smart_callback_add(ph, "loaded", my_ph_loaded, win);
+   evas_object_smart_callback_add(ph, "load,details", my_ph_load_details, win);
+   evas_object_smart_callback_add(ph, "loaded,details", my_ph_loaded_details, win);
+   evas_object_smart_callback_add(ph, "zoom,start", my_ph_zoom_start, win);
+   evas_object_smart_callback_add(ph, "zoom,stop", my_ph_zoom_stop, win);
+   evas_object_smart_callback_add(ph, "zoom,change", my_ph_zoom_change, win);
+   evas_object_smart_callback_add(ph, "scroll,anim,start", my_ph_anim_start, win);
+   evas_object_smart_callback_add(ph, "scroll,anim,stop", my_ph_anim_stop, win);
+   evas_object_smart_callback_add(ph, "scroll,drag,start", my_ph_drag_start, win);
+   evas_object_smart_callback_add(ph, "scroll,drag,stop", my_ph_drag_stop, win);
+   evas_object_smart_callback_add(ph, "scroll", my_ph_scroll, win);
+   
+   elm_photocam_file_set(ph, img[1]);
+   
+   evas_object_show(ph);
+   
+   tb2 = elm_table_add(win);
+   evas_object_size_hint_weight_set(tb2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, tb2);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Z -");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_zoom_out, ph);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.1, 0.1);
+   elm_table_pack(tb2, bt, 0, 0, 1, 1);
+   evas_object_show(bt);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Select Photo");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_open, ph);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.5, 0.1);
+   elm_table_pack(tb2, bt, 1, 0, 1, 1);
+   evas_object_show(bt);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Z +");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_zoom_in, ph);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.9, 0.1);
+   elm_table_pack(tb2, bt, 2, 0, 1, 1);
+   evas_object_show(bt);
+
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Show 30,50 500x300");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_show_reg, ph);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.1, 0.5);
+   elm_table_pack(tb2, bt, 0, 1, 1, 1);
+   evas_object_show(bt);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Bring 800,300 500x300");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_bring_reg, ph);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.9, 0.5);
+   elm_table_pack(tb2, bt, 2, 1, 1, 1);
+   evas_object_show(bt);
+   
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Pause On/Off");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_pause, ph);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.1, 0.9);
+   elm_table_pack(tb2, bt, 0, 2, 1, 1);
+   evas_object_show(bt);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Fit");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_zoom_fit, ph);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.5, 0.9);
+   elm_table_pack(tb2, bt, 1, 2, 1, 1);
+   evas_object_show(bt);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Fill");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_zoom_fill, ph);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.9, 0.9);
+   elm_table_pack(tb2, bt, 2, 2, 1, 1);
+   evas_object_show(bt);
+   
+   evas_object_show(tb2);
+   
+   evas_object_resize(win, 800, 800);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_progressbar.c b/src/bin/test_progressbar.c
new file mode 100644 (file)
index 0000000..f0c24c5
--- /dev/null
@@ -0,0 +1,202 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+typedef struct Progressbar
+{
+   Evas_Object *pb1;
+   Evas_Object *pb2;
+   Evas_Object *pb3;
+   Evas_Object *pb4;
+   Evas_Object *pb5;
+   Evas_Object *pb6;
+   Evas_Object *pb7;
+   Eina_Bool run;
+   Ecore_Timer *timer;
+} Progressbar;
+
+static Progressbar _test_progressbar;
+
+static int
+_my_progressbar_value_set (void *data)
+{
+   double progress;
+
+   progress = elm_progressbar_value_get (_test_progressbar.pb1);
+   if (progress < 1.0) progress += 0.0123;
+   else progress = 0.0;
+   elm_progressbar_value_set(_test_progressbar.pb1, progress);
+   elm_progressbar_value_set(_test_progressbar.pb4, progress);
+   elm_progressbar_value_set(_test_progressbar.pb3, progress);
+   elm_progressbar_value_set(_test_progressbar.pb6, progress);
+   if (progress < 1.0) return ECORE_CALLBACK_RENEW;
+   _test_progressbar.run = 0;
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+my_progressbar_test_start(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_progressbar_pulse(_test_progressbar.pb2, EINA_TRUE);
+   elm_progressbar_pulse(_test_progressbar.pb5, EINA_TRUE);
+   elm_progressbar_pulse(_test_progressbar.pb7, EINA_TRUE);
+   if (!_test_progressbar.run)
+     {
+        _test_progressbar.timer = ecore_timer_add(0.1, _my_progressbar_value_set, NULL);
+        _test_progressbar.run = EINA_TRUE;
+     }
+}
+
+static void
+my_progressbar_test_stop(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_progressbar_pulse(_test_progressbar.pb2, EINA_FALSE);
+   elm_progressbar_pulse(_test_progressbar.pb5, EINA_FALSE);
+   elm_progressbar_pulse(_test_progressbar.pb7, EINA_FALSE);
+   if (_test_progressbar.run)
+     {
+        ecore_timer_del(_test_progressbar.timer);
+        _test_progressbar.run = EINA_FALSE;
+     }
+}
+
+static void
+my_progressbar_destroy(void *data, Evas_Object *obj, void *event_info)
+{
+   my_progressbar_test_stop(NULL, NULL, NULL);
+   evas_object_del(obj);
+}
+
+void
+test_progressbar(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *pb, *bx, *hbx, *bt, *bt_bx, *ic1, *ic2;
+   char buf[PATH_MAX];
+
+   win = elm_win_add(NULL, "progressbar", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Progressbar");
+   evas_object_smart_callback_add(win, "delete,request", 
+                                  my_progressbar_destroy, NULL);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   elm_win_resize_object_add(win, bx);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bx);
+
+   pb = elm_progressbar_add(win);
+   evas_object_size_hint_weight_set(pb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(pb, EVAS_HINT_FILL, 0.5);
+   elm_box_pack_end(bx, pb);
+//   elm_progressbar_horizontal_set(pb, EINA_TRUE);
+//   elm_progressbar_label_set(pb, "Progression %");
+//   elm_progressbar_unit_format_set(pb, NULL);
+   evas_object_show(pb);
+   _test_progressbar.pb1 = pb;
+
+   pb = elm_progressbar_add(win);
+   evas_object_size_hint_align_set(pb, EVAS_HINT_FILL, 0.5);
+   evas_object_size_hint_weight_set(pb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_progressbar_label_set(pb, "Infinite bounce");
+   elm_progressbar_pulse_set(pb, EINA_TRUE);
+   elm_box_pack_end(bx, pb);
+   evas_object_show(pb);
+   _test_progressbar.pb2 = pb;
+
+   ic1 = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic1, buf, NULL);
+   evas_object_size_hint_aspect_set(ic1, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+
+   pb = elm_progressbar_add(win);
+   elm_progressbar_label_set(pb, "Label");
+   elm_progressbar_icon_set(pb, ic1);
+   elm_progressbar_inverted_set(pb, 1);
+   elm_progressbar_unit_format_set(pb, "%1.1f units");
+   elm_progressbar_span_size_set(pb, 200);
+   evas_object_size_hint_align_set(pb, EVAS_HINT_FILL, 0.5);
+   evas_object_size_hint_weight_set(pb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx, pb);
+   evas_object_show(ic1);
+   evas_object_show(pb);
+   _test_progressbar.pb3 = pb;
+
+   hbx = elm_box_add(win);
+   elm_box_horizontal_set(hbx, EINA_TRUE);
+   evas_object_size_hint_weight_set(hbx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(hbx, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx, hbx);
+   evas_object_show(hbx);
+
+   pb = elm_progressbar_add(win);
+   elm_progressbar_horizontal_set(pb, EINA_FALSE);
+   evas_object_size_hint_align_set(pb, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(pb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(hbx, pb);
+   elm_progressbar_span_size_set(pb, 60);
+   elm_progressbar_label_set(pb, "percent");
+   evas_object_show(pb);
+   _test_progressbar.pb4 = pb;
+
+   pb = elm_progressbar_add(win);
+   elm_progressbar_horizontal_set(pb, EINA_FALSE);
+   evas_object_size_hint_align_set(pb, EVAS_HINT_FILL, 0.5);
+   evas_object_size_hint_weight_set(pb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_progressbar_span_size_set(pb, 80);
+   elm_progressbar_pulse_set(pb, EINA_TRUE);
+   elm_progressbar_unit_format_set(pb, NULL);
+   elm_progressbar_label_set(pb, "Infinite bounce");
+   elm_box_pack_end(hbx, pb);
+   evas_object_show(pb);
+   _test_progressbar.pb5 = pb;
+
+   ic2 = elm_icon_add(win);
+   elm_icon_file_set(ic2, buf, NULL);
+   evas_object_size_hint_aspect_set(ic2, EVAS_ASPECT_CONTROL_HORIZONTAL, 1, 1);
+
+   pb = elm_progressbar_add(win);
+   elm_progressbar_horizontal_set(pb, EINA_FALSE);
+   elm_progressbar_label_set(pb, "Label");
+   elm_progressbar_icon_set(pb, ic2);
+   elm_progressbar_inverted_set(pb, 1);
+   elm_progressbar_unit_format_set(pb, "%1.2f%%");
+   elm_progressbar_span_size_set(pb, 200);
+   evas_object_size_hint_align_set(pb, EVAS_HINT_FILL, 0.5);
+   evas_object_size_hint_weight_set(pb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(hbx, pb);
+   evas_object_show(ic2);
+   evas_object_show(pb);
+   _test_progressbar.pb6 = pb;
+
+   pb = elm_progressbar_add(win);
+   elm_object_style_set(pb, "wheel");
+   elm_progressbar_label_set(pb, "Style: wheel");
+   evas_object_size_hint_align_set(pb, EVAS_HINT_FILL, 0.5);
+   evas_object_size_hint_weight_set(pb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx, pb);
+   evas_object_show(pb);
+   _test_progressbar.pb7 = pb;
+
+   bt_bx = elm_box_add(win);
+   elm_box_horizontal_set(bt_bx, 1);
+   evas_object_size_hint_weight_set(bt_bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx, bt_bx);
+   evas_object_show(bt_bx);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Start");
+   evas_object_smart_callback_add(bt, "clicked", my_progressbar_test_start, NULL);
+   elm_box_pack_end(bt_bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Stop");
+   evas_object_smart_callback_add(bt, "clicked", my_progressbar_test_stop, NULL);
+   elm_box_pack_end(bt_bx, bt);
+   evas_object_show(bt);
+
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_radio.c b/src/bin/test_radio.c
new file mode 100644 (file)
index 0000000..701693a
--- /dev/null
@@ -0,0 +1,99 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+void
+test_radio(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *ic, *rd, *rdg;
+   char buf[PATH_MAX];
+
+   win = elm_win_add(NULL, "radio", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Radios");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+
+   rd = elm_radio_add(win);
+   elm_radio_state_value_set(rd, 0);
+   evas_object_size_hint_weight_set(rd, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(rd, EVAS_HINT_FILL, 0.5);
+   elm_radio_label_set(rd, "Icon sized to radio");
+   elm_radio_icon_set(rd, ic);
+   elm_box_pack_end(bx, rd);
+   evas_object_show(rd);
+   evas_object_show(ic);
+   rdg = rd;
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+
+   rd = elm_radio_add(win);
+   elm_radio_state_value_set(rd, 1);
+   elm_radio_group_add(rd, rdg);
+   elm_radio_label_set(rd, "Icon no scale");
+   elm_radio_icon_set(rd, ic);
+   elm_box_pack_end(bx, rd);
+   evas_object_show(rd);
+   evas_object_show(ic);
+
+   rd = elm_radio_add(win);
+   elm_radio_state_value_set(rd, 2);
+   elm_radio_group_add(rd, rdg);
+   elm_radio_label_set(rd, "Label Only");
+   elm_box_pack_end(bx, rd);
+   evas_object_show(rd);
+
+   rd = elm_radio_add(win);
+   elm_radio_state_value_set(rd, 3);
+   elm_radio_group_add(rd, rdg);
+   elm_radio_label_set(rd, "Disabled");
+   elm_object_disabled_set(rd, 1);
+   elm_box_pack_end(bx, rd);
+   evas_object_show(rd);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+
+   rd = elm_radio_add(win);
+   elm_radio_state_value_set(rd, 4);
+   elm_radio_group_add(rd, rdg);
+   elm_radio_icon_set(rd, ic);
+   elm_box_pack_end(bx, rd);
+   evas_object_show(rd);
+   evas_object_show(ic);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+
+   rd = elm_radio_add(win);
+   elm_radio_state_value_set(rd, 5);
+   elm_radio_group_add(rd, rdg);
+   elm_radio_icon_set(rd, ic);
+   elm_object_disabled_set(rd, 1);
+   elm_box_pack_end(bx, rd);
+   evas_object_show(rd);
+   evas_object_show(ic);
+
+   elm_radio_value_set(rdg, 2);
+
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_scaling.c b/src/bin/test_scaling.c
new file mode 100644 (file)
index 0000000..876368c
--- /dev/null
@@ -0,0 +1,123 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+void
+test_scaling(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *bt;
+
+   win = elm_win_add(NULL, "scaling", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Scaling");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Scale: 0.5");
+   elm_object_scale_set(bt, 0.5);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Scale: 0.75");
+   elm_object_scale_set(bt, 0.75);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Scale: 1.0");
+   elm_object_scale_set(bt, 1.0);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Scale: 1.5");
+   elm_object_scale_set(bt, 1.5);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Scale: 2.0");
+   elm_object_scale_set(bt, 2.0);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Scale: 3.0");
+   elm_object_scale_set(bt, 3.0);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   evas_object_resize(win, 320, 320);
+   evas_object_show(win);
+}
+
+void
+test_scaling2(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *fr, *lb;
+
+   win = elm_win_add(NULL, "scaling-2", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Scaling 2");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   fr = elm_frame_add(win);
+   elm_object_scale_set(fr, 0.5);
+   elm_frame_label_set(fr, "Scale: 0.5");
+   lb = elm_label_add(win);
+   elm_label_label_set(lb,
+                      "Parent frame scale<br>"
+                      "is 0.5. Child should<br>"
+                      "inherit it.");
+   elm_frame_content_set(fr, lb);
+   evas_object_show(lb);
+   elm_box_pack_end(bx, fr);
+   evas_object_show(fr);
+
+   fr = elm_frame_add(win);
+   elm_frame_label_set(fr, "Scale: 1.0");
+   lb = elm_label_add(win);
+   elm_label_label_set(lb,
+                      "Parent frame scale<br>"
+                      "is 1.0. Child should<br>"
+                      "inherit it.");
+   elm_frame_content_set(fr, lb);
+   evas_object_show(lb);
+   elm_object_scale_set(fr, 1.0);
+   elm_box_pack_end(bx, fr);
+   evas_object_show(fr);
+
+   fr = elm_frame_add(win);
+   elm_frame_label_set(fr, "Scale: 2.0");
+   lb = elm_label_add(win);
+   elm_label_label_set(lb,
+                      "Parent frame scale<br>"
+                      "is 2.0. Child should<br>"
+                      "inherit it.");
+   elm_frame_content_set(fr, lb);
+   evas_object_show(lb);
+   elm_object_scale_set(fr, 2.0);
+   elm_box_pack_end(bx, fr);
+   evas_object_show(fr);
+
+   evas_object_resize(win, 320, 320);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_scroller.c b/src/bin/test_scroller.c
new file mode 100644 (file)
index 0000000..210e90f
--- /dev/null
@@ -0,0 +1,263 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+void
+my_bt_go_300_300(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_scroller_region_bring_in((Evas_Object *)data, 300, 300, 318, 318);
+}
+
+void
+my_bt_go_900_300(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_scroller_region_bring_in((Evas_Object *)data, 900, 300, 318, 318);
+}
+
+void
+my_bt_go_300_900(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_scroller_region_bring_in((Evas_Object *)data, 300, 900, 318, 318);
+}
+
+void
+my_bt_go_900_900(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_scroller_region_bring_in((Evas_Object *)data, 900, 900, 318, 318);
+}
+
+void
+test_scroller(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg2, *tb, *tb2, *bg, *sc, *bt;
+   int i, j, n;
+   char buf[PATH_MAX];
+   const char *img[9] =
+     {
+        "panel_01.jpg", 
+          "plant_01.jpg", 
+          "rock_01.jpg", 
+          "rock_02.jpg",
+          "sky_01.jpg", 
+          "sky_02.jpg", 
+          "sky_03.jpg", 
+          "sky_04.jpg",
+          "wood_01.jpg"
+     };
+
+   win = elm_win_add(NULL, "scroller", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Scroller");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+
+   tb = elm_table_add(win);
+   evas_object_size_hint_weight_set(tb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+   n = 0;
+   for (j = 0; j < 12; j++)
+     {
+        for (i = 0; i < 12; i++)
+          {
+             bg2 = elm_bg_add(win);
+             snprintf(buf, sizeof(buf), "%s/images/%s", 
+                      PACKAGE_DATA_DIR, img[n]);
+             n++;
+             if (n >= 9) n = 0;
+             elm_bg_file_set(bg2, buf, NULL);
+             evas_object_size_hint_weight_set(bg2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+             evas_object_size_hint_align_set(bg2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+             evas_object_size_hint_min_set(bg2, 318, 318);
+             elm_table_pack(tb, bg2, i, j, 1, 1);
+             evas_object_show(bg2);
+          }
+     }
+   
+   sc = elm_scroller_add(win);
+   evas_object_size_hint_weight_set(sc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, sc);
+
+   elm_scroller_content_set(sc, tb);
+   evas_object_show(tb);
+
+   elm_scroller_page_relative_set(sc, 1.0, 1.0);
+//   elm_scroller_page_size_set(sc, 200, 200);
+   evas_object_show(sc);
+
+   tb2 = elm_table_add(win);
+   evas_object_size_hint_weight_set(tb2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, tb2);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "to 300 300");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_go_300_300, sc);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.1, 0.1);
+   elm_table_pack(tb2, bt, 0, 0, 1, 1);
+   evas_object_show(bt);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "to 900 300");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_go_900_300, sc);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.9, 0.1);
+   elm_table_pack(tb2, bt, 1, 0, 1, 1);
+   evas_object_show(bt);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "to 300 900");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_go_300_900, sc);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.1, 0.9);
+   elm_table_pack(tb2, bt, 0, 1, 1, 1);
+   evas_object_show(bt);
+   
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "to 900 900");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_go_900_900, sc);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, 0.9, 0.9);
+   elm_table_pack(tb2, bt, 1, 1, 1, 1);
+   evas_object_show(bt);
+   
+   evas_object_show(tb2);
+   
+   evas_object_resize(win, 320, 320);
+   evas_object_show(win);
+}
+
+void
+click_through(void *data, Evas_Object *obj, void *event_info)
+{
+   printf("click went through on %p\n", obj);
+}
+
+void
+test_scroller2(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bt, *bx, *bx2, *bg, *sc, *tb, *tb2, *rc;
+   int i, j;
+
+   win = elm_win_add(NULL, "scroller2", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Scroller 2");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.0);
+
+   /* { */
+   for (i = 0; i < 3; i++)
+     {
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Vertical");
+        evas_object_smart_callback_add(bt, "clicked", click_through, NULL);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+        evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, 0.5);
+        elm_box_pack_end(bx, bt);
+        evas_object_show(bt);
+     }
+   /* } */
+   
+   /* { */
+   sc = elm_scroller_add(win);
+   evas_object_size_hint_weight_set(sc, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(sc, EVAS_HINT_FILL, 0.5);
+   elm_scroller_bounce_set(sc, 1, 0);
+   elm_scroller_content_min_limit(sc, 0, 1);
+   elm_box_pack_end(bx, sc);
+   evas_object_show(sc);
+   
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+
+   for (i = 0; i < 10; i++)
+     {
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "... Horizontal scrolling ...");
+        evas_object_smart_callback_add(bt, "clicked", click_through, NULL);
+        elm_box_pack_end(bx2, bt);
+        evas_object_show(bt);
+     }
+   
+   elm_scroller_content_set(sc, bx2);
+   evas_object_show(bx2);
+   /* } */
+
+   /* { */
+   for (i = 0; i < 3; i++)
+     {
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Vertical");
+        evas_object_smart_callback_add(bt, "clicked", click_through, NULL);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+        evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, 0.5);
+        elm_box_pack_end(bx, bt);
+        evas_object_show(bt);
+     }
+   /* } */
+   
+   /* { */
+   tb = elm_table_add(win);
+   evas_object_size_hint_weight_set(tb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(tb, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx, tb);
+   evas_object_show(tb);
+   
+   rc = evas_object_rectangle_add(evas_object_evas_get(win));
+   evas_object_size_hint_min_set(rc, 200, 120);
+   elm_table_pack(tb, rc, 0, 0, 1, 1);
+   
+   sc = elm_scroller_add(win);
+   evas_object_size_hint_weight_set(sc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(sc, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_table_pack(tb, sc, 0, 0, 1, 1);
+   evas_object_show(sc);
+   
+   tb2 = elm_table_add(win);
+
+   for (j = 0; j < 16; j++)
+     {
+        for (i = 0; i < 16; i++)
+          {
+             bt = elm_button_add(win);
+             elm_button_label_set(bt, "Both");
+             evas_object_smart_callback_add(bt, "clicked", click_through, NULL);
+             elm_table_pack(tb2, bt, i, j, 1, 1);
+             evas_object_show(bt);
+          }
+     }
+   
+   elm_scroller_content_set(sc, tb2);
+   evas_object_show(tb2);
+   /* } */
+   
+   for (i = 0; i < 24; i++)
+     {
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, "Vertical");
+        evas_object_smart_callback_add(bt, "clicked", click_through, NULL);
+        evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+        evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, 0.5);
+        elm_box_pack_end(bx, bt);
+        evas_object_show(bt);
+     }
+   
+   sc = elm_scroller_add(win);
+   evas_object_size_hint_weight_set(sc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_scroller_bounce_set(sc, 0, 1);
+   elm_win_resize_object_add(win, sc);
+   elm_scroller_content_set(sc, bx);
+   evas_object_show(bx);
+   evas_object_show(sc);
+   
+   evas_object_resize(win, 320, 480);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_separator.c b/src/bin/test_separator.c
new file mode 100644 (file)
index 0000000..4371058
--- /dev/null
@@ -0,0 +1,71 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+void
+test_separator(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx0, *bx, *bt, *sp;
+
+   win = elm_win_add(NULL, "separators", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Separators");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx0 = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx0, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_horizontal_set(bx0, 1);
+   elm_win_resize_object_add(win, bx0);
+   evas_object_show(bx0);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx0, bx);
+   evas_object_show(bx);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Left upper corner");
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   sp = elm_separator_add(win);
+   elm_separator_horizontal_set(sp, 1); // by default, separator is vertical, we must set it horizontal
+   elm_box_pack_end(bx, sp);
+   evas_object_show(sp);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Left lower corner");
+   elm_object_disabled_set(bt, 1);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   sp = elm_separator_add(win); // now we need vertical separator
+   elm_box_pack_end(bx0, sp);
+   evas_object_show(sp);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx0, bx);
+   evas_object_show(bx);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Right upper corner");
+   elm_object_disabled_set(bt, 1);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   sp = elm_separator_add(win);
+   elm_separator_horizontal_set(sp, 1);
+   elm_box_pack_end(bx, sp);
+   evas_object_show(sp);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Right lower corner");
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_slider.c b/src/bin/test_slider.c
new file mode 100644 (file)
index 0000000..6439202
--- /dev/null
@@ -0,0 +1,105 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+
+
+void
+_change_cb(void *data, Evas_Object *obj, void *event_info)
+{
+    double val = elm_slider_value_get(obj);
+    elm_slider_value_set(data, val);
+}
+
+void
+test_slider(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *sl, *ic, *sl1;
+   char buf[PATH_MAX];
+
+   win = elm_win_add(NULL, "slider", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Slider");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+
+   sl = elm_slider_add(win);
+   sl1 = sl;
+   elm_slider_label_set(sl, "Label");
+   elm_slider_icon_set(sl, ic);
+   elm_slider_unit_format_set(sl, "%1.1f units");
+   elm_slider_span_size_set(sl, 120);
+   evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
+   evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx, sl);
+   evas_object_show(ic);
+   evas_object_show(sl);
+
+   sl = elm_slider_add(win);
+   elm_slider_label_set(sl, "Label 2");
+   elm_slider_span_size_set(sl, 80);
+   evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
+   evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_slider_indicator_format_set(sl, "%3.0f");
+   elm_slider_min_max_set(sl, 50, 150);
+   elm_slider_value_set(sl, 80);
+   elm_slider_inverted_set(sl, 1);
+   evas_object_size_hint_align_set(sl, 0.5, 0.5);
+   evas_object_size_hint_weight_set(sl, 0.0, 0.0);
+   elm_box_pack_end(bx, sl);
+   evas_object_show(ic);
+   evas_object_show(sl);
+
+   sl = elm_slider_add(win);
+   elm_slider_label_set(sl, "Label 3");
+   elm_slider_unit_format_set(sl, "units");
+   elm_slider_span_size_set(sl, 40);
+   evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
+   evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_slider_indicator_format_set(sl, "%3.0f");
+   elm_slider_min_max_set(sl, 50, 150);
+   elm_slider_value_set(sl, 80);
+   elm_slider_inverted_set(sl, 1);
+   elm_object_scale_set(sl, 2.0);
+   elm_box_pack_end(bx, sl);
+   evas_object_show(ic);
+   evas_object_show(sl);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_HORIZONTAL, 1, 1);
+
+   sl = elm_slider_add(win);
+   elm_slider_icon_set(sl, ic);
+   elm_slider_label_set(sl, "Label 4");
+   elm_slider_inverted_set(sl, 1);
+   elm_slider_unit_format_set(sl, "units");
+   elm_slider_span_size_set(sl, 60);
+   evas_object_size_hint_align_set(sl, 0.5, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(sl, 0.0, EVAS_HINT_EXPAND);
+   elm_slider_indicator_format_set(sl, "%1.1f");
+   elm_slider_value_set(sl, 0.2);
+   elm_object_scale_set(sl, 1.0);
+   elm_slider_horizontal_set(sl, 0);
+   elm_box_pack_end(bx, sl);
+   evas_object_show(ic);
+   evas_object_show(sl);
+
+
+   evas_object_smart_callback_add(sl1, "changed", _change_cb, sl);
+
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_slideshow.c b/src/bin/test_slideshow.c
new file mode 100644 (file)
index 0000000..123fecc
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+
+static Evas_Object *slideshow, *bt_start, *bt_stop;
+static Elm_Slideshow_Item_Class itc;
+static char *img1 = PACKAGE_DATA_DIR"/images/logo.png";
+static char *img2 = PACKAGE_DATA_DIR"/images/plant_01.jpg";
+static char *img3 = PACKAGE_DATA_DIR"/images/rock_01.jpg";
+static char *img4 = PACKAGE_DATA_DIR"/images/rock_02.jpg";
+static char *img5 = PACKAGE_DATA_DIR"/images/sky_01.jpg";
+static char *img6 = PACKAGE_DATA_DIR"/images/sky_04.jpg";
+static char *img7 = PACKAGE_DATA_DIR"/images/wood_01.jpg";
+
+static void
+_notify_show(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+   evas_object_show(data);
+   elm_notify_timer_init(data);
+}
+
+static void
+_next(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_slideshow_next(data);
+}
+
+static void
+_previous(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_slideshow_previous(data);
+}
+
+static void
+_mouse_in(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+   elm_notify_timeout_set(data, 0);
+}
+
+
+static void
+_mouse_out(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+   elm_notify_timeout_set(data, 3);
+}
+
+static void
+_hv_select(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_slideshow_transition_set(slideshow, data);
+   elm_hoversel_label_set(obj, data);
+}
+
+static void
+_start(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_slideshow_timeout_set(slideshow, (int)elm_spinner_value_get(data));
+
+   elm_object_disabled_set(bt_start, 1);
+   elm_object_disabled_set(bt_stop, 0);
+}
+
+static void
+_stop(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_slideshow_timeout_set(slideshow, 0);
+   elm_object_disabled_set(bt_start, 0);
+   elm_object_disabled_set(bt_stop, 1);
+}
+
+static void
+_spin(void *data, Evas_Object *obj, void *event_info)
+{
+   if (elm_slideshow_timeout_get(slideshow) > 0)
+     elm_slideshow_timeout_set(slideshow, (int)elm_spinner_value_get(data));
+}
+
+static Evas_Object *
+_get(void *data, Evas_Object *obj)
+{
+   Evas_Object *photo = elm_photocam_add(obj);
+   elm_photocam_file_set(photo, data);
+   elm_photocam_zoom_mode_set(photo, ELM_PHOTOCAM_ZOOM_MODE_AUTO_FIT);
+   return photo;
+}
+
+
+
+void
+test_slideshow(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *notify, *bx, *bt, *hv, *spin;
+   const Eina_List *l;
+   const char *transition;
+
+   win = elm_win_add(NULL, "Slideshow", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Slideshow");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   slideshow = elm_slideshow_add(win);
+   elm_slideshow_loop_set(slideshow, 1);
+   elm_win_resize_object_add(win, slideshow);
+   evas_object_size_hint_weight_set(slideshow, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(slideshow);
+
+   itc.func.get = _get;
+   itc.func.del = NULL;
+
+   elm_slideshow_item_add(slideshow, &itc, img1);
+   elm_slideshow_item_add(slideshow, &itc, img2);
+   elm_slideshow_item_add(slideshow, &itc, img3);
+   elm_slideshow_item_add(slideshow, &itc, img4);
+   elm_slideshow_item_add(slideshow, &itc, img5);
+   elm_slideshow_item_add(slideshow, &itc, img6);
+   elm_slideshow_item_add(slideshow, &itc, img7);
+
+   notify = elm_notify_add(win);
+   elm_notify_orient_set(notify, ELM_NOTIFY_ORIENT_BOTTOM);
+   elm_win_resize_object_add(win, notify);
+   elm_notify_timeout_set(notify, 3);
+
+   bx = elm_box_add(win);
+   elm_box_horizontal_set(bx, 1);
+   elm_notify_content_set(notify, bx);
+   evas_object_show(bx);
+
+   evas_object_event_callback_add(bx, EVAS_CALLBACK_MOUSE_IN, _mouse_in, notify);
+   evas_object_event_callback_add(bx, EVAS_CALLBACK_MOUSE_OUT, _mouse_out, notify);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Previous");
+   evas_object_smart_callback_add(bt, "clicked", _previous, slideshow);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Next");
+   evas_object_smart_callback_add(bt, "clicked", _next, slideshow);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   hv = elm_hoversel_add(win);
+   elm_box_pack_end(bx, hv);
+   elm_hoversel_hover_parent_set(hv, win);
+   EINA_LIST_FOREACH(elm_slideshow_transitions_get(slideshow), l, transition)
+      elm_hoversel_item_add(hv, transition, NULL, 0, _hv_select, transition);
+   elm_hoversel_label_set(hv, eina_list_data_get(elm_slideshow_transitions_get(slideshow)));
+   evas_object_show(hv);
+
+   spin = elm_spinner_add(win);
+   elm_spinner_label_format_set(spin, "%2.0f secs.");
+   evas_object_smart_callback_add(spin, "changed", _spin, spin);
+   elm_spinner_step_set(spin, 1);
+   elm_spinner_min_max_set(spin, 1, 30);
+   elm_spinner_value_set(spin, 3);
+   elm_box_pack_end(bx, spin);
+   evas_object_show(spin);
+
+   bt = elm_button_add(win);
+   bt_start = bt;
+   elm_button_label_set(bt, "Start");
+   evas_object_smart_callback_add(bt, "clicked", _start, spin);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   bt_stop = bt;
+   elm_button_label_set(bt, "Stop");
+   evas_object_smart_callback_add(bt, "clicked", _stop, spin);
+   elm_box_pack_end(bx, bt);
+   elm_object_disabled_set(bt, 1);
+   evas_object_show(bt);
+
+
+   evas_object_event_callback_add(slideshow, EVAS_CALLBACK_MOUSE_UP, _notify_show, notify);
+   evas_object_event_callback_add(slideshow, EVAS_CALLBACK_MOUSE_MOVE, _notify_show, notify);
+
+   evas_object_resize(win, 350, 200);
+   evas_object_show(win);
+}
+
+#endif
diff --git a/src/bin/test_spinner.c b/src/bin/test_spinner.c
new file mode 100644 (file)
index 0000000..d57a8ed
--- /dev/null
@@ -0,0 +1,86 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+void
+test_spinner(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *sp;
+
+   win = elm_win_add(NULL, "spinner", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Spinner");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   sp = elm_spinner_add(win);
+   elm_spinner_label_format_set(sp, "%1.1f units");
+   elm_spinner_step_set(sp, 1.3);
+   elm_spinner_wrap_set(sp, 1);
+   elm_spinner_min_max_set(sp, -50.0, 250.0);
+   evas_object_size_hint_align_set(sp, EVAS_HINT_FILL, 0.5);
+   evas_object_size_hint_weight_set(sp, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx, sp);
+   evas_object_show(sp);
+
+   sp = elm_spinner_add(win);
+   elm_spinner_label_format_set(sp, "Percentage %%%1.2f something");
+   elm_spinner_step_set(sp, 5.0);
+   elm_spinner_wrap_set(sp, 1);
+   elm_spinner_min_max_set(sp, 0.0, 100.0);
+   evas_object_size_hint_align_set(sp, EVAS_HINT_FILL, 0.5);
+   evas_object_size_hint_weight_set(sp, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx, sp);
+   evas_object_show(sp);
+
+   sp = elm_spinner_add(win);
+   elm_spinner_label_format_set(sp, "%1.1f units");
+   elm_spinner_step_set(sp, 1.3);
+   elm_spinner_wrap_set(sp, 1);
+   elm_object_style_set (sp, "vertical");
+   elm_spinner_min_max_set(sp, -50.0, 250.0);
+   evas_object_size_hint_align_set(sp, EVAS_HINT_FILL, 0.5);
+   evas_object_size_hint_weight_set(sp, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx, sp);
+   evas_object_show(sp);
+
+   sp = elm_spinner_add(win);
+   elm_spinner_label_format_set(sp, "Disabled %.0f");
+   elm_object_disabled_set(sp, 1);
+   elm_spinner_min_max_set(sp, -50.0, 250.0);
+   evas_object_size_hint_align_set(sp, EVAS_HINT_FILL, 0.5);
+   evas_object_size_hint_weight_set(sp, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx, sp);
+   evas_object_show(sp);
+
+   sp = elm_spinner_add(win);
+   elm_spinner_min_max_set(sp, 1, 12);
+   elm_spinner_label_format_set(sp, "%.0f");
+   elm_spinner_step_set(sp, 1.0);
+   elm_spinner_editable_set(sp, EINA_FALSE);
+   elm_spinner_special_value_add(sp, 1, "January");
+   elm_spinner_special_value_add(sp, 2, "February");
+   elm_spinner_special_value_add(sp, 3, "March");
+   elm_spinner_special_value_add(sp, 4, "April");
+   elm_spinner_special_value_add(sp, 5, "May");
+   elm_spinner_special_value_add(sp, 6, "June");
+   elm_spinner_special_value_add(sp, 7, "July");
+   elm_spinner_special_value_add(sp, 8, "August");
+   elm_spinner_special_value_add(sp, 9, "September");
+   elm_spinner_special_value_add(sp, 10, "October");
+   elm_spinner_special_value_add(sp, 11, "November");
+   elm_spinner_special_value_add(sp, 12, "December");
+   evas_object_size_hint_align_set(sp, EVAS_HINT_FILL, 0.5);
+   evas_object_size_hint_weight_set(sp, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx, sp);
+   evas_object_show(sp);
+
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_table.c b/src/bin/test_table.c
new file mode 100644 (file)
index 0000000..8ec607b
--- /dev/null
@@ -0,0 +1,66 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+void
+test_table(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *tb, *bt;
+
+   win = elm_win_add(NULL, "table", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Table");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+
+   tb = elm_table_add(win);
+   elm_win_resize_object_add(win, tb);
+   evas_object_size_hint_weight_set(tb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(tb);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button 1");
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_table_pack(tb, bt, 0, 0, 1, 1);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button 2");
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_table_pack(tb, bt, 1, 0, 1, 1);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button 3");
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_table_pack(tb, bt, 2, 0, 1, 1);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button 4");
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_table_pack(tb, bt, 0, 1, 2, 1);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button 5");
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_table_pack(tb, bt, 2, 1, 1, 3);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Button 6");
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_table_pack(tb, bt, 0, 2, 2, 2);
+   evas_object_show(bt);
+
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_thumb.c b/src/bin/test_thumb.c
new file mode 100644 (file)
index 0000000..d55242b
--- /dev/null
@@ -0,0 +1,68 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+void
+test_thumb(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *sc, *tb, *th;
+   int i, j, n;
+   char buf[PATH_MAX];
+   const char *img[9] =
+     {
+       "panel_01.jpg",
+       "plant_01.jpg",
+       "rock_01.jpg",
+       "rock_02.jpg",
+       "sky_01.jpg",
+       "sky_02.jpg",
+       "sky_03.jpg",
+       "sky_04.jpg",
+       "wood_01.jpg",
+     };
+
+   elm_need_ethumb();
+
+   win = elm_win_add(NULL, "thumb", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Thumb");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+
+   tb = elm_table_add(win);
+   evas_object_size_hint_weight_set(tb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+   n = 0;
+   for (j = 0; j < 12; j++)
+     {
+        for (i = 0; i < 12; i++)
+          {
+             th = elm_thumb_add(win);
+             snprintf(buf, sizeof(buf), "%s/images/%s", PACKAGE_DATA_DIR,
+                     img[n]);
+            n = (n + 1) % 9;
+             elm_thumb_file_set(th, buf, img[n]);
+             evas_object_size_hint_weight_set(th, EVAS_HINT_EXPAND,
+                                              EVAS_HINT_EXPAND);
+            evas_object_size_hint_align_set(th, EVAS_HINT_FILL,
+                                            EVAS_HINT_FILL);
+            elm_thumb_align_set(th, 0.5, 0.5);
+            elm_thumb_keep_aspect_set(th, EINA_TRUE);
+             elm_table_pack(tb, th, i, j, 1, 1);
+             evas_object_show(th);
+          }
+     }
+
+   sc = elm_scroller_add(win);
+   evas_object_size_hint_weight_set(sc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, sc);
+
+   elm_scroller_content_set(sc, tb);
+   evas_object_show(tb);
+   evas_object_show(sc);
+
+   evas_object_resize(win, 600, 600);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_toggle.c b/src/bin/test_toggle.c
new file mode 100644 (file)
index 0000000..5c914c4
--- /dev/null
@@ -0,0 +1,84 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+void
+test_toggle(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *ic, *tg;
+   char buf[PATH_MAX];
+
+   win = elm_win_add(NULL, "toggles", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Toggles");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+
+   tg = elm_toggle_add(win);
+   evas_object_size_hint_weight_set(tg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(tg, EVAS_HINT_FILL, 0.5);
+   elm_toggle_label_set(tg, "Icon sized to toggle");
+   elm_toggle_icon_set(tg, ic);
+   elm_toggle_state_set(tg, 1);
+   elm_toggle_states_labels_set(tg, "Yes", "No");
+   elm_box_pack_end(bx, tg);
+   evas_object_show(tg);
+   evas_object_show(ic);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+
+   tg = elm_toggle_add(win);
+   elm_toggle_label_set(tg, "Icon no scale");
+   elm_toggle_icon_set(tg, ic);
+   elm_box_pack_end(bx, tg);
+   evas_object_show(tg);
+   evas_object_show(ic);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+
+   tg = elm_toggle_add(win);
+   elm_toggle_label_set(tg, "Icon no scale");
+   elm_toggle_icon_set(tg, ic);
+   elm_object_disabled_set(tg, 1);
+   elm_box_pack_end(bx, tg);
+   evas_object_show(tg);
+   evas_object_show(ic);
+
+   tg = elm_toggle_add(win);
+   elm_toggle_label_set(tg, "Label Only");
+   elm_toggle_states_labels_set(tg, "Big long fun times label", 
+                                "Small long happy fun label");
+   elm_box_pack_end(bx, tg);
+   evas_object_show(tg);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_icon_scale_set(ic, 0, 0);
+
+   tg = elm_toggle_add(win);
+   elm_toggle_icon_set(tg, ic);
+   elm_box_pack_end(bx, tg);
+   evas_object_show(tg);
+   evas_object_show(ic);
+
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_toolbar.c b/src/bin/test_toolbar.c
new file mode 100644 (file)
index 0000000..29bc2a4
--- /dev/null
@@ -0,0 +1,177 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+static void
+tb_1(void *data, Evas_Object *obj, void *event_info)
+{
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf), "%s/images/panel_01.jpg", PACKAGE_DATA_DIR);
+   elm_photo_file_set(data, buf);
+}
+
+static void
+tb_2(void *data, Evas_Object *obj, void *event_info)
+{
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf), "%s/images/rock_01.jpg", PACKAGE_DATA_DIR);
+   elm_photo_file_set(data, buf);
+}
+
+static void
+tb_3(void *data, Evas_Object *obj, void *event_info)
+{
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf), "%s/images/wood_01.jpg", PACKAGE_DATA_DIR);
+   elm_photo_file_set(data, buf);
+}
+
+static void
+tb_4(void *data, Evas_Object *obj, void *event_info)
+{
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf), "%s/images/sky_03.jpg", PACKAGE_DATA_DIR);
+   elm_photo_file_set(data, buf);
+}
+
+static void
+tb_5(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_photo_file_set(data, NULL);
+}
+
+void
+test_toolbar(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *bx, *tb, *ic, *ph, *menu;
+   Evas_Object *ph1, *ph2, *ph3, *ph4;
+   Elm_Toolbar_Item *item;
+   Elm_Menu_Item *menu_item;
+   char buf[PATH_MAX];
+
+   win = elm_win_add(NULL, "toolbar", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Toolbar");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   elm_win_resize_object_add(win, bx);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bx);
+
+   tb = elm_toolbar_add(win);
+   elm_toolbar_homogenous_set(tb, 0);
+   evas_object_size_hint_weight_set(tb, 0.0, 0.0);
+   evas_object_size_hint_align_set(tb, EVAS_HINT_FILL, 0.0);
+   
+   ph1 = elm_photo_add(win);
+   ph2 = elm_photo_add(win);
+   ph3 = elm_photo_add(win);
+   ph4 = elm_photo_add(win);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   item = elm_toolbar_item_add(tb, ic, "Hello", tb_1, ph1);
+   elm_toolbar_item_disabled_set(item, EINA_TRUE);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_toolbar_item_add(tb, ic, "World", tb_2, ph1);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_toolbar_item_add(tb, ic, "H", tb_3, ph4);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_toolbar_item_add(tb, ic, "Comes", tb_4, ph4);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_toolbar_item_add(tb, ic, "Elementary", tb_5, ph4);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   item = elm_toolbar_item_add(tb, ic, "Menu", NULL, NULL);
+   elm_toolbar_item_menu_set(item, 1);
+   elm_toolbar_menu_parent_set(tb, win);
+   menu = elm_toolbar_item_menu_get(item);
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_menu_item_add(menu, NULL, ic, "Here", tb_3, ph4);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   menu_item = elm_menu_item_add(menu, NULL, ic, "Comes", tb_4, ph4);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   elm_menu_item_add(menu, menu_item, ic, "hey ho", tb_4, ph4);
+
+   ic = elm_icon_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(ic, buf, NULL);
+   menu_item = elm_menu_item_add(menu, NULL, ic, "Elementary", tb_5, ph4);
+
+   elm_box_pack_end(bx, tb);
+   evas_object_show(tb);
+
+   tb = elm_table_add(win);
+   //elm_table_homogenous_set(tb, 1);
+   evas_object_size_hint_weight_set(tb, 0.0, EVAS_HINT_EXPAND);
+   evas_object_size_hint_fill_set(tb, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   ph = ph1;
+   elm_photo_size_set(ph, 40);
+   snprintf(buf, sizeof(buf), "%s/images/plant_01.jpg", PACKAGE_DATA_DIR);
+   elm_photo_file_set(ph, buf);
+   evas_object_size_hint_weight_set(ph, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ph, 0.5, 0.5);
+   elm_table_pack(tb, ph, 0, 0, 1, 1);
+   evas_object_show(ph);
+
+   ph = ph2;
+   elm_photo_size_set(ph, 80);
+   evas_object_size_hint_weight_set(ph, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ph, 0.5, 0.5);
+   elm_table_pack(tb, ph, 1, 0, 1, 1);
+   evas_object_show(ph);
+
+   ph = ph3;
+   elm_photo_size_set(ph, 20);
+   snprintf(buf, sizeof(buf), "%s/images/sky_01.jpg", PACKAGE_DATA_DIR);
+   elm_photo_file_set(ph, buf);
+   evas_object_size_hint_weight_set(ph, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ph, 0.5, 0.5);
+   elm_table_pack(tb, ph, 0, 1, 1, 1);
+   evas_object_show(ph);
+
+   ph = ph4;
+   elm_photo_size_set(ph, 60);
+   snprintf(buf, sizeof(buf), "%s/images/sky_02.jpg", PACKAGE_DATA_DIR);
+   elm_photo_file_set(ph, buf);
+   evas_object_size_hint_weight_set(ph, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ph, 0.5, 0.5);
+   elm_table_pack(tb, ph, 1, 1, 1, 1);
+   evas_object_show(ph);
+
+   elm_box_pack_end(bx, tb);
+   evas_object_show(tb);
+
+   evas_object_resize(win, 320, 300);
+
+   evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_weather.c b/src/bin/test_weather.c
new file mode 100644 (file)
index 0000000..f480629
--- /dev/null
@@ -0,0 +1,175 @@
+#include <Elementary.h>
+#include "../../elementary_config.h"
+#ifndef ELM_LIB_QUICKLAUNCH
+
+#ifdef HAVE_ELEMENTARY_EWEATHER
+# include "EWeather_Smart.h"
+#endif
+
+#ifdef HAVE_ELEMENTARY_EWEATHER
+static Evas_Object *en, *hv, *fl;
+static Evas_Object *weather[2];
+static int current = 0;
+static Eina_Module *module[2];
+
+static void
+_first_city_cb(void *data, Evas_Object *o, void *event_info)
+{
+   if (!current) return;
+   current = 0;
+   elm_flip_go(fl, ELM_FLIP_ROTATE_YZ_CENTER_AXIS);
+}
+
+static void
+_second_city_cb(void *data, Evas_Object *o, void *event_info)
+{
+   if (current) return;
+   current = 1;
+   elm_flip_go(fl, ELM_FLIP_ROTATE_XZ_CENTER_AXIS);
+}
+
+static void _apply_cb(void *data, Evas_Object *o, void *event_info)
+{
+   EWeather *eweather = eweather_object_eweather_get(weather[current]);
+   
+   if (module[current])
+     eweather_plugin_set(eweather, module[current]);
+   eweather_code_set(eweather, elm_entry_entry_get(en));
+   printf("CURRENT %d %p %p\n", current, module[current], eweather);
+}
+
+static void
+_hover_select_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   EWeather *eweather = eweather_object_eweather_get(weather[0]);
+   module[0] = eweather_plugin_search(eweather, elm_hoversel_item_label_get(event_info));
+   
+   eweather = eweather_object_eweather_get(weather[1]);
+   module[1] = eweather_plugin_search(eweather, elm_hoversel_item_label_get(event_info));
+   printf("%p %p\n", module[0], module[1]);
+}
+#endif
+
+void
+test_weather(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg;
+#ifdef HAVE_ELEMENTARY_EWEATHER
+   Evas_Object *bx, *bx0, *bt;
+   EWeather *eweather;
+   Eina_Array_Iterator it;
+   Eina_Array *array;
+   Eina_Module *m;
+   int i;
+#endif
+
+   win = elm_win_add(NULL, "weather", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Weather");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+
+#ifdef HAVE_ELEMENTARY_EWEATHER 
+   bx = elm_box_add(win);
+   elm_win_resize_object_add(win, bx);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bx);
+
+   fl = elm_flip_add(win);
+   evas_object_size_hint_align_set(fl, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(fl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx, fl);
+
+   current = 0;
+
+   module[0] = NULL;
+   weather[0] = eweather_object_add(evas_object_evas_get(win));
+   eweather = eweather_object_eweather_get(weather[0]);
+   evas_object_size_hint_weight_set(weather[0], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(weather[0], -1.0, -1.0);
+   elm_flip_content_front_set(fl, weather[0]);
+   evas_object_show(weather[0]);
+
+   module[1] = NULL;
+   weather[1] = eweather_object_add(evas_object_evas_get(win));
+   eweather = eweather_object_eweather_get(weather[1]);
+   evas_object_size_hint_weight_set(weather[1], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(weather[1], -1.0, -1.0);
+   elm_flip_content_back_set(fl, weather[1]);
+   evas_object_show(weather[1]);
+
+   evas_object_show(fl);
+
+   //
+   bx0 = elm_box_add(win);
+   elm_box_horizontal_set(bx0, EINA_TRUE);
+   evas_object_size_hint_weight_set(bx0, 1.0, 0.0);
+   elm_box_pack_end(bx, bx0);
+   evas_object_show(bx0);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "First city");
+   evas_object_show(bt);
+   elm_box_pack_end(bx0, bt);
+   evas_object_smart_callback_add(bt, "clicked", _first_city_cb, NULL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Second city");
+   evas_object_show(bt);
+   elm_box_pack_end(bx0, bt);
+   evas_object_smart_callback_add(bt, "clicked", _second_city_cb, NULL);
+   //
+
+   //
+   bx0 = elm_box_add(win);
+   elm_box_horizontal_set(bx0, EINA_TRUE);
+   evas_object_size_hint_weight_set(bx0, 1.0, 0.0);
+   elm_box_pack_end(bx, bx0);
+   evas_object_show(bx0);
+
+   hv = elm_hoversel_add(win);
+   elm_hoversel_hover_parent_set(hv, win);
+   elm_hoversel_label_set(hv, "data source");
+   evas_object_size_hint_weight_set(hv, 0.0, 0.0);
+   evas_object_size_hint_align_set(hv, 0.5, 0.5);
+   elm_box_pack_end(bx0, hv);
+   evas_object_show(hv);
+
+   array = eweather_plugins_list_get(eweather);
+   
+   EINA_ARRAY_ITER_NEXT(array, i, m, it)
+     elm_hoversel_item_add(hv, eweather_plugin_name_get(eweather, i), NULL, ELM_ICON_NONE, _hover_select_cb, NULL);
+   
+   en = elm_entry_add(win);
+   elm_entry_line_wrap_set(en, 0);
+   elm_entry_single_line_set(en, EINA_TRUE);
+   elm_entry_entry_set(en, "Paris");
+   evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(en, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx0, en);
+   evas_object_show(en);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Apply");
+   evas_object_show(bt);
+   elm_box_pack_end(bx0, bt);
+   evas_object_smart_callback_add(bt, "clicked", _apply_cb, NULL);
+   //
+
+
+#else
+    Evas_Object *lbl;
+    
+    lbl = elm_label_add(win);
+    elm_win_resize_object_add(win, lbl);
+    elm_label_label_set(lbl, "libeweather is required to display the forecast.");
+    evas_object_show(lbl);
+#endif
+
+    evas_object_resize(win, 244, 388);
+    evas_object_show(win);
+}
+#endif
diff --git a/src/bin/test_win_state.c b/src/bin/test_win_state.c
new file mode 100644 (file)
index 0000000..2d771da
--- /dev/null
@@ -0,0 +1,366 @@
+#include <Elementary.h>
+#ifndef ELM_LIB_QUICKLAUNCH
+typedef struct _Testitem
+{
+   Elm_Genlist_Item *item;
+   int mode, onoff;
+} Testitem;
+
+static int rotate_with_resize = 0;
+
+static void
+my_bt_38_alpha_on(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win = data;
+   Evas_Object *bg = evas_object_data_get(win, "bg");
+   evas_object_hide(bg);
+   elm_win_alpha_set(win, 1);
+}
+
+static void
+my_bt_38_alpha_off(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win = data;
+   Evas_Object *bg = evas_object_data_get(win, "bg");
+   evas_object_show(bg);
+   elm_win_alpha_set(win, 0);
+}
+
+static void
+my_ck_38_resize(void *data, Evas_Object *obj, void *event_info)
+{
+//   Evas_Object *win = data;
+   rotate_with_resize = elm_check_state_get(obj);
+}
+
+static void
+my_bt_38_rot_0(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win = data;
+   if (rotate_with_resize)
+     elm_win_rotation_with_resize_set(win, 0);
+   else        
+     elm_win_rotation_set(win, 0);
+}
+
+static void
+my_bt_38_rot_90(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win = data;
+   if (rotate_with_resize)
+     elm_win_rotation_with_resize_set(win, 90);
+   else        
+     elm_win_rotation_set(win, 90);
+}
+
+static void
+my_bt_38_rot_180(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win = data;
+   if (rotate_with_resize)
+     elm_win_rotation_with_resize_set(win, 180);
+   else        
+     elm_win_rotation_set(win, 180);
+}
+
+static void
+my_bt_38_rot_270(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win = data;
+   if (rotate_with_resize)
+     elm_win_rotation_with_resize_set(win, 270);
+   else        
+     elm_win_rotation_set(win, 270);
+}
+
+static void
+my_win_move(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Coord x, y;
+   elm_win_screen_position_get(obj, &x, &y);
+   printf("MOVE - win geom: %4i %4i\n", x, y);
+}
+
+static void
+_win_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+   Evas_Coord w, h;
+   evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+   printf("RESIZE - win geom: %4ix%4i\n", w, h);
+}
+
+static void
+_win_foc_in(void *data, Evas *e, void *event_info)
+{
+   printf("FOC IN\n");
+}
+
+static void
+_win_foc_out(void *data, Evas *e, void *event_info)
+{
+   printf("FOC OUT\n");
+}
+
+static void
+_close_win(void *data, Evas *e, void *event_info)
+{
+   evas_object_del(data);
+}
+
+void
+test_win_state(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *sl, *bx, *bx2, *bt, *ck;
+
+   win = elm_win_add(NULL, "window-state", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Window States");
+   evas_object_smart_callback_add(win, "moved", my_win_move, NULL);
+   evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE, _win_resize, NULL);
+   evas_event_callback_add(evas_object_evas_get(win), EVAS_CALLBACK_CANVAS_FOCUS_IN, _win_foc_in, NULL);
+   evas_event_callback_add(evas_object_evas_get(win), EVAS_CALLBACK_CANVAS_FOCUS_OUT, _win_foc_out, NULL);
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+   evas_object_data_set(win, "bg", bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   elm_box_homogenous_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_fill_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Alpha On");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_38_alpha_on, win);
+   evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Alpha Off");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_38_alpha_off, win);
+   evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   elm_box_homogenous_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_fill_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   sl = elm_slider_add(win);
+   elm_slider_label_set(sl, "Test");
+   elm_slider_span_size_set(sl, 100);
+   evas_object_size_hint_align_set(sl, 0.5, 0.5);
+   evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_slider_indicator_format_set(sl, "%3.0f");
+   elm_slider_min_max_set(sl, 50, 150);
+   elm_slider_value_set(sl, 50);
+   elm_slider_inverted_set(sl, 1);
+   elm_box_pack_end(bx2, sl);
+   evas_object_show(sl);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   ck = elm_check_add(win);
+   elm_check_label_set(ck, "resize");
+   elm_check_state_set(ck, rotate_with_resize);
+   evas_object_smart_callback_add(ck, "changed", my_ck_38_resize, win);
+   evas_object_size_hint_weight_set(ck, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ck, 0.02, 0.99);
+   evas_object_show(ck); 
+   elm_box_pack_end(bx, ck);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   elm_box_homogenous_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_fill_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Rot 0");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_38_rot_0, win);
+   evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Rot 90");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_38_rot_90, win);
+   evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Rot 180");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_38_rot_180, win);
+   evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Rot 270");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_38_rot_270, win);
+   evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   evas_object_resize(win, 280, 400);
+   evas_object_show(win);
+}
+
+void
+test_win_state2(void *data, Evas_Object *obj, void *event_info)
+{
+   Evas_Object *win, *bg, *sl, *bx, *bx2, *bt, *ck;
+   char buf[PATH_MAX];
+   
+   win = elm_win_add(NULL, "window-state2", ELM_WIN_BASIC);
+   elm_win_override_set(win, 1);
+   evas_object_smart_callback_add(win, "moved", my_win_move, NULL);
+   evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE, _win_resize, NULL);
+   elm_win_title_set(win, "Window States 2");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   snprintf(buf, sizeof(buf), "%s/images/sky_02.jpg", PACKAGE_DATA_DIR);
+   elm_bg_file_set(bg, buf, NULL);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+   evas_object_data_set(win, "bg", bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_fill_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Alpha On");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_38_alpha_on, win);
+   evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, 0.0, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Alpha Off");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_38_alpha_off, win);
+   evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, 0.0, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Close");
+   evas_object_smart_callback_add(bt, "clicked", _close_win, win);
+   evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   elm_box_homogenous_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_fill_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   sl = elm_slider_add(win);
+   elm_slider_label_set(sl, "Override Redirect");
+   elm_slider_span_size_set(sl, 100);
+   evas_object_size_hint_align_set(sl, 0.5, 0.5);
+   evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_slider_indicator_format_set(sl, "%3.0f");
+   elm_slider_min_max_set(sl, 50, 150);
+   elm_slider_value_set(sl, 50);
+   elm_slider_inverted_set(sl, 1);
+   elm_box_pack_end(bx2, sl);
+   evas_object_show(sl);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   ck = elm_check_add(win);
+   elm_check_label_set(ck, "resize");
+   elm_check_state_set(ck, rotate_with_resize);
+   evas_object_smart_callback_add(ck, "changed", my_ck_38_resize, win);
+   evas_object_size_hint_weight_set(ck, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ck, 0.02, 0.99);
+   evas_object_show(ck); 
+   elm_box_pack_end(bx, ck);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, 1);
+   elm_box_homogenous_set(bx2, 1);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_fill_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Rot 0");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_38_rot_0, win);
+   evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Rot 90");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_38_rot_90, win);
+   evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Rot 180");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_38_rot_180, win);
+   evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, "Rot 270");
+   evas_object_smart_callback_add(bt, "clicked", my_bt_38_rot_270, win);
+   evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   evas_object_show(bt);
+
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx2);
+
+   evas_object_resize(win, 320, 480);
+   evas_object_show(win);
+}
+#endif
diff --git a/src/edje_externals/Makefile.am b/src/edje_externals/Makefile.am
new file mode 100644 (file)
index 0000000..5d56695
--- /dev/null
@@ -0,0 +1,54 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_builddir) \
+-I$(top_srcdir) \
+-I$(top_srcdir)/src/lib \
+-I$(top_builddir)/src/lib \
+-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
+-DPACKAGE_LIB_DIR=\"$(libdir)\" \
+@ELEMENTARY_CFLAGS@ \
+@ELEMENTARY_X_CFLAGS@ \
+@ELEMENTARY_FB_CFLAGS@ \
+@ELEMENTARY_WIN32_CFLAGS@ \
+@ELEMENTARY_WINCE_CFLAGS@ \
+@ELEMENTARY_EDBUS_CFLAGS@ \
+@ELEMENTARY_EFREET_CFLAGS@
+
+if ELEMENTARY_WINDOWS_BUILD
+AM_CPPFLAGS += -DELEMENTARY_BUILD
+endif
+
+pkgdir = $(libdir)/edje
+pkg_LTLIBRARIES = elm.la
+
+elm_la_SOURCES = private.h \
+modules.inc \
+elm.c \
+elm_anchorblock.c \
+elm_anchorview.c \
+elm_bubble.c \
+elm_button.c \
+elm_check.c \
+elm_clock.c \
+elm_fileselector.c \
+elm_fileselector_button.c \
+elm_genlist.c \
+elm_hoversel.c \
+elm_list.c \
+elm_map.c \
+elm_notepad.c \
+elm_photocam.c \
+elm_progressbar.c \
+elm_radio.c \
+elm_scrolled_entry.c \
+elm_slider.c \
+elm_slideshow.c \
+elm_spinner.c \
+elm_thumb.c \
+elm_toggle.c \
+elm_toolbar.c
+
+elm_la_LIBADD = $(top_builddir)/src/lib/libelementary.la
+elm_la_LDFLAGS = $(all_libraries) -no-undefined @lt_enable_auto_import@ -module -avoid-version -shared -fPIC
diff --git a/src/edje_externals/elm.c b/src/edje_externals/elm.c
new file mode 100644 (file)
index 0000000..b2a815e
--- /dev/null
@@ -0,0 +1,207 @@
+#include "Elementary.h"
+#include "private.h"
+
+int _elm_log_dom = -1;
+
+void
+external_signal(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const char *signal, const char *source)
+{
+   printf("External Signal received: '%s' '%s'\n", signal, source);
+}
+
+const char *
+external_translate(void *data __UNUSED__, const char *orig)
+{
+   // in future, mark all params as translatable and use dgettext()
+   // with "elementary" text domain here.
+   return orig;
+}
+
+typedef struct {
+   const char *emission;
+   const char *source;
+   Evas_Object *edje;
+} Elm_External_Signals_Proxy_Context;
+
+static void
+_external_signal_proxy_free_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Elm_External_Signals_Proxy_Context *ctxt = data;
+   free(ctxt);
+}
+
+static void
+_external_signal_proxy_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Elm_External_Signals_Proxy_Context *ctxt = data;
+   // TODO: Is it worth to check Evas_Smart_Cb_Description and do something
+   // TODO: with event_info given its description?
+   edje_object_signal_emit(ctxt->edje, ctxt->emission, ctxt->source);
+}
+
+void
+external_signals_proxy(Evas_Object *obj, Evas_Object *edje, const char *part_name)
+{
+   const Evas_Smart_Cb_Description **cls_descs, **inst_descs;
+   unsigned int cls_count, inst_count, total;
+   Elm_External_Signals_Proxy_Context *ctxt;
+
+   evas_object_smart_callbacks_descriptions_get
+     (obj, &cls_descs, &cls_count, &inst_descs, &inst_count);
+
+   total = cls_count + inst_count;
+   if (!total) return;
+   ctxt = malloc(sizeof(Elm_External_Signals_Proxy_Context) * total);
+   if (!ctxt) return;
+   evas_object_event_callback_add
+     (obj, EVAS_CALLBACK_DEL, _external_signal_proxy_free_cb, ctxt);
+
+   for (; cls_count > 0; cls_count--,  cls_descs++, ctxt++)
+     {
+       const Evas_Smart_Cb_Description *d = *cls_descs;
+       ctxt->emission = d->name;
+       ctxt->source = part_name;
+       ctxt->edje = edje;
+       evas_object_smart_callback_add
+         (obj, d->name, _external_signal_proxy_cb, ctxt);
+     }
+
+   for (; inst_count > 0; inst_count--,  inst_descs++, ctxt++)
+     {
+       const Evas_Smart_Cb_Description *d = *inst_descs;
+       ctxt->emission = d->name;
+       ctxt->source = part_name;
+       ctxt->edje = edje;
+       evas_object_smart_callback_add
+         (obj, d->name, _external_signal_proxy_cb, ctxt);
+     }
+}
+
+void *
+external_common_params_parse_internal(size_t params_size, void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params)
+{
+   Elm_Params *p;
+   const Eina_List *l;
+   Edje_External_Param *param;
+
+   if (params_size < sizeof(Elm_Params))
+     return NULL;
+
+   p = calloc(1, params_size);
+   if (!p)
+     return NULL;
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "label"))
+         p->label = param->s;
+     }
+   return p;
+}
+
+Evas_Object *
+external_common_param_icon_get(Evas_Object *obj, const Edje_External_Param *p)
+{
+   Evas_Object *edje, *parent_widget, *icon;
+   const char *file;
+
+   if ((!p) || (!p->s) || (p->type != EDJE_EXTERNAL_PARAM_TYPE_STRING))
+       return NULL;
+
+   edje = evas_object_smart_parent_get(obj);
+   edje_object_file_get(edje, &file, NULL);
+
+   parent_widget = elm_widget_parent_widget_get(obj);
+   if (!parent_widget)
+     parent_widget = edje;
+   icon = elm_icon_add(parent_widget);
+
+   if (elm_icon_file_set(icon, file, p->s))
+     return icon;
+   if (elm_icon_standard_set(icon, p->s))
+     return icon;
+
+   evas_object_del(icon);
+   return NULL;
+}
+
+void
+external_common_icon_param_parse(Evas_Object **icon, Evas_Object *obj, const Eina_List *params)
+{
+   Edje_External_Param *p = edje_external_param_find(params, "icon");
+   *icon = external_common_param_icon_get(obj, p);
+}
+
+Evas_Object *
+external_common_param_edje_object_get(Evas_Object *obj, const Edje_External_Param *p)
+{
+   Evas_Object *edje, *parent_widget, *ret;
+   const char *file;
+
+   if ((!p) || (!p->s) || (p->type != EDJE_EXTERNAL_PARAM_TYPE_STRING))
+       return NULL;
+
+   edje = evas_object_smart_parent_get(obj);
+   edje_object_file_get(edje, &file, NULL);
+
+   parent_widget = elm_widget_parent_widget_get(obj);
+   if (!parent_widget)
+     parent_widget = edje;
+
+   ret = edje_object_add(evas_object_evas_get(parent_widget));
+
+   if (edje_object_file_set(ret, file, p->s))
+     return ret;
+
+   evas_object_del(ret);
+   return NULL;
+}
+
+void
+external_common_params_free(void *params)
+{
+   Elm_Params *p = params;
+   free(p);
+};
+
+#define DEFINE_TYPE(type_name) \
+  extern const Edje_External_Type external_##type_name##_type;
+#include "modules.inc"
+#undef DEFINE_TYPE
+
+static Edje_External_Type_Info elm_external_types[] =
+{
+#define DEFINE_TYPE(type_name)              \
+  {"elm/"#type_name, &external_##type_name##_type},
+#include "modules.inc"
+#undef DEFINE_TYPE
+   {NULL, NULL}
+};
+
+static Eina_Bool
+elm_mod_init(void)
+{
+   int argc = 0;
+   char **argv = NULL;
+
+   ecore_app_args_get(&argc, &argv);
+   elm_init(argc, argv);
+
+   _elm_log_dom = eina_log_domain_register("elm-externals", EINA_COLOR_LIGHTBLUE);
+   edje_external_type_array_register(elm_external_types);
+   return EINA_TRUE;
+}
+
+static void
+elm_mod_shutdown(void)
+{
+   edje_external_type_array_unregister(elm_external_types);
+
+   eina_log_domain_unregister(_elm_log_dom);
+   _elm_log_dom = -1;
+
+   elm_shutdown();
+}
+
+EINA_MODULE_INIT(elm_mod_init);
+EINA_MODULE_SHUTDOWN(elm_mod_shutdown);
diff --git a/src/edje_externals/elm_anchorblock.c b/src/edje_externals/elm_anchorblock.c
new file mode 100644 (file)
index 0000000..cb5dc91
--- /dev/null
@@ -0,0 +1,95 @@
+#include "private.h"
+
+typedef struct _Elm_Params_Anchorblock
+{
+   const char *text;
+} Elm_Params_Anchorblock;
+
+static void
+external_anchorblock_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Anchorblock *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->text)
+     {
+       elm_anchorblock_text_set(obj, p->text);
+     }
+}
+
+static Eina_Bool
+external_anchorblock_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "text"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_anchorblock_text_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_anchorblock_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "text"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_anchorblock_text_get(obj);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_anchorblock_params_parse(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params)
+{
+   Elm_Params_Anchorblock *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = calloc(1, sizeof(Elm_Params_Anchorblock));
+   if (!mem)
+     return NULL;
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "text"))
+         mem->text = eina_stringshare_add(param->s);
+     }
+
+   return mem;
+}
+
+static void
+external_anchorblock_params_free(void *params)
+{
+   Elm_Params_Anchorblock *mem = params;
+
+   if (mem->text)
+     eina_stringshare_del(mem->text);
+   free(mem);
+}
+
+static Edje_External_Param_Info external_anchorblock_params[] = {
+   EDJE_EXTERNAL_PARAM_INFO_STRING_DEFAULT("text", "some text"),
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(anchorblock, "anchorblock")
+DEFINE_EXTERNAL_TYPE_SIMPLE(anchorblock, "Anchorblock");
diff --git a/src/edje_externals/elm_anchorview.c b/src/edje_externals/elm_anchorview.c
new file mode 100644 (file)
index 0000000..88ebdff
--- /dev/null
@@ -0,0 +1,95 @@
+#include "private.h"
+
+typedef struct _Elm_Params_Anchorview
+{
+   const char *text;
+} Elm_Params_Anchorview;
+
+static void
+external_anchorview_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Anchorview *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->text)
+     {
+       elm_anchorview_text_set(obj, p->text);
+     }
+}
+
+static Eina_Bool
+external_anchorview_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "text"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_anchorview_text_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_anchorview_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "text"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_anchorview_text_get(obj);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_anchorview_params_parse(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params)
+{
+   Elm_Params_Anchorview *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = calloc(1, sizeof(Elm_Params_Anchorview));
+   if (!mem)
+     return NULL;
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "text"))
+         mem->text = eina_stringshare_add(param->s);
+     }
+
+   return mem;
+}
+
+static void
+external_anchorview_params_free(void *params)
+{
+   Elm_Params_Anchorview *mem = params;
+
+   if (mem->text)
+     eina_stringshare_del(mem->text);
+   free(mem);
+}
+
+static Edje_External_Param_Info external_anchorview_params[] = {
+   EDJE_EXTERNAL_PARAM_INFO_STRING_DEFAULT("text", "some text"),
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(anchorview, "anchorview")
+DEFINE_EXTERNAL_TYPE_SIMPLE(anchorview, "Anchorview");
diff --git a/src/edje_externals/elm_bubble.c b/src/edje_externals/elm_bubble.c
new file mode 100644 (file)
index 0000000..380e07c
--- /dev/null
@@ -0,0 +1,160 @@
+#include "private.h"
+
+typedef struct _Elm_Params_Bubble
+{
+   Elm_Params base;
+   Evas_Object *icon;
+   const char *info;
+   Evas_Object *content; /* part name whose obj is to be set as content */
+} Elm_Params_Bubble;
+
+static void
+external_bubble_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Bubble *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->base.label) elm_bubble_label_set(obj, p->base.label);
+   if (p->icon) elm_bubble_icon_set(obj, p->icon);
+   if (p->info) elm_bubble_info_set(obj, p->info);
+   if (p->content) elm_bubble_content_set(obj, p->content);
+}
+
+static Eina_Bool
+external_bubble_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_bubble_label_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "icon"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            Evas_Object *icon = external_common_param_icon_get(obj, param);
+            if (icon)
+              {
+                 elm_bubble_icon_set(obj, icon);
+                 return EINA_TRUE;
+              }
+         }
+     }
+   else if (!strcmp(param->name, "info"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_bubble_info_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "content"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            Evas_Object *content = \
+              external_common_param_edje_object_get(obj, param);
+            if (content)
+              {
+                 elm_bubble_content_set(obj, content);
+                 return EINA_TRUE;
+              }
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_bubble_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_bubble_label_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "icon"))
+     {
+       /* not easy to get icon name back from live object */
+       return EINA_FALSE;
+     }
+   else if (!strcmp(param->name, "info"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_bubble_info_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "content"))
+     {
+       /* not easy to get content name back from live object */
+       return EINA_FALSE;
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_bubble_params_parse(void *data, Evas_Object *obj, const Eina_List *params)
+{
+   Elm_Params_Bubble *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = external_common_params_parse(Elm_Params_Bubble, data, obj, params);
+   if (!mem)
+     return NULL;
+
+   external_common_icon_param_parse(&mem->icon, obj, params);
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "info"))
+         mem->info = eina_stringshare_add(param->s);
+       else if (!strcmp(param->name, "content"))
+         mem->content = external_common_param_edje_object_get(obj, param);
+     }
+
+   return mem;
+}
+
+ static void
+external_bubble_params_free(void *params)
+{
+   Elm_Params_Bubble *mem = params;
+
+   if (mem->icon)
+     evas_object_del(mem->icon);
+   if (mem->content)
+     evas_object_del(mem->content);
+   if (mem->info)
+     eina_stringshare_del(mem->info);
+   external_common_params_free(params);
+}
+
+static Edje_External_Param_Info external_bubble_params[] = {
+   DEFINE_EXTERNAL_COMMON_PARAMS,
+   EDJE_EXTERNAL_PARAM_INFO_STRING("icon"),
+   EDJE_EXTERNAL_PARAM_INFO_STRING("info"),
+   EDJE_EXTERNAL_PARAM_INFO_STRING("content"),
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(bubble, "bubble");
+DEFINE_EXTERNAL_TYPE_SIMPLE(bubble, "Bubble");
diff --git a/src/edje_externals/elm_button.c b/src/edje_externals/elm_button.c
new file mode 100644 (file)
index 0000000..f0daaf1
--- /dev/null
@@ -0,0 +1,108 @@
+#include "private.h"
+
+typedef struct _Elm_Params_Button
+{
+   Elm_Params base;
+   Evas_Object *icon;
+} Elm_Params_Button;
+
+static void
+external_button_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Button *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->base.label)
+     elm_button_label_set(obj, p->base.label);
+   if (p->icon)
+     elm_button_icon_set(obj, p->icon);
+}
+
+static Eina_Bool
+external_button_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_button_label_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "icon"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            Evas_Object *icon = external_common_param_icon_get(obj, param);
+            if (icon)
+              {
+                 elm_button_icon_set(obj, icon);
+                 return EINA_TRUE;
+              }
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_button_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_button_label_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "icon"))
+     {
+       /* not easy to get icon name back from live object */
+       return EINA_FALSE;
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_button_params_parse(void *data, Evas_Object *obj, const Eina_List *params)
+{
+   Elm_Params_Button *mem;
+
+   mem = external_common_params_parse(Elm_Params_Button, data, obj, params);
+   if (!mem)
+     return NULL;
+
+   external_common_icon_param_parse(&mem->icon, obj, params);
+
+   return mem;
+}
+
+ static void
+external_button_params_free(void *params)
+{
+   Elm_Params_Button *mem = params;
+
+   if (mem->icon)
+     evas_object_del(mem->icon);
+   external_common_params_free(params);
+}
+
+static Edje_External_Param_Info external_button_params[] = {
+   DEFINE_EXTERNAL_COMMON_PARAMS,
+   EDJE_EXTERNAL_PARAM_INFO_STRING("icon"),
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(button, "button");
+DEFINE_EXTERNAL_TYPE_SIMPLE(button, "Button");
diff --git a/src/edje_externals/elm_check.c b/src/edje_externals/elm_check.c
new file mode 100644 (file)
index 0000000..2fb331e
--- /dev/null
@@ -0,0 +1,137 @@
+#include "private.h"
+
+typedef struct _Elm_Params_Check
+{
+   Elm_Params base;
+   Evas_Object *icon;
+   Eina_Bool state:1;
+   Eina_Bool state_exists:1;
+} Elm_Params_Check;
+
+static void
+external_check_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Check *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->base.label)
+     elm_check_label_set(obj, p->base.label);
+   if (p->icon)
+     elm_check_icon_set(obj, p->icon);
+   if (p->state_exists)
+     elm_check_state_set(obj, p->state);
+}
+
+static Eina_Bool
+external_check_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_check_label_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "icon"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            Evas_Object *icon = external_common_param_icon_get(obj, param);
+            if (icon)
+              {
+                 elm_check_icon_set(obj, icon);
+                 return EINA_TRUE;
+              }
+         }
+     }
+   else if (!strcmp(param->name, "state"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_check_state_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_check_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_check_label_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "icon"))
+     {
+       /* not easy to get icon name back from live object */
+       return EINA_FALSE;
+     }
+   else if (!strcmp(param->name, "state"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_check_state_get(obj);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_check_params_parse(void *data, Evas_Object *obj, const Eina_List *params)
+{
+   Elm_Params_Check *mem;
+   Edje_External_Param *param;
+
+   mem = external_common_params_parse(Elm_Params_Check, data, obj, params);
+   if (!mem)
+     return NULL;
+
+   external_common_icon_param_parse(&mem->icon, obj, params);
+
+   param = edje_external_param_find(params, "state");
+   if (param)
+     {
+       mem->state = !!param->i;
+       mem->state_exists = EINA_TRUE;
+     }
+
+   return mem;
+}
+
+static void
+external_check_params_free(void *params)
+{
+   Elm_Params_Check *mem = params;
+
+   if (mem->icon)
+     evas_object_del(mem->icon);
+   external_common_params_free(params);
+}
+
+static Edje_External_Param_Info external_check_params[] = {
+   DEFINE_EXTERNAL_COMMON_PARAMS,
+   EDJE_EXTERNAL_PARAM_INFO_STRING("icon"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL_FULL("state", 0, "unchecked", "checked"),
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(check, "check")
+DEFINE_EXTERNAL_TYPE_SIMPLE(check, "Check")
diff --git a/src/edje_externals/elm_clock.c b/src/edje_externals/elm_clock.c
new file mode 100644 (file)
index 0000000..74f0818
--- /dev/null
@@ -0,0 +1,232 @@
+#include "private.h"
+
+typedef struct _Elm_Params_Clock
+{
+   int hrs, min, sec;
+   Eina_Bool hrs_exists:1;
+   Eina_Bool min_exists:1;
+   Eina_Bool sec_exists:1;
+   Eina_Bool edit:1;
+   Eina_Bool ampm:1;
+   Eina_Bool seconds:1;
+} Elm_Params_Clock;
+
+static void
+external_clock_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Clock *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if ((p->hrs_exists) && (p->min_exists) && (p->sec_exists))
+     elm_clock_time_set(obj, p->hrs, p->min, p->sec);
+   else if ((p->hrs_exists) || (p->min_exists) || (p->sec_exists))
+     {
+       int hrs, min, sec;
+       elm_clock_time_get(obj, &hrs, &min, &sec);
+       if (p->hrs_exists)
+         hrs = p->hrs;
+       if (p->min_exists)
+         min = p->min;
+       if (p->sec_exists)
+         sec = p->sec;
+       elm_clock_time_set(obj, hrs, min, sec);
+     }
+   if (p->edit)
+     elm_clock_edit_set(obj, p->edit);
+   if (p->ampm)
+     elm_clock_show_am_pm_set(obj, p->ampm);
+   if (p->seconds)
+     elm_clock_show_seconds_set(obj, p->seconds);
+}
+
+static Eina_Bool
+external_clock_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "hours"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT)
+         {
+            int hrs, min, sec;
+            elm_clock_time_get(obj, &hrs, &min, &sec);
+            elm_clock_time_set(obj, param->d, min, sec);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "minutes"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT)
+         {
+            int hrs, min, sec;
+            elm_clock_time_get(obj, &hrs, &min, &sec);
+            elm_clock_time_set(obj, hrs, param->d, sec);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "seconds"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT)
+         {
+            int hrs, min, sec;
+            elm_clock_time_get(obj, &hrs, &min, &sec);
+            elm_clock_time_set(obj, hrs, min, param->d);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "editable"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_clock_edit_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "am/pm"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_clock_show_am_pm_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "show seconds"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_clock_show_seconds_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_clock_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "hours"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT)
+         {
+            int hrs, min, sec;
+            elm_clock_time_get(obj, &hrs, &min, &sec);
+            param->i = hrs;
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "minutes"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT)
+         {
+            int hrs, min, sec;
+            elm_clock_time_get(obj, &hrs, &min, &sec);
+            param->i = min;
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "seconds"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT)
+         {
+            int hrs, min, sec;
+            elm_clock_time_get(obj, &hrs, &min, &sec);
+            param->i = sec;
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "editable"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_clock_edit_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "am/pm"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_clock_show_am_pm_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "show seconds"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_clock_show_seconds_get(obj);
+            return EINA_TRUE;
+         }
+     }
+
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_clock_params_parse(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params)
+{
+   Elm_Params_Clock *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = calloc(1, sizeof(Elm_Params_Clock));
+   if (!mem)
+     return NULL;
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "hours"))
+         {
+            mem->hrs = param->i;
+            mem->hrs_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "minutes"))
+         {
+            mem->min = param->i;
+            mem->min_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "seconds"))
+         {
+            mem->sec = param->i;
+            mem->sec_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "editable"))
+         mem->edit = !!param->i;
+       else if (!strcmp(param->name, "am/pm"))
+         mem->ampm = !!param->i;
+       else if (!strcmp(param->name, "show seconds"))
+         mem->seconds = !!param->i;
+     }
+
+   return mem;
+}
+
+static void
+external_clock_params_free(void *params)
+{
+   Elm_Params_Clock *mem = params;
+
+   free(mem);
+}
+
+static Edje_External_Param_Info external_clock_params[] = {
+   EDJE_EXTERNAL_PARAM_INFO_INT("hours"),
+   EDJE_EXTERNAL_PARAM_INFO_INT("minutes"),
+   EDJE_EXTERNAL_PARAM_INFO_INT("seconds"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("editable"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("am/pm"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("show seconds"),
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(clock, "clock")
+DEFINE_EXTERNAL_TYPE_SIMPLE(clock, "Clock")
diff --git a/src/edje_externals/elm_fileselector.c b/src/edje_externals/elm_fileselector.c
new file mode 100644 (file)
index 0000000..571cd13
--- /dev/null
@@ -0,0 +1,176 @@
+#include <assert.h>
+
+#include "private.h"
+
+typedef struct _Elm_Params_Fileselector
+{
+   Eina_Bool is_save:1;
+   Eina_Bool is_save_set:1;
+   Eina_Bool folder_only:1;
+   Eina_Bool folder_only_set:1;
+   Eina_Bool show_buttons:1;
+   Eina_Bool show_buttons_set:1;
+   Eina_Bool expandable:1;
+   Eina_Bool expandable_set:1;
+} Elm_Params_Fileselector;
+
+static void
+external_fileselector_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Fileselector *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->is_save_set && p->is_save)
+     elm_fileselector_is_save_set(obj, p->is_save);
+   if (p->folder_only_set)
+     elm_fileselector_folder_only_set(obj, p->folder_only);
+   if (p->show_buttons_set)
+     elm_fileselector_buttons_ok_cancel_set(obj, p->show_buttons);
+   if (p->expandable_set)
+     elm_fileselector_expandable_set(obj, p->expandable);
+}
+
+static Eina_Bool
+external_fileselector_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "save"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_fileselector_is_save_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "folder only"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_fileselector_folder_only_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "show buttons"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_fileselector_buttons_ok_cancel_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "expandable"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_fileselector_expandable_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_fileselector_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "save"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_fileselector_is_save_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "folder only"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_fileselector_folder_only_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "show buttons"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_fileselector_buttons_ok_cancel_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "expandable"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_fileselector_expandable_get(obj);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_fileselector_params_parse(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params)
+{
+   Elm_Params_Fileselector *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = calloc(1, sizeof(Elm_Params_Fileselector));
+   if (!mem)
+     return NULL;
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "save"))
+         {
+            mem->is_save = !!param->i;
+            mem->is_save_set = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "folder only"))
+         {
+            mem->folder_only = !!param->i;
+            mem->folder_only_set = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "show buttons"))
+         {
+            mem->show_buttons = !!param->i;
+            mem->show_buttons_set = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "expandable"))
+         {
+            mem->expandable = !!param->i;
+            mem->expandable_set = EINA_TRUE;
+         }
+     }
+
+   return mem;
+}
+
+static void
+external_fileselector_params_free(void *params)
+{
+   Elm_Params_Fileselector *mem = params;
+   free(mem);
+}
+
+static Edje_External_Param_Info external_fileselector_params[] =
+  {
+    EDJE_EXTERNAL_PARAM_INFO_BOOL("save"),
+    EDJE_EXTERNAL_PARAM_INFO_BOOL("folder only"),
+    EDJE_EXTERNAL_PARAM_INFO_BOOL("show buttons"),
+    EDJE_EXTERNAL_PARAM_INFO_BOOL("expandable"),
+    EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+  };
+
+DEFINE_EXTERNAL_ICON_ADD(fileselector, "fileselector")
+DEFINE_EXTERNAL_TYPE_SIMPLE(fileselector, "File Selector")
+
diff --git a/src/edje_externals/elm_fileselector_button.c b/src/edje_externals/elm_fileselector_button.c
new file mode 100644 (file)
index 0000000..bfa0650
--- /dev/null
@@ -0,0 +1,244 @@
+#include "private.h"
+
+typedef struct _Elm_Params_fileselector_button
+{
+   Elm_Params base;
+   Evas_Object *icon;
+
+   struct {
+      const char *path;
+      Eina_Bool is_save:1;
+      Eina_Bool is_save_set:1;
+      Eina_Bool folder_only:1;
+      Eina_Bool folder_only_set:1;
+      Eina_Bool expandable:1;
+      Eina_Bool expandable_set:1;
+      Eina_Bool inwin_mode:1;
+      Eina_Bool inwin_mode_set:1;
+   } fs;
+} Elm_Params_fileselector_button;
+
+static void
+external_fileselector_button_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_fileselector_button *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->base.label)
+     elm_fileselector_button_label_set(obj, p->base.label);
+   if (p->icon) elm_fileselector_button_icon_set(obj, p->icon);
+   if (p->fs.path) elm_fileselector_button_selected_set(obj, p->fs.path);
+   if (p->fs.is_save_set)
+     elm_fileselector_button_is_save_set(obj, p->fs.is_save);
+   if (p->fs.folder_only_set)
+     elm_fileselector_button_folder_only_set(obj, p->fs.folder_only);
+   if (p->fs.expandable_set)
+     elm_fileselector_button_expandable_set(obj, p->fs.expandable);
+   if (p->fs.inwin_mode_set)
+     elm_fileselector_button_inwin_mode_set(obj, p->fs.inwin_mode);
+}
+
+static Eina_Bool
+external_fileselector_button_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_fileselector_button_label_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "icon"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            Evas_Object *icon = external_common_param_icon_get(obj, param);
+            if (icon)
+              {
+                 elm_fileselector_button_icon_set(obj, icon);
+                 return EINA_TRUE;
+              }
+         }
+     }
+   else if (!strcmp(param->name, "path"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_fileselector_button_selected_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "save"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_fileselector_button_is_save_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "folder only"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_fileselector_button_folder_only_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "expandable"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_fileselector_button_expandable_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "inwin mode"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_fileselector_button_inwin_mode_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_fileselector_button_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_fileselector_button_label_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "icon"))
+     {
+       /* not easy to get icon name back from live object */
+       return EINA_FALSE;
+     }
+   else if (!strcmp(param->name, "path"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_fileselector_button_selected_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "save"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_fileselector_button_is_save_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "folder only"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_fileselector_button_folder_only_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "expandable"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_fileselector_button_expandable_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "inwin mode"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_fileselector_button_inwin_mode_get(obj);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_fileselector_button_params_parse(void *data, Evas_Object *obj, const Eina_List *params)
+{
+   Elm_Params_fileselector_button *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = external_common_params_parse(Elm_Params_fileselector_button,
+                                     data, obj, params);
+   if (!mem)
+     return NULL;
+
+   external_common_icon_param_parse(&mem->icon, obj, params);
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "path"))
+         mem->fs.path = eina_stringshare_add(param->s);
+       else if (!strcmp(param->name, "save"))
+         {
+            mem->fs.is_save = !!param->i;
+            mem->fs.is_save_set = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "folder only"))
+         {
+            mem->fs.folder_only = !!param->i;
+            mem->fs.folder_only_set = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "expandable"))
+         {
+            mem->fs.expandable = !!param->i;
+            mem->fs.expandable_set = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "inwin mode"))
+         {
+            mem->fs.inwin_mode = !!param->i;
+            mem->fs.inwin_mode_set = EINA_TRUE;
+         }
+     }
+
+   return mem;
+}
+
+ static void
+external_fileselector_button_params_free(void *params)
+{
+   Elm_Params_fileselector_button *mem = params;
+
+   if (mem->icon)
+     evas_object_del(mem->icon);
+   if (mem->fs.path)
+     eina_stringshare_del(mem->fs.path);
+   external_common_params_free(params);
+}
+
+static Edje_External_Param_Info external_fileselector_button_params[] = {
+   DEFINE_EXTERNAL_COMMON_PARAMS,
+   EDJE_EXTERNAL_PARAM_INFO_STRING("icon"),
+   EDJE_EXTERNAL_PARAM_INFO_STRING("path"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("save"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("folder only"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("expandable"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("inwin mode"),
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(fileselector_button, "fileselector_button");
+DEFINE_EXTERNAL_TYPE_SIMPLE(fileselector_button, "File Selector Button");
diff --git a/src/edje_externals/elm_genlist.c b/src/edje_externals/elm_genlist.c
new file mode 100644 (file)
index 0000000..bc3f634
--- /dev/null
@@ -0,0 +1,324 @@
+#include <assert.h>
+
+#include "private.h"
+
+typedef struct _Elm_Params_Genlist
+{
+   const char *horizontal_mode;
+   Eina_Bool multi:1;
+   Eina_Bool multi_exists:1;
+   Eina_Bool always_select:1;
+   Eina_Bool always_select_exists:1;
+   Eina_Bool no_select:1;
+   Eina_Bool no_select_exists:1;
+   Eina_Bool compress:1;
+   Eina_Bool compress_exists:1;
+   Eina_Bool homogeneous:1;
+   Eina_Bool homogeneous_exists:1;
+   Eina_Bool h_bounce:1;
+   Eina_Bool h_bounce_exists:1;
+   Eina_Bool v_bounce:1;
+   Eina_Bool v_bounce_exists:1;
+} Elm_Params_Genlist;
+
+static const char* list_horizontal_mode_choices[] = {"compress", "scroll", "limit", NULL};
+
+static Elm_List_Mode
+_list_horizontal_mode_setting_get(const char *horizontal_mode_str)
+{
+   unsigned int i;
+
+   assert(sizeof(list_horizontal_mode_choices)/sizeof(list_horizontal_mode_choices[0]) == ELM_LIST_LAST + 1);
+
+   for (i = 0; i < sizeof(list_horizontal_mode_choices); i++)
+     {
+       if (!strcmp(horizontal_mode_str, list_horizontal_mode_choices[i]))
+         return i;
+     }
+   return ELM_LIST_LAST;
+}
+
+static void
+external_genlist_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Genlist *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->horizontal_mode)
+     {
+       Elm_List_Mode set = _list_horizontal_mode_setting_get(p->horizontal_mode);
+
+       if (set != ELM_LIST_LAST)
+          elm_genlist_horizontal_mode_set(obj, set);
+     }
+   if (p->multi_exists)
+     elm_genlist_multi_select_set(obj, p->multi);
+   if (p->always_select_exists)
+     elm_genlist_always_select_mode_set(obj, p->always_select);
+   if (p->no_select_exists)
+     elm_genlist_no_select_mode_set(obj, p->no_select);
+   if (p->compress_exists)
+     elm_genlist_compress_mode_set(obj, p->compress);
+   if (p->homogeneous_exists)
+     elm_genlist_homogeneous_set(obj, p->homogeneous);
+   if ((p->h_bounce_exists) && (p->v_bounce_exists))
+     elm_genlist_bounce_set(obj, p->h_bounce, p->v_bounce);
+   else if ((p->h_bounce_exists) || (p->v_bounce_exists))
+     {
+       Eina_Bool h_bounce, v_bounce;
+
+       elm_genlist_bounce_get(obj, &h_bounce, &v_bounce);
+       if (p->h_bounce_exists)
+         elm_genlist_bounce_set(obj, p->h_bounce, v_bounce);
+       else
+         elm_genlist_bounce_set(obj, h_bounce, p->v_bounce);
+     }
+}
+
+static Eina_Bool
+external_genlist_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "horizontal mode"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE)
+         {
+            Elm_List_Mode set = _list_horizontal_mode_setting_get(param->s);
+
+            if (set == ELM_LIST_LAST) return EINA_FALSE;
+            elm_genlist_horizontal_mode_set(obj, set);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "multi select"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_genlist_multi_select_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "always select"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_genlist_always_select_mode_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "no select"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_genlist_no_select_mode_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "compress"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_genlist_compress_mode_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "homogeneous"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_genlist_homogeneous_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "height bounce"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            Eina_Bool h_bounce, v_bounce;
+            elm_genlist_bounce_get(obj, &h_bounce, &v_bounce);
+            elm_genlist_bounce_set(obj, param->i, v_bounce);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "width bounce"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            Eina_Bool h_bounce, v_bounce;
+            elm_genlist_bounce_get(obj, &h_bounce, &v_bounce);
+            elm_genlist_bounce_set(obj, h_bounce, param->i);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_genlist_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "horizontal mode"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE)
+         {
+            Elm_List_Mode list_horizontal_mode_set = elm_genlist_horizontal_mode_get(obj);
+
+            if (list_horizontal_mode_set == ELM_LIST_LAST)
+              return EINA_FALSE;
+
+            param->s = list_horizontal_mode_choices[list_horizontal_mode_set];
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "multi select"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_genlist_multi_select_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "always select"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_genlist_always_select_mode_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "no select"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_genlist_no_select_mode_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "compress"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_genlist_compress_mode_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "homogeneous"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_genlist_homogeneous_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "height bounce"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            Eina_Bool h_bounce, v_bounce;
+            elm_genlist_bounce_get(obj, &h_bounce, &v_bounce);
+            param->i = h_bounce;
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "width bounce"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            Eina_Bool h_bounce, v_bounce;
+            elm_genlist_bounce_get(obj, &h_bounce, &v_bounce);
+            param->i = v_bounce;
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_genlist_params_parse(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params)
+{
+   Elm_Params_Genlist *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = calloc(1, sizeof(Elm_Params_Genlist));
+   if (!mem)
+     return NULL;
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "horizontal mode"))
+            mem->horizontal_mode = eina_stringshare_add(param->s);
+       else if (!strcmp(param->name, "multi select"))
+         {
+            mem->multi = !!param->i;
+            mem->multi_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "always select"))
+         {
+            mem->always_select = !!param->i;
+            mem->always_select_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "no select"))
+         {
+            mem->no_select = !!param->i;
+            mem->no_select_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "compress"))
+         {
+            mem->compress = !!param->i;
+            mem->compress_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "homogeneous"))
+         {
+            mem->homogeneous = !!param->i;
+            mem->homogeneous_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "height bounce"))
+         {
+            mem->h_bounce = !!param->i;
+            mem->h_bounce_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "width bounce"))
+         {
+            mem->v_bounce = !!param->i;
+            mem->v_bounce_exists = EINA_TRUE;
+         }
+     }
+
+   return mem;
+}
+
+static void
+external_genlist_params_free(void *params)
+{
+   Elm_Params_Genlist *mem = params;
+
+   if (mem->horizontal_mode)
+     eina_stringshare_del(mem->horizontal_mode);
+
+   free(mem);
+}
+
+static Edje_External_Param_Info external_genlist_params[] = {
+   EDJE_EXTERNAL_PARAM_INFO_CHOICE_FULL("horizontal mode", "scroll", list_horizontal_mode_choices),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("multi select"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("always select"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("no select"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("compress"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("homogeneous"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("height bounce"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("width bounce"),
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(genlist, "genlist");
+DEFINE_EXTERNAL_TYPE_SIMPLE(genlist, "Generic List");
diff --git a/src/edje_externals/elm_hoversel.c b/src/edje_externals/elm_hoversel.c
new file mode 100644 (file)
index 0000000..902a956
--- /dev/null
@@ -0,0 +1,140 @@
+#include "private.h"
+
+typedef struct _Elm_Params_Hoversel
+{
+   Elm_Params base;
+   Evas_Object *icon;
+   Eina_Bool horizontal:1;
+   Eina_Bool horizontal_exists:1;
+} Elm_Params_Hoversel;
+
+static void
+external_hoversel_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Hoversel *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->base.label)
+     elm_hoversel_label_set(obj, p->base.label);
+   if (p->icon)
+     elm_hoversel_icon_set(obj, p->icon);
+   if (p->horizontal_exists)
+      elm_hoversel_horizontal_set(obj, p->horizontal);
+}
+
+static Eina_Bool
+external_hoversel_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_hoversel_label_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "icon"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            Evas_Object *icon = external_common_param_icon_get(obj, param);
+            if (icon)
+              {
+                 elm_hoversel_icon_set(obj, icon);
+                 return EINA_TRUE;
+              }
+         }
+     }
+   else if (!strcmp(param->name, "horizontal"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_hoversel_horizontal_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_hoversel_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_hoversel_label_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "icon"))
+     {
+       /* not easy to get icon name back from live object */
+       return EINA_FALSE;
+     }
+   else if (!strcmp(param->name, "horizontal"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_hoversel_horizontal_get(obj);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_hoversel_params_parse(void *data, Evas_Object *obj, const Eina_List *params)
+{
+   Elm_Params_Hoversel *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = external_common_params_parse(Elm_Params_Hoversel, data, obj, params);
+   if (!mem)
+     return NULL;
+
+   external_common_icon_param_parse(&mem->icon, obj, params);
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "horizontal"))
+         {
+            mem->horizontal = !!param->i;
+            mem->horizontal_exists = EINA_TRUE;
+         }
+     }
+
+   return mem;
+}
+
+ static void
+external_hoversel_params_free(void *params)
+{
+   Elm_Params_Hoversel *mem = params;
+
+   if (mem->icon)
+     evas_object_del(mem->icon);
+   external_common_params_free(params);
+}
+
+static Edje_External_Param_Info external_hoversel_params[] = {
+   DEFINE_EXTERNAL_COMMON_PARAMS,
+   EDJE_EXTERNAL_PARAM_INFO_STRING("icon"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("horizontal"),
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(hoversel, "hoversel");
+DEFINE_EXTERNAL_TYPE_SIMPLE(hoversel, "Hoversel");
diff --git a/src/edje_externals/elm_list.c b/src/edje_externals/elm_list.c
new file mode 100644 (file)
index 0000000..2f6d193
--- /dev/null
@@ -0,0 +1,273 @@
+#include <assert.h>
+
+#include "private.h"
+
+typedef struct _Elm_Params_List
+{
+   const char *policy_h;
+   const char *policy_v;
+   const char *horizontal_mode;
+   Eina_Bool multi : 1;
+   Eina_Bool multi_exists : 1;
+   Eina_Bool always_select : 1;
+   Eina_Bool always_select_exists : 1;
+} Elm_Params_List;
+
+#define CHOICE_GET(CHOICES, STR)               \
+  unsigned int i;                              \
+  for (i = 0; i < sizeof(CHOICES); i++)                \
+    if (strcmp(STR, CHOICES[i]) == 0)          \
+      return i
+
+static const char *scroller_policy_choices[] = {"auto", "on", "off", NULL};
+static const char *list_horizontal_mode_choices[] = {"compress", "scroll",
+                                                    "limit", NULL};
+
+static Elm_Scroller_Policy
+_scroller_policy_choices_setting_get(const char *policy_str)
+{
+   assert(sizeof(scroller_policy_choices)/
+         sizeof(scroller_policy_choices[0]) == ELM_SCROLLER_POLICY_LAST + 1);
+   CHOICE_GET(scroller_policy_choices, policy_str);
+   return ELM_SCROLLER_POLICY_LAST;
+}
+
+static Elm_List_Mode
+_list_horizontal_mode_setting_get(const char *horizontal_mode_str)
+{
+   assert(sizeof(list_horizontal_mode_choices)/
+         sizeof(list_horizontal_mode_choices[0]) == ELM_LIST_LAST + 1);
+   CHOICE_GET(list_horizontal_mode_choices, horizontal_mode_str);
+   return ELM_LIST_LAST;
+}
+
+
+static void
+external_list_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_List *p;
+   Elm_Scroller_Policy policy_h, policy_v;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->horizontal_mode)
+     {
+       Elm_List_Mode set = _list_horizontal_mode_setting_get(
+                                            p->horizontal_mode);
+
+       if (set != ELM_LIST_LAST)
+          elm_list_horizontal_mode_set(obj, set);
+     }
+
+   if ((p->policy_h) && (p->policy_v))
+     {
+       policy_h = _scroller_policy_choices_setting_get(p->policy_h);
+       policy_v = _scroller_policy_choices_setting_get(p->policy_v);
+       elm_list_scroller_policy_set(obj, policy_h, policy_v);
+     }
+   else if ((p->policy_h) || (p->policy_v))
+     {
+       elm_list_scroller_policy_get(obj, &policy_h, &policy_v);
+       if (p->policy_h)
+         {
+            policy_h = _scroller_policy_choices_setting_get(p->policy_h);
+            elm_list_scroller_policy_set(obj, policy_h, policy_v);
+         }
+       else
+         {
+            policy_v = _scroller_policy_choices_setting_get(p->policy_v);
+            elm_list_scroller_policy_set(obj, policy_h, policy_v);
+         }
+     }
+
+   if (p->multi_exists)
+     elm_list_multi_select_set(obj, p->multi);
+   if (p->always_select_exists)
+     elm_list_always_select_mode_set(obj, p->always_select);
+}
+
+static Eina_Bool
+external_list_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "horizontal mode"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE)
+         {
+            Elm_List_Mode set = _list_horizontal_mode_setting_get(param->s);
+            if (set == ELM_LIST_LAST) return EINA_FALSE;
+            elm_list_horizontal_mode_set(obj, set);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "scroll horizontal"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE)
+         {
+            Elm_Scroller_Policy h, v;
+            elm_list_scroller_policy_get(obj, &h, &v);
+            h = _scroller_policy_choices_setting_get(param->s);
+            if (h == ELM_SCROLLER_POLICY_LAST) return EINA_FALSE;
+            elm_list_scroller_policy_set(obj, h, v);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "scroll vertical"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE)
+         {
+            Elm_Scroller_Policy h, v;
+            elm_list_scroller_policy_get(obj, &h, &v);
+            v = _scroller_policy_choices_setting_get(param->s);
+            if (v == ELM_SCROLLER_POLICY_LAST) return EINA_FALSE;
+            elm_list_scroller_policy_set(obj, h, v);
+            return EINA_TRUE;
+         }
+     }
+   else  if (!strcmp(param->name, "multi"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_list_multi_select_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "always_select"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_list_always_select_mode_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_list_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "multi"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_list_multi_select_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "always_select"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_list_always_select_mode_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "scroll horizontal"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE)
+         {
+            Elm_Scroller_Policy h, v;
+            elm_list_scroller_policy_get(obj, &h, &v);
+
+            param->s = scroller_policy_choices[h];
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "scroll vertical"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE)
+         {
+            Elm_Scroller_Policy h, v;
+            elm_list_scroller_policy_get(obj, &h, &v);
+
+            param->s = scroller_policy_choices[v];
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "horizontal mode"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE)
+         {
+            Elm_List_Mode m = elm_list_horizontal_mode_get(obj);
+
+            if (m == ELM_LIST_LAST)
+              return EINA_FALSE;
+
+            param->s = list_horizontal_mode_choices[m];
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_list_params_parse(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params)
+{
+   Elm_Params_List *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = calloc(1, sizeof(Elm_Params_List));
+   if (!mem)
+     return NULL;
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "multi"))
+         {
+            mem->multi = param->i;
+            mem->multi_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "always_select"))
+         {
+            mem->always_select = param->i;
+            mem->always_select_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "scroll horizontal"))
+         mem->policy_h = eina_stringshare_add(param->s);
+       else if (!strcmp(param->name, "scroll vertical"))
+         mem->policy_v = eina_stringshare_add(param->s);
+       else if (!strcmp(param->name, "horizontal mode"))
+         mem->horizontal_mode = eina_stringshare_add(param->s);
+     }
+   return mem;
+}
+
+static void
+external_list_params_free(void *params)
+{
+   Elm_Params_List *mem = params;
+
+   if (mem->horizontal_mode)
+     eina_stringshare_del(mem->horizontal_mode);
+   if (mem->policy_h)
+     eina_stringshare_del(mem->policy_h);
+   if (mem->policy_v)
+     eina_stringshare_del(mem->policy_v);
+
+   free(mem);
+}
+
+static Edje_External_Param_Info external_list_params[] = {
+  EDJE_EXTERNAL_PARAM_INFO_CHOICE_FULL("horizontal mode", "scroll",
+                                      list_horizontal_mode_choices),
+  EDJE_EXTERNAL_PARAM_INFO_CHOICE_FULL("scroll horizontal", "auto",
+                                      scroller_policy_choices),
+  EDJE_EXTERNAL_PARAM_INFO_CHOICE_FULL("scroll vertical", "auto",
+                                      scroller_policy_choices),
+  EDJE_EXTERNAL_PARAM_INFO_BOOL("multi"),
+  EDJE_EXTERNAL_PARAM_INFO_BOOL("always_select"),
+  EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(list, "list")
+DEFINE_EXTERNAL_TYPE_SIMPLE(list, "List");
diff --git a/src/edje_externals/elm_map.c b/src/edje_externals/elm_map.c
new file mode 100644 (file)
index 0000000..13c0592
--- /dev/null
@@ -0,0 +1,198 @@
+#include <assert.h>
+
+#include "private.h"
+
+typedef struct _Elm_Params_Map
+{
+   const char *map_source;
+   const char *zoom_mode;
+   double zoom;
+   Eina_Bool zoom_set:1;
+} Elm_Params_Map;
+
+static const char *zoom_choices[] = {"manual", "auto fit", "auto fill", NULL};
+
+static const char *source_choices[] =
+  {"Mapnik", "Osmarender", "Cycle Map", "Maplint",
+   "Custom 1", "Custom 2", "Custom 3", "Custom 4",
+   "Custom 5", "Custom 6", "Custom 7"};
+
+static Elm_Map_Zoom_Mode
+_zoom_mode_get(const char *map_src)
+{
+   unsigned int i;
+
+   assert(sizeof(zoom_choices)/sizeof(zoom_choices[0]) ==
+         ELM_MAP_ZOOM_MODE_LAST + 1);
+
+   for (i = 0; i < sizeof(zoom_choices); i++)
+     if (strcmp(map_src, zoom_choices[i]) == 0) return i;
+
+   return ELM_MAP_ZOOM_MODE_LAST;
+}
+
+static Elm_Map_Sources
+_map_source_get(const char *map_src)
+{
+   unsigned int i;
+
+   assert(sizeof(source_choices)/sizeof(source_choices[0]) ==
+         ELM_MAP_SOURCE_LAST);
+
+   for (i = 0; i < sizeof(source_choices); i++)
+     if (strcmp(map_src, source_choices[i]) == 0) return i;
+
+   return ELM_MAP_SOURCE_LAST;
+}
+
+static void
+external_map_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Map *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->map_source)
+     {
+       Elm_Map_Sources set = _map_source_get(p->map_source);
+       if (set == ELM_MAP_SOURCE_LAST) return;
+       elm_map_source_set(obj, set);
+     }
+   if (p->zoom_mode)
+     {
+       Elm_Map_Zoom_Mode set = _zoom_mode_get(p->zoom_mode);
+       if (set == ELM_MAP_ZOOM_MODE_LAST) return;
+       elm_map_zoom_mode_set(obj, set);
+     }
+   if (p->zoom_set) elm_map_zoom_set(obj, p->zoom);
+}
+
+static Eina_Bool
+external_map_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "map source"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE)
+         {
+            Elm_Map_Sources set = _map_source_get(param->s);
+            if (set == ELM_MAP_SOURCE_LAST) return EINA_FALSE;
+            elm_map_source_set(obj, set);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "zoom mode"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE)
+         {
+            Elm_Map_Zoom_Mode set = _zoom_mode_get(param->s);
+            if (set == ELM_MAP_ZOOM_MODE_LAST) return EINA_FALSE;
+            elm_map_zoom_mode_set(obj, set);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "zoom level"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            elm_map_zoom_set(obj, param->d);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_map_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "map source"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE)
+         {
+            Elm_Map_Sources set = elm_map_source_get(obj);
+            if (set == ELM_MAP_SOURCE_LAST) return EINA_FALSE;
+            param->s = source_choices[set];
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "zoom mode"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE)
+         {
+            Elm_Map_Zoom_Mode set = elm_map_zoom_mode_get(obj);
+            if (set == ELM_MAP_ZOOM_MODE_LAST) return EINA_FALSE;
+            param->s = zoom_choices[set];
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "zoom level"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            param->d = elm_map_zoom_get(obj);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_map_params_parse(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params)
+{
+   Elm_Params_Map *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = calloc(1, sizeof(Elm_Params_Map));
+   if (!mem)
+     return NULL;
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "map source"))
+         mem->map_source = eina_stringshare_add(param->s);
+       if (!strcmp(param->name, "zoom mode"))
+         mem->zoom_mode = eina_stringshare_add(param->s);
+       else if (!strcmp(param->name, "zoom level"))
+         {
+            mem->zoom = param->d;
+            mem->zoom_set = EINA_TRUE;
+         }
+     }
+
+   return mem;
+}
+
+static void
+external_map_params_free(void *params)
+{
+   Elm_Params_Map *mem = params;
+
+   if (mem->map_source)
+     eina_stringshare_del(mem->map_source);
+   if (mem->zoom_mode)
+     eina_stringshare_del(mem->zoom_mode);
+   free(mem);
+}
+
+static Edje_External_Param_Info external_map_params[] =
+  {
+    EDJE_EXTERNAL_PARAM_INFO_CHOICE_FULL("map source", "Mapnik",
+                                        source_choices),
+    EDJE_EXTERNAL_PARAM_INFO_CHOICE_FULL("zoom mode", "manual", zoom_choices),
+    EDJE_EXTERNAL_PARAM_INFO_DOUBLE("zoom level"),
+    EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+  };
+
+DEFINE_EXTERNAL_ICON_ADD(map, "map")
+DEFINE_EXTERNAL_TYPE_SIMPLE(map, "Map")
+
diff --git a/src/edje_externals/elm_notepad.c b/src/edje_externals/elm_notepad.c
new file mode 100644 (file)
index 0000000..697b0ae
--- /dev/null
@@ -0,0 +1,59 @@
+#include "private.h"
+
+typedef struct _Elm_Params_Notepad
+{
+} Elm_Params_Notepad;
+
+static void
+external_notepad_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Notepad *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   /* TODO: to be expanded */
+}
+
+static Eina_Bool
+external_notepad_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   /* TODO: to be expanded */
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_notepad_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   /* TODO: to be expanded */
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_notepad_params_parse(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params)
+{
+   /* TODO: to be expanded */
+
+   return NULL;
+}
+
+static void
+external_notepad_params_free(void *params)
+{
+}
+
+static Edje_External_Param_Info external_notepad_params[] = {
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(notepad, "notepad")
+DEFINE_EXTERNAL_TYPE_SIMPLE(notepad, "Notepad");
diff --git a/src/edje_externals/elm_photocam.c b/src/edje_externals/elm_photocam.c
new file mode 100644 (file)
index 0000000..4cb821d
--- /dev/null
@@ -0,0 +1,199 @@
+#include <assert.h>
+
+#include "private.h"
+
+typedef struct _Elm_Params_Photocam
+{
+   const char *file;
+   double zoom;
+   const char *zoom_mode;
+   Eina_Bool paused:1;
+   Eina_Bool paused_exists:1;
+   Eina_Bool zoom_exists:1;
+} Elm_Params_Photocam;
+
+static const char* choices[] = {"manual", "auto fit", "auto fill", NULL};
+
+static Elm_Photocam_Zoom_Mode
+_zoom_mode_setting_get(const char *zoom_mode_str)
+{
+   unsigned int i;
+
+   assert(sizeof(choices)/sizeof(choices[0]) == ELM_PHOTOCAM_ZOOM_MODE_LAST + 1);
+
+   for (i = 0; i < sizeof(choices); i++)
+     {
+       if (!strcmp(zoom_mode_str, choices[i]))
+         return i;
+     }
+   return ELM_PHOTOCAM_ZOOM_MODE_LAST;
+}
+
+static void
+external_photocam_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Photocam *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->file)
+     elm_photocam_file_set(obj, p->file);
+   if (p->zoom_exists)
+     elm_photocam_zoom_set(obj, p->zoom);
+   if (p->zoom_mode)
+     {
+       Elm_Photocam_Zoom_Mode set = _zoom_mode_setting_get(p->zoom_mode);
+       if (set == ELM_PHOTOCAM_ZOOM_MODE_LAST) return;
+       elm_photocam_zoom_mode_set(obj, set);
+     }
+   if (p->paused_exists)
+     elm_photocam_paused_set(obj, p->paused);
+}
+
+static Eina_Bool
+external_photocam_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "file"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_photocam_file_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "zoom"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            elm_photocam_zoom_set(obj, param->d);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "zoom mode"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            Elm_Photocam_Zoom_Mode set = _zoom_mode_setting_get(param->s);
+            if (set == ELM_PHOTOCAM_ZOOM_MODE_LAST) return EINA_FALSE;
+            elm_photocam_zoom_mode_set(obj, set);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "paused"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_photocam_paused_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_photocam_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "file"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_photocam_file_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "zoom"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            param->d = elm_photocam_zoom_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "zoom mode"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            Elm_Photocam_Zoom_Mode zoom_mode_set = elm_photocam_zoom_mode_get(obj);
+
+            if (zoom_mode_set == ELM_PHOTOCAM_ZOOM_MODE_LAST)
+              return EINA_FALSE;
+
+            param->s = choices[zoom_mode_set];
+            return EINA_TRUE;
+         }
+     }
+   else if(!strcmp(param->name, "paused"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_photocam_paused_get(obj);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_photocam_params_parse(void *data, Evas_Object *obj, const Eina_List *params)
+{
+   Elm_Params_Photocam *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = calloc(1, sizeof(Elm_Params_Photocam));
+   if (!mem)
+     return NULL;
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "file"))
+         mem->file = eina_stringshare_add(param->s);
+       else if (!strcmp(param->name, "zoom"))
+         {
+            mem->zoom = param->d;
+            mem->zoom_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "zoom mode"))
+         mem->zoom_mode = eina_stringshare_add(param->s);
+       else if (!strcmp(param->name, "paused"))
+         {
+            mem->paused = !!param->i;
+            mem->paused_exists = EINA_TRUE;
+         }
+     }
+
+   return mem;
+}
+
+static void
+external_photocam_params_free(void *params)
+{
+   Elm_Params_Photocam *mem = params;
+
+   if (mem->file)
+     eina_stringshare_del(mem->file);
+   if (mem->zoom_mode)
+     eina_stringshare_del(mem->zoom_mode);
+   free(mem);
+}
+
+static Edje_External_Param_Info external_photocam_params[] = {
+   EDJE_EXTERNAL_PARAM_INFO_STRING("file"),
+   EDJE_EXTERNAL_PARAM_INFO_DOUBLE("zoom"),
+   EDJE_EXTERNAL_PARAM_INFO_CHOICE_FULL("zoom mode", "manual", choices),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("paused"),
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(photocam, "photocam");
+DEFINE_EXTERNAL_TYPE_SIMPLE(photocam, "Photocam");
diff --git a/src/edje_externals/elm_progressbar.c b/src/edje_externals/elm_progressbar.c
new file mode 100644 (file)
index 0000000..9cb0150
--- /dev/null
@@ -0,0 +1,242 @@
+#include "private.h"
+
+typedef struct _Elm_Params_Progressbar
+{
+   Elm_Params base;
+   Evas_Object *icon;
+   const char *unit;
+   double value;
+   Evas_Coord span;
+   Eina_Bool value_exists:1;
+   Eina_Bool span_exists:1;
+   Eina_Bool inverted:1;
+   Eina_Bool inverted_exists:1;
+   Eina_Bool horizontal:1;
+   Eina_Bool horizontal_exists:1;
+} Elm_Params_Progressbar;
+
+static void
+external_progressbar_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Progressbar *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->base.label)
+     elm_progressbar_label_set(obj, p->base.label);
+   if (p->icon)
+     elm_progressbar_icon_set(obj, p->icon);
+   if (p->span_exists)
+     elm_progressbar_span_size_set(obj, p->span);
+   if (p->value_exists)
+     elm_progressbar_value_set(obj, p->value);
+   if (p->inverted_exists)
+     elm_progressbar_inverted_set(obj, p->inverted);
+   if (p->horizontal_exists)
+     elm_progressbar_horizontal_set(obj, p->horizontal);
+   if (p->unit)
+     elm_progressbar_unit_format_set(obj, p->unit);
+}
+
+static Eina_Bool
+external_progressbar_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_progressbar_label_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "icon"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            Evas_Object *icon = external_common_param_icon_get(obj, param);
+            if (icon)
+              {
+                 elm_progressbar_icon_set(obj, icon);
+                 return EINA_TRUE;
+              }
+         }
+     }
+   else if (!strcmp(param->name, "value"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            elm_progressbar_value_set(obj, param->d);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "horizontal"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_progressbar_horizontal_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "inverted"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_progressbar_inverted_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "span"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT)
+         {
+            elm_progressbar_span_size_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "unit format"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_progressbar_unit_format_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_progressbar_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_progressbar_label_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "icon"))
+     {
+       /* not easy to get icon name back from live object */
+       return EINA_FALSE;
+     }
+   else if (!strcmp(param->name, "value"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            param->d = elm_progressbar_value_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "horizontal"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_progressbar_horizontal_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "inverted"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_progressbar_inverted_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "span"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT)
+         {
+            param->i = elm_progressbar_span_size_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "unit format"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_progressbar_unit_format_get(obj);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_progressbar_params_parse(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params)
+{
+   Elm_Params_Progressbar *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = external_common_params_parse(Elm_Params_Progressbar, data, obj, params);
+   if (!mem)
+     return NULL;
+
+   external_common_icon_param_parse(&mem->icon, obj, params);
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "span"))
+         {
+            mem->span = param->i;
+            mem->span_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "value"))
+         {
+            mem->value = param->d;
+            mem->value_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "inverted"))
+         {
+            mem->inverted = !!param->i;
+            mem->inverted_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "horizontal"))
+         {
+             mem->horizontal = !!param->i;
+             mem->horizontal_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "unit format"))
+         mem->unit = eina_stringshare_add(param->s);
+     }
+
+   return mem;
+}
+
+static void
+external_progressbar_params_free(void *params)
+{
+   Elm_Params_Progressbar *mem = params;
+
+   if (mem->icon)
+     evas_object_del(mem->icon);
+   if (mem->unit)
+     eina_stringshare_del(mem->unit);
+   external_common_params_free(params);
+}
+
+static Edje_External_Param_Info external_progressbar_params[] = {
+   DEFINE_EXTERNAL_COMMON_PARAMS,
+   EDJE_EXTERNAL_PARAM_INFO_STRING("icon"),
+   EDJE_EXTERNAL_PARAM_INFO_DOUBLE("value"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("horizontal"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("inverted"),
+   EDJE_EXTERNAL_PARAM_INFO_INT("span"),
+   EDJE_EXTERNAL_PARAM_INFO_STRING_DEFAULT("unit format", "%1.2f"),
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(progressbar, "progressbar")
+DEFINE_EXTERNAL_TYPE_SIMPLE(progressbar, "Progressbar")
diff --git a/src/edje_externals/elm_radio.c b/src/edje_externals/elm_radio.c
new file mode 100644 (file)
index 0000000..35206a8
--- /dev/null
@@ -0,0 +1,167 @@
+#include "private.h"
+
+typedef struct _Elm_Params_Radio
+{
+   Elm_Params base;
+   Evas_Object *icon;
+   const char* group_name;
+   int value;
+   Eina_Bool value_exists:1;
+} Elm_Params_Radio;
+
+static void
+external_radio_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Radio *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->base.label)
+     elm_radio_label_set(obj, p->base.label);
+   if (p->icon)
+     elm_radio_icon_set(obj, p->icon);
+   if (p->value_exists)
+     elm_radio_state_value_set(obj, p->value);
+   if (p->group_name)
+     {
+       Evas_Object *ed = evas_object_smart_parent_get(obj);
+       Evas_Object *group = edje_object_part_swallow_get(ed, p->group_name);
+       elm_radio_group_add(obj, group);
+     }
+}
+
+static Eina_Bool
+external_radio_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_radio_label_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "icon"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            Evas_Object *icon = external_common_param_icon_get(obj, param);
+            if (icon)
+              {
+                 elm_radio_icon_set(obj, icon);
+                 return EINA_TRUE;
+              }
+         }
+     }
+   else if (!strcmp(param->name, "value"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT)
+         {
+            elm_radio_value_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "group"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            Evas_Object *ed = evas_object_smart_parent_get(obj);
+            Evas_Object *group = edje_object_part_swallow_get(ed, param->s);
+            elm_radio_group_add(obj, group);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_radio_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_radio_label_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "icon"))
+     {
+       /* not easy to get icon name back from live object */
+       return EINA_FALSE;
+     }
+   else if (!strcmp(param->name, "value"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT)
+         {
+            param->i = elm_radio_value_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "group"))
+     {
+       /* not easy to get group name back from live object */
+       return EINA_FALSE;
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_radio_params_parse(void *data, Evas_Object *obj, const Eina_List *params)
+{
+   Elm_Params_Radio *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = external_common_params_parse(Elm_Params_Radio, data, obj, params);
+   if (!mem)
+     return NULL;
+
+   external_common_icon_param_parse(&mem->icon, obj, params);
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "group"))
+         mem->group_name = eina_stringshare_add(param->s);
+       else if (!strcmp(param->name, "value"))
+         {
+            mem->value = param->i;
+            mem->value_exists = EINA_TRUE;
+         }
+     }
+
+   return mem;
+}
+
+static void
+external_radio_params_free(void *params)
+{
+   Elm_Params_Radio *mem = params;
+
+   if (mem->icon)
+     evas_object_del(mem->icon);
+   if (mem->group_name)
+     eina_stringshare_del(mem->group_name);
+   external_common_params_free(params);
+}
+
+static Edje_External_Param_Info external_radio_params[] = {
+   DEFINE_EXTERNAL_COMMON_PARAMS,
+   EDJE_EXTERNAL_PARAM_INFO_STRING("icon"),
+   EDJE_EXTERNAL_PARAM_INFO_STRING("group"),
+   EDJE_EXTERNAL_PARAM_INFO_INT("value"),
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(radio, "radio")
+DEFINE_EXTERNAL_TYPE_SIMPLE(radio, "Radio")
diff --git a/src/edje_externals/elm_scrolled_entry.c b/src/edje_externals/elm_scrolled_entry.c
new file mode 100644 (file)
index 0000000..446106a
--- /dev/null
@@ -0,0 +1,175 @@
+#include "private.h"
+
+typedef struct _Elm_Params_Entry
+{
+   const char *text;
+   Eina_Bool text_set:1;
+   Eina_Bool editable:1;
+   Eina_Bool single:1;
+   Eina_Bool password:1;
+   Eina_Bool editable_exists:1;
+   Eina_Bool single_exists:1;
+   Eina_Bool password_exists:1;
+} Elm_Params_Entry;
+
+static void
+external_scrolled_entry_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Entry *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if ((!p->text_set) && (p->text))
+     {
+       elm_scrolled_entry_entry_set(obj, p->text);
+       ((Elm_Params_Entry *)p)->text_set = EINA_TRUE;
+     }
+   if (p->editable_exists)
+     elm_scrolled_entry_editable_set(obj, p->editable);
+   if (p->single_exists)
+     elm_scrolled_entry_single_line_set(obj, p->single);
+   if (p->password_exists)
+     elm_scrolled_entry_password_set(obj, p->password);
+}
+
+static Eina_Bool
+external_scrolled_entry_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "text"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_scrolled_entry_entry_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "editable"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_scrolled_entry_editable_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "single line"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_scrolled_entry_single_line_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "password"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_scrolled_entry_password_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_scrolled_entry_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "text"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_scrolled_entry_entry_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "editable"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_scrolled_entry_editable_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "single line"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_scrolled_entry_single_line_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "password"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_scrolled_entry_password_get(obj);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_scrolled_entry_params_parse(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params)
+{
+   Elm_Params_Entry *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = calloc(1, sizeof(Elm_Params_Entry));
+   if (!mem)
+     return NULL;
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "text"))
+         mem->text = eina_stringshare_add(param->s);
+       else if (!strcmp(param->name, "single line"))
+         {
+            mem->single = !!param->i;
+            mem->single_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "password"))
+         {
+            mem->password = !!param->i;
+            mem->password_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "editable"))
+         {
+            mem->editable = param->i;
+            mem->editable_exists = EINA_TRUE;
+         }
+     }
+
+   return mem;
+}
+
+static void
+external_scrolled_entry_params_free(void *params)
+{
+   Elm_Params_Entry *mem = params;
+
+   if (mem->text)
+     eina_stringshare_del(mem->text);
+   free(mem);
+}
+
+static Edje_External_Param_Info external_scrolled_entry_params[] = {
+   EDJE_EXTERNAL_PARAM_INFO_STRING_DEFAULT("text", "some text"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("editable"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("single line"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("password"),
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(scrolled_entry, "scrolled_entry")
+DEFINE_EXTERNAL_TYPE_SIMPLE(scrolled_entry, "Entry");
diff --git a/src/edje_externals/elm_slider.c b/src/edje_externals/elm_slider.c
new file mode 100644 (file)
index 0000000..d7423f3
--- /dev/null
@@ -0,0 +1,330 @@
+#include "private.h"
+
+typedef struct _Elm_Params_Slider
+{
+   Elm_Params base;
+   Evas_Object *icon;
+   const char *indicator, *unit;
+   double min, max, value;
+   Eina_Bool min_exists:1;
+   Eina_Bool max_exists:1;
+   Eina_Bool value_exists:1;
+   Eina_Bool inverted:1;
+   Eina_Bool inverted_exists:1;
+   Eina_Bool span:1;
+   Eina_Bool span_exists:1;
+   Eina_Bool horizontal:1;
+   Eina_Bool horizontal_exists:1;
+} Elm_Params_Slider;
+
+static void
+external_slider_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Slider *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->base.label)
+     elm_slider_label_set(obj, p->base.label);
+   if (p->icon)
+     elm_slider_icon_set(obj, p->icon);
+   if (p->span_exists)
+     elm_slider_span_size_set(obj, p->span);
+   if ((p->min_exists) && (p->max_exists))
+     elm_slider_min_max_set(obj, p->min, p->max);
+   else if ((p->min_exists) || (p->max_exists))
+     {
+       double min, max;
+       elm_slider_min_max_get(obj, &min, &max);
+       if (p->min_exists)
+         elm_slider_min_max_set(obj, p->min, max);
+       else
+         elm_slider_min_max_set(obj, min, p->max);
+     }
+   if (p->value_exists)
+     elm_slider_value_set(obj, p->value);
+   if (p->inverted_exists)
+     elm_slider_inverted_set(obj, p->inverted);
+   if (p->horizontal_exists)
+     elm_slider_horizontal_set(obj, p->horizontal);
+   if (p->indicator)
+     elm_slider_indicator_format_set(obj, p->indicator);
+   if (p->unit)
+     elm_slider_unit_format_set(obj, p->unit);
+}
+
+static Eina_Bool
+external_slider_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_slider_label_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "icon"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            Evas_Object *icon = external_common_param_icon_get(obj, param);
+            if (icon)
+              {
+                 elm_slider_icon_set(obj, icon);
+                 return EINA_TRUE;
+              }
+         }
+     }
+   else if (!strcmp(param->name, "min"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            double min, max;
+            elm_slider_min_max_get(obj, &min, &max);
+            elm_slider_min_max_set(obj, param->d, max);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "max"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            double min, max;
+            elm_slider_min_max_get(obj, &min, &max);
+            elm_slider_min_max_set(obj, min, param->d);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "value"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            elm_slider_value_set(obj, param->d);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "horizontal"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_slider_horizontal_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "inverted"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_slider_inverted_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "span"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT)
+         {
+            elm_slider_span_size_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "unit format"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_slider_unit_format_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "indicator format"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_slider_indicator_format_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_slider_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_slider_label_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "icon"))
+     {
+       /* not easy to get icon name back from live object */
+       return EINA_FALSE;
+     }
+   else if (!strcmp(param->name, "min"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            double min, max;
+            elm_slider_min_max_get(obj, &min, &max);
+            param->d = min;
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "max"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            double min, max;
+            elm_slider_min_max_get(obj, &min, &max);
+            param->d = max;
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "value"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            param->d = elm_slider_value_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "horizontal"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_slider_horizontal_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "inverted"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_slider_inverted_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "span"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT)
+         {
+            param->i = elm_slider_span_size_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "unit format"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_slider_unit_format_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "indicator format"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_slider_indicator_format_get(obj);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_slider_params_parse(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params)
+{
+   Elm_Params_Slider *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = external_common_params_parse(Elm_Params_Slider, data, obj, params);
+   if (!mem)
+     return NULL;
+
+   external_common_icon_param_parse(&mem->icon, obj, params);
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "span"))
+         {
+            mem->span = param->i;
+            mem->span_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "min"))
+         {
+            mem->min = param->d;
+            mem->min_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "max"))
+         {
+            mem->max = param->d;
+            mem->max_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "value"))
+         {
+            mem->value = param->d;
+            mem->value_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "inverted"))
+         {
+            mem->inverted = param->i;
+            mem->inverted_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "horizontal"))
+         {
+            mem->horizontal = param->i;
+            mem->horizontal_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "unit format"))
+         mem->unit = eina_stringshare_add(param->s);
+       else if (!strcmp(param->name, "indicator format"))
+         mem->indicator = eina_stringshare_add(param->s);
+     }
+
+   return mem;
+}
+
+static void
+external_slider_params_free(void *params)
+{
+   Elm_Params_Slider *mem = params;
+
+   if (mem->icon)
+     evas_object_del(mem->icon);
+   if (mem->unit)
+     eina_stringshare_del(mem->unit);
+   if (mem->indicator)
+     eina_stringshare_del(mem->indicator);
+   external_common_params_free(params);
+}
+
+static Edje_External_Param_Info external_slider_params[] = {
+   DEFINE_EXTERNAL_COMMON_PARAMS,
+   EDJE_EXTERNAL_PARAM_INFO_STRING("icon"),
+   EDJE_EXTERNAL_PARAM_INFO_DOUBLE("min"),
+   EDJE_EXTERNAL_PARAM_INFO_DOUBLE_DEFAULT("max", 10.0),
+   EDJE_EXTERNAL_PARAM_INFO_DOUBLE("value"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("horizontal"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("inverted"),
+   EDJE_EXTERNAL_PARAM_INFO_INT("span"),
+   EDJE_EXTERNAL_PARAM_INFO_STRING_DEFAULT("unit format", "%1.2f"),
+   EDJE_EXTERNAL_PARAM_INFO_STRING_DEFAULT("indicator format", "%1.2f"),
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(slider, "slider")
+DEFINE_EXTERNAL_TYPE_SIMPLE(slider, "Slider")
diff --git a/src/edje_externals/elm_slideshow.c b/src/edje_externals/elm_slideshow.c
new file mode 100644 (file)
index 0000000..657f95b
--- /dev/null
@@ -0,0 +1,147 @@
+#include "private.h"
+
+typedef struct _Elm_Params_Slideshow
+{
+   int timeout;
+   const char *transition;
+   Eina_Bool loop:1;
+   Eina_Bool timeout_exists:1;
+   Eina_Bool loop_exists:1;
+} Elm_Params_Slideshow;
+
+static const char *transitions[] = { "fade", "black_fade", "horizontal",
+                                    "vertical", "square", NULL};
+
+static void
+external_slideshow_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Slideshow *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->timeout_exists)
+     elm_slideshow_timeout_set(obj , p->timeout);
+   if (p->loop_exists)
+     elm_slideshow_loop_set(obj, p->loop);
+   if (p->transition) {
+      elm_slideshow_transition_set(obj, p->transition);
+   }
+}
+
+static Eina_Bool
+external_slideshow_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "timeout"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT)
+         {
+            elm_slideshow_timeout_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "loop"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_slideshow_loop_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "transition"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_slideshow_transition_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_slideshow_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "timeout"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT)
+         {
+            param->i = elm_slideshow_timeout_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "loop"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_slideshow_loop_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "transition"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_slideshow_transition_get(obj);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_slideshow_params_parse(void *data, Evas_Object *obj, const Eina_List *params)
+{
+   Elm_Params_Slideshow *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = calloc(1, sizeof(Elm_Params_Slideshow));
+   if (!mem)
+     return NULL;
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "timeout"))
+         {
+            mem->timeout = param->i;
+            mem->timeout_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "loop"))
+         {
+            mem->loop = param->i;
+            mem->loop_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "transition"))
+         {
+            mem->transition = param->s;
+         }
+     }
+
+   return mem;
+}
+
+static void
+external_slideshow_params_free(void *params)
+{
+   return;
+}
+
+static Edje_External_Param_Info external_slideshow_params[] = {
+   EDJE_EXTERNAL_PARAM_INFO_INT("timeout"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("loop"),
+   EDJE_EXTERNAL_PARAM_INFO_CHOICE_FULL("transition", "fade", transitions),
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(slideshow, "slideshow");
+DEFINE_EXTERNAL_TYPE_SIMPLE(slideshow, "Slideshow");
diff --git a/src/edje_externals/elm_spinner.c b/src/edje_externals/elm_spinner.c
new file mode 100644 (file)
index 0000000..ba86ea0
--- /dev/null
@@ -0,0 +1,235 @@
+#include "private.h"
+
+typedef struct _Elm_Params_Spinner
+{
+   const char *label_format;
+   double min, max, step, value;
+   Eina_Bool min_exists:1;
+   Eina_Bool max_exists:1;
+   Eina_Bool step_exists:1;
+   Eina_Bool value_exists:1;
+   Eina_Bool wrap_exists:1;
+   Eina_Bool wrap:1;
+} Elm_Params_Spinner;
+
+static void
+external_spinner_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Spinner *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->label_format)
+     elm_spinner_label_format_set(obj, p->label_format);
+   if ((p->min_exists) && (p->max_exists))
+     elm_spinner_min_max_set(obj, p->min, p->max);
+   else if ((p->min_exists) || (p->max_exists))
+     {
+       double min, max;
+       elm_spinner_min_max_get(obj, &min, &max);
+       if (p->min_exists)
+         elm_spinner_min_max_set(obj, p->min, max);
+       else
+         elm_spinner_min_max_set(obj, min, p->max);
+     }
+   if (p->step_exists)
+     elm_spinner_step_set(obj, p->step);
+   if (p->value_exists)
+     elm_spinner_value_set(obj, p->value);
+   if (p->wrap_exists)
+     elm_spinner_wrap_set(obj, p->wrap);
+}
+
+static Eina_Bool
+external_spinner_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label format"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_spinner_label_format_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "min"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            double min, max;
+            elm_spinner_min_max_get(obj, &min, &max);
+            elm_spinner_min_max_set(obj, param->d, max);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "max"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            double min, max;
+            elm_spinner_min_max_get(obj, &min, &max);
+            elm_spinner_min_max_set(obj, min, param->d);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "step"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            elm_spinner_step_set(obj, param->d);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "value"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            elm_spinner_value_set(obj, param->d);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "wrap"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_spinner_wrap_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_spinner_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label format"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_spinner_label_format_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "min"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            double min, max;
+            elm_spinner_min_max_get(obj, &min, &max);
+            param->d = min;
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "max"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            double min, max;
+            elm_spinner_min_max_get(obj, &min, &max);
+            param->d = max;
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "step"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            param->d = elm_spinner_step_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "value"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            param->d = elm_spinner_value_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "wrap"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_spinner_value_get(obj);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_spinner_params_parse(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params)
+{
+   Elm_Params_Spinner *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = calloc(1, sizeof(Elm_Params_Spinner));
+   if (!mem)
+     return NULL;
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "label format"))
+         mem->label_format = eina_stringshare_add(param->s);
+       else if (!strcmp(param->name, "min"))
+         {
+            mem->min = param->d;
+            mem->min_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "max"))
+         {
+            mem->max = param->d;
+            mem->max_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "step"))
+         {
+            mem->step = param->d;
+            mem->step_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "value"))
+         {
+            mem->value = param->d;
+            mem->value_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "wrap"))
+         {
+            mem->wrap = param->i;
+            mem->wrap_exists = EINA_TRUE;
+         }
+     }
+
+   return mem;
+}
+
+static void
+external_spinner_params_free(void *params)
+{
+   Elm_Params_Spinner *mem = params;
+
+   if (mem->label_format)
+     eina_stringshare_del(mem->label_format);
+   free(mem);
+}
+
+static Edje_External_Param_Info external_spinner_params[] = {
+   EDJE_EXTERNAL_PARAM_INFO_STRING_DEFAULT("label format", "%1.2f"),
+   EDJE_EXTERNAL_PARAM_INFO_DOUBLE("min"),
+   EDJE_EXTERNAL_PARAM_INFO_DOUBLE_DEFAULT("max", 100.0),
+   EDJE_EXTERNAL_PARAM_INFO_DOUBLE_DEFAULT("step", 1.0),
+   EDJE_EXTERNAL_PARAM_INFO_DOUBLE("value"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("wrap"),
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(spinner, "spinner")
+DEFINE_EXTERNAL_TYPE_SIMPLE(spinner, "Spinner")
diff --git a/src/edje_externals/elm_thumb.c b/src/edje_externals/elm_thumb.c
new file mode 100644 (file)
index 0000000..c3310dc
--- /dev/null
@@ -0,0 +1,162 @@
+#include <assert.h>
+
+#include "private.h"
+
+typedef struct _Elm_Params_Thumb
+{
+   const char *animate;
+   Eina_Bool keep_aspect:1;
+   Eina_Bool aspect_exists:1;
+} Elm_Params_Thumb;
+
+static const char* choices[] = {"loop", "start", "stop", NULL};
+
+static Elm_Thumb_Animation_Setting
+_anim_setting_get(const char *anim_str)
+{
+   unsigned int i;
+
+   assert(sizeof(choices)/sizeof(choices[0]) == ELM_THUMB_ANIMATION_LAST + 1);
+
+   for (i = 0; i < sizeof(choices); i++)
+     {
+       if (strcmp(anim_str, choices[i]) == 0)
+         return i;
+     }
+   return ELM_THUMB_ANIMATION_LAST;
+}
+
+static void
+external_thumb_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Thumb *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->animate)
+     {
+       Elm_Thumb_Animation_Setting set = _anim_setting_get(p->animate);
+       if (set != ELM_THUMB_ANIMATION_LAST)
+          elm_thumb_animate_set(obj, set);
+     }
+   if (p->aspect_exists)
+     elm_thumb_keep_aspect_set(obj, p->keep_aspect);
+}
+
+static Eina_Bool
+external_thumb_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "animate"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE)
+         {
+            Elm_Thumb_Animation_Setting set = _anim_setting_get(param->s);
+            if (set == ELM_THUMB_ANIMATION_LAST) return EINA_FALSE;
+            elm_thumb_animate_set(obj, set);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "aspect"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_thumb_keep_aspect_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_thumb_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "animate"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE)
+         {
+            Elm_Thumb_Animation_Setting anim_set = elm_thumb_animate_get(obj);
+
+            if (anim_set == ELM_THUMB_ANIMATION_LAST)
+              return EINA_FALSE;
+
+            param->s = choices[anim_set];
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "aspect"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_thumb_keep_aspect_get(obj);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_thumb_params_parse(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params)
+{
+   Elm_Params_Thumb *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = calloc(1, sizeof(Elm_Params_Thumb));
+   if (!mem)
+     return NULL;
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "animate"))
+         mem->animate = eina_stringshare_add(param->s);
+       else if (!strcmp(param->name, "aspect"))
+         {
+            mem->keep_aspect = !!param->i;
+            mem->aspect_exists = EINA_TRUE;
+         }
+     }
+
+   return mem;
+}
+
+static void
+external_thumb_params_free(void *params)
+{
+   Elm_Params_Thumb *mem = params;
+
+   if (mem->animate)
+     eina_stringshare_del(mem->animate);
+   free(mem);
+}
+
+static Edje_External_Param_Info external_thumb_params[] =
+  {
+    EDJE_EXTERNAL_PARAM_INFO_CHOICE_FULL("animate", "loop", choices),
+    EDJE_EXTERNAL_PARAM_INFO_BOOL("keep aspect"),
+    EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+  };
+
+DEFINE_EXTERNAL_ICON_ADD(thumb, "thumb")
+
+static Evas_Object *
+external_thumb_add(void *data __UNUSED__, Evas *evas __UNUSED__, Evas_Object *edje, const Eina_List *params __UNUSED__, const char *part_name)
+{
+   Evas_Object *parent, *obj;
+   parent = elm_widget_parent_widget_get(edje);
+   if (!parent) parent = edje;
+   elm_need_ethumb(); /* extra command needed */
+   obj = elm_thumb_add(parent);
+   external_signals_proxy(obj, edje, part_name);
+   return obj;
+}
+DEFINE_EXTERNAL_TYPE(thumb, "Thumbnail")
diff --git a/src/edje_externals/elm_toggle.c b/src/edje_externals/elm_toggle.c
new file mode 100644 (file)
index 0000000..62d645f
--- /dev/null
@@ -0,0 +1,205 @@
+#include <string.h>
+
+#include "private.h"
+
+typedef struct _Elm_Params_Toggle
+{
+   Elm_Params base;
+   Evas_Object *icon;
+   const char *on, *off;
+   Eina_Bool state:1;
+   Eina_Bool state_exists:1;
+} Elm_Params_Toggle;
+
+static void
+external_toggle_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Toggle *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->base.label)
+     elm_toggle_label_set(obj, p->base.label);
+   if (p->icon)
+     elm_toggle_icon_set(obj, p->icon);
+
+   if ((p->on) && (p->off))
+     elm_toggle_states_labels_set(obj, p->on, p->off);
+   else if ((p->on) || (p->off))
+     {
+       const char *on, *off;
+       elm_toggle_states_labels_get(obj, &on, &off);
+       if (p->on)
+         elm_toggle_states_labels_set(obj, p->on, off);
+       else
+         elm_toggle_states_labels_set(obj, on, p->off);
+     }
+
+   if (p->state_exists)
+     elm_toggle_state_set(obj, p->state);
+}
+
+static Eina_Bool
+external_toggle_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            elm_toggle_label_set(obj, param->s);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "icon"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            Evas_Object *icon = external_common_param_icon_get(obj, param);
+            if (icon)
+              {
+                 elm_toggle_icon_set(obj, icon);
+                 return EINA_TRUE;
+              }
+         }
+     }
+   else if (!strcmp(param->name, "label on"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            const char *on, *off;
+            elm_toggle_states_labels_get(obj, &on, &off);
+            elm_toggle_states_labels_set(obj, param->s, off);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "label off"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            const char *on, *off;
+            elm_toggle_states_labels_get(obj, &on, &off);
+            elm_toggle_states_labels_set(obj, on, param->s);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "state"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            elm_toggle_state_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_toggle_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "label"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            param->s = elm_toggle_label_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "icon"))
+     {
+       /* not easy to get icon name back from live object */
+       return EINA_FALSE;
+     }
+   else if (!strcmp(param->name, "label on"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            const char *on, *off;
+            elm_toggle_states_labels_get(obj, &on, &off);
+            param->s = on;
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "label off"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
+         {
+            const char *on, *off;
+            elm_toggle_states_labels_get(obj, &on, &off);
+            param->s = off;
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "state"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
+         {
+            param->i = elm_toggle_state_get(obj);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_toggle_params_parse(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params)
+{
+   Elm_Params_Toggle *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = external_common_params_parse(Elm_Params_Toggle, data, obj, params);
+   if (!mem)
+     return NULL;
+
+   external_common_icon_param_parse(&mem->icon, obj, params);
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "state")) {
+          mem->state = param->i;
+          mem->state_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "label on"))
+         mem->on = eina_stringshare_add(param->s);
+       else if (!strcmp(param->name, "label off"))
+         mem->off = eina_stringshare_add(param->s);
+     }
+
+   return mem;
+}
+
+static void
+external_toggle_params_free(void *params)
+{
+   Elm_Params_Toggle *mem = params;
+
+   if (mem->icon)
+     evas_object_del(mem->icon);
+   if (mem->on)
+     eina_stringshare_del(mem->on);
+   if (mem->off)
+     eina_stringshare_del(mem->off);
+   external_common_params_free(params);
+}
+
+static Edje_External_Param_Info external_toggle_params[] = {
+   DEFINE_EXTERNAL_COMMON_PARAMS,
+   EDJE_EXTERNAL_PARAM_INFO_STRING("icon"),
+   EDJE_EXTERNAL_PARAM_INFO_STRING_DEFAULT("label on", "ON"),
+   EDJE_EXTERNAL_PARAM_INFO_STRING_DEFAULT("label off", "OFF"),
+   EDJE_EXTERNAL_PARAM_INFO_BOOL("state"),
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(toggle, "toggle")
+DEFINE_EXTERNAL_TYPE_SIMPLE(toggle, "Toggle")
diff --git a/src/edje_externals/elm_toolbar.c b/src/edje_externals/elm_toolbar.c
new file mode 100644 (file)
index 0000000..a41cb69
--- /dev/null
@@ -0,0 +1,120 @@
+#include "private.h"
+
+typedef struct _Elm_Params_Toolbar
+{
+   int icon_size;
+   Eina_Bool icon_size_exists:1;
+   double align;
+   Eina_Bool align_exists:1;
+} Elm_Params_Toolbar;
+
+static void
+external_toolbar_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
+{
+   const Elm_Params_Toolbar *p;
+
+   if (to_params) p = to_params;
+   else if (from_params) p = from_params;
+   else return;
+
+   if (p->icon_size_exists)
+     elm_toolbar_icon_size_set(obj, p->icon_size);
+   if (p->align_exists)
+     elm_toolbar_align_set(obj, p->align);
+}
+
+static Eina_Bool
+external_toolbar_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "icon_size"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT)
+         {
+            elm_toolbar_icon_size_set(obj, param->i);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "align"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            elm_toolbar_align_set(obj, param->d);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+external_toolbar_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
+{
+   if (!strcmp(param->name, "icon_size"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT)
+         {
+            param->i = elm_toolbar_icon_size_get(obj);
+            return EINA_TRUE;
+         }
+     }
+   else if (!strcmp(param->name, "align"))
+     {
+       if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
+         {
+            param->d = elm_toolbar_align_get(obj);
+            return EINA_TRUE;
+         }
+     }
+
+   ERR("unknown parameter '%s' of type '%s'",
+       param->name, edje_external_param_type_str(param->type));
+
+   return EINA_FALSE;
+}
+
+static void *
+external_toolbar_params_parse(void *data, Evas_Object *obj, const Eina_List *params)
+{
+   Elm_Params_Toolbar *mem;
+   Edje_External_Param *param;
+   const Eina_List *l;
+
+   mem = calloc(1, sizeof(Elm_Params_Toolbar));
+   if (!mem)
+     return NULL;
+
+   EINA_LIST_FOREACH(params, l, param)
+     {
+       if (!strcmp(param->name, "icon_size"))
+         {
+            mem->icon_size = param->i;
+            mem->icon_size_exists = EINA_TRUE;
+         }
+       else if (!strcmp(param->name, "align"))
+         {
+            mem->align = param->d;
+            mem->align_exists = EINA_TRUE;
+         }
+     }
+
+   return mem;
+}
+
+static void
+external_toolbar_params_free(void *params)
+{
+   Elm_Params_Toolbar *mem = params;
+   free(mem);
+}
+
+static Edje_External_Param_Info external_toolbar_params[] = {
+   EDJE_EXTERNAL_PARAM_INFO_INT("icon_size"),
+   EDJE_EXTERNAL_PARAM_INFO_DOUBLE("align"),
+   EDJE_EXTERNAL_PARAM_INFO_SENTINEL
+};
+
+DEFINE_EXTERNAL_ICON_ADD(toolbar, "toolbar");
+DEFINE_EXTERNAL_TYPE_SIMPLE(toolbar, "Toolbar");
diff --git a/src/edje_externals/modules.inc b/src/edje_externals/modules.inc
new file mode 100644 (file)
index 0000000..ec29508
--- /dev/null
@@ -0,0 +1,23 @@
+DEFINE_TYPE(anchorblock)
+DEFINE_TYPE(anchorview)
+DEFINE_TYPE(bubble)
+DEFINE_TYPE(button)
+DEFINE_TYPE(check)
+DEFINE_TYPE(clock)
+DEFINE_TYPE(fileselector)
+DEFINE_TYPE(fileselector_button)
+DEFINE_TYPE(genlist)
+DEFINE_TYPE(hoversel)
+DEFINE_TYPE(list)
+DEFINE_TYPE(map)
+DEFINE_TYPE(notepad)
+DEFINE_TYPE(photocam)
+DEFINE_TYPE(progressbar)
+DEFINE_TYPE(radio)
+DEFINE_TYPE(scrolled_entry)
+DEFINE_TYPE(slider)
+DEFINE_TYPE(slideshow)
+DEFINE_TYPE(spinner)
+DEFINE_TYPE(thumb)
+DEFINE_TYPE(toggle)
+DEFINE_TYPE(toolbar)
diff --git a/src/edje_externals/private.h b/src/edje_externals/private.h
new file mode 100644 (file)
index 0000000..45591b1
--- /dev/null
@@ -0,0 +1,79 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+#include "Elementary.h"
+#include "elm_priv.h"
+
+typedef struct {
+    const char *label;
+} Elm_Params;
+
+void external_signal(void *data, Evas_Object *obj, const char *signal, const char *source);
+void external_signals_proxy(Evas_Object *obj, Evas_Object *edje, const char *part_name);
+const char *external_translate(void *data, const char *orig);
+void external_common_params_free(void *params);
+void *external_common_params_parse_internal(size_t params_size, void *data, Evas_Object *obj, const Eina_List *params);
+Evas_Object *external_common_param_icon_get(Evas_Object *obj, const Edje_External_Param *param);
+Evas_Object *external_common_param_edje_object_get(Evas_Object *obj, const Edje_External_Param *p);
+void external_common_icon_param_parse(Evas_Object **icon, Evas_Object *obj, const Eina_List *params);
+#define external_common_params_parse(type, data, obj, params)   \
+    external_common_params_parse_internal(sizeof(type), data, obj, params)
+
+
+#define DEFINE_EXTERNAL_TYPE(type_name, name)           \
+static const char *                                     \
+external_##type_name##_label_get(void *data __UNUSED__) \
+{                                                       \
+    return name;                                        \
+}                                                       \
+                                                        \
+const Edje_External_Type external_##type_name##_type = {\
+    .abi_version = EDJE_EXTERNAL_TYPE_ABI_VERSION,      \
+    .module = "elm",                                    \
+    .module_name = "Elementary",                        \
+    .add = external_##type_name##_add,                  \
+    .state_set = external_##type_name##_state_set,      \
+    .signal_emit = external_signal,                     \
+    .param_set = external_##type_name##_param_set,      \
+    .param_get = external_##type_name##_param_get,      \
+    .params_parse = external_##type_name##_params_parse,\
+    .params_free = external_##type_name##_params_free,  \
+    .label_get = external_##type_name##_label_get,      \
+    .description_get = NULL,                            \
+    .icon_add = external_##type_name##_icon_add,        \
+    .preview_add = NULL,                                \
+    .translate = external_translate,                    \
+    .parameters_info = external_##type_name##_params,   \
+    .data = NULL                                        \
+};
+
+#define DEFINE_EXTERNAL_TYPE_SIMPLE(type_name, name)    \
+static Evas_Object *                                \
+external_##type_name##_add(void *data __UNUSED__, Evas *evas __UNUSED__, Evas_Object *edje, const Eina_List *params __UNUSED__, const char *part_name) \
+{                                                                      \
+   Evas_Object *parent, *obj;                                          \
+   parent = elm_widget_parent_widget_get(edje);                        \
+   if (!parent) parent = edje;                                         \
+   obj = elm_##type_name##_add(parent);                                \
+   external_signals_proxy(obj, edje, part_name);                       \
+   return obj;                                                         \
+}                                                                      \
+                                                                       \
+DEFINE_EXTERNAL_TYPE(type_name, name)
+
+#define DEFINE_EXTERNAL_ICON_ADD(type_name, name)                   \
+Evas_Object *                                                       \
+external_##type_name##_icon_add(void *data __UNUSED__, Evas *e) {   \
+   Evas_Object *ic;                                                 \
+   int w = 20, h = 10;                                              \
+                                                                    \
+   ic = edje_object_add(e);                                         \
+   edje_object_file_set(ic, PACKAGE_DATA_DIR"/edje_externals/icons.edj", "ico_"name);\
+   evas_object_size_hint_min_set(ic, w, h);                         \
+   evas_object_size_hint_max_set(ic, w, h);                         \
+                                                                    \
+   return ic;                                                       \
+}
+
+#define DEFINE_EXTERNAL_COMMON_PARAMS           \
+    EDJE_EXTERNAL_PARAM_INFO_STRING_DEFAULT("label", "label goes here")
diff --git a/src/lib/Elementary.h.in b/src/lib/Elementary.h.in
new file mode 100644 (file)
index 0000000..1862715
--- /dev/null
@@ -0,0 +1,1511 @@
+/*
+ *
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#ifndef ELEMENTARY_H
+#define ELEMENTARY_H
+
+/**
+ * @file Elementary.h
+ * @brief Elementary's API
+ *
+ * Elementary API.
+ */
+
+@ELM_UNIX_DEF@ ELM_UNIX
+@ELM_WIN32_DEF@ ELM_WIN32
+@ELM_WINCE_DEF@ ELM_WINCE
+@ELM_EDBUS_DEF@ ELM_EDBUS
+@ELM_EFREET_DEF@ ELM_EFREET
+@ELM_ETHUMB_DEF@ ELM_ETHUMB
+@ELM_ALLOCA_H_DEF@ ELM_ALLOCA_H
+@ELM_LIBINTL_H_DEF@ ELM_LIBINTL_H
+
+/* Standard headers for standard system calls etc. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#include <dlfcn.h>
+#include <math.h>
+#include <fnmatch.h>
+#include <limits.h>
+#include <ctype.h>
+#include <time.h>
+#include <dirent.h>
+#include <pwd.h>
+#include <errno.h>
+
+#ifdef ELM_UNIX
+# include <locale.h>
+# ifdef ELM_LIBINTL_H
+#  include <libintl.h>
+# endif
+# include <signal.h>
+# include <grp.h>
+# include <glob.h>
+#endif
+
+#ifdef ELM_ALLOCA_H
+# include <alloca.h>
+#endif
+
+#if defined (ELM_WIN32) || defined (ELM_WINCE)
+# include <malloc.h>
+# ifndef alloca
+#  define alloca _alloca
+# endif
+#endif
+
+
+/* EFL headers */
+#include <Eina.h>
+#include <Eet.h>
+#include <Evas.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Ecore_File.h>
+#include <Edje.h>
+
+#ifdef ELM_EDBUS
+# include <E_DBus.h>
+# include <E_Hal.h>
+#endif
+
+#ifdef ELM_EFREET
+# include <Efreet.h>
+# include <Efreet_Mime.h>
+# include <Efreet_Trash.h>
+#endif
+
+#ifdef ELM_ETHUMB
+# include <Ethumb_Client.h>
+#endif
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef ELEMENTARY_BUILD
+#  ifdef DLL_EXPORT
+#   define EAPI __declspec(dllexport)
+#  else
+#   define EAPI
+#  endif /* ! DLL_EXPORT */
+# else
+#  define EAPI __declspec(dllimport)
+# endif /* ! EFL_EVAS_BUILD */
+#else
+# ifdef __GNUC__
+#  if __GNUC__ >= 4
+#   define EAPI __attribute__ ((visibility("default")))
+#  else
+#   define EAPI
+#  endif
+# else
+#  define EAPI
+# endif
+#endif /* ! _WIN32 */
+
+
+/* allow usage from c++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* handy macros */
+#define ELM_RECTS_INTERSECT(x, y, w, h, xx, yy, ww, hh) (((x) < ((xx) + (ww))) && ((y) < ((yy) + (hh))) && (((x) + (w)) > (xx)) && (((y) + (h)) > (yy)))
+#define ELM_PI 3.14159265358979323846
+
+/**************************************************************************/
+   EAPI extern int ELM_ECORE_EVENT_ETHUMB_CONNECT;
+
+   /* Objects */
+   typedef enum _Elm_Win_Type
+     {
+       ELM_WIN_BASIC,
+       ELM_WIN_DIALOG_BASIC,
+       ELM_WIN_DESKTOP,
+       ELM_WIN_DOCK,
+       ELM_WIN_TOOLBAR,
+       ELM_WIN_MENU,
+       ELM_WIN_UTILITY,
+       ELM_WIN_SPLASH
+     } Elm_Win_Type;
+
+   typedef enum _Elm_Win_Keyboard_Mode
+     {
+       ELM_WIN_KEYBOARD_UNKNOWN,
+         ELM_WIN_KEYBOARD_OFF,
+         ELM_WIN_KEYBOARD_ON,
+         ELM_WIN_KEYBOARD_ALPHA,
+         ELM_WIN_KEYBOARD_NUMERIC,
+         ELM_WIN_KEYBOARD_PIN,
+         ELM_WIN_KEYBOARD_PHONE_NUMBER,
+         ELM_WIN_KEYBOARD_HEX,
+         ELM_WIN_KEYBOARD_TERMINAL,
+         ELM_WIN_KEYBOARD_PASSWORD,
+         ELM_WIN_KEYBOARD_IP,
+         ELM_WIN_KEYBOARD_HOST,
+         ELM_WIN_KEYBOARD_FILE,
+         ELM_WIN_KEYBOARD_URL,
+         ELM_WIN_KEYBOARD_KEYPAD,
+         ELM_WIN_KEYBOARD_J2ME
+     } Elm_Win_Keyboard_Mode;
+
+  /**
+   * Emitted when policy value changed.
+   */
+  EAPI extern int ELM_EVENT_POLICY_CHANGED;
+  typedef struct _Elm_Event_Policy_Changed
+    {
+       unsigned int policy;
+       int new_value;
+       int old_value;
+    } Elm_Event_Policy_Changed;
+
+  /**
+   * Policy identifiers.
+   *
+   * @see elm_policy_set()
+   */
+  typedef enum _Elm_Policy
+    {
+      ELM_POLICY_QUIT, /**< when should quit application automatically.
+                       * @see Elm_Policy_Quit.
+                       */
+      ELM_POLICY_LAST
+    } Elm_Policy;
+
+  typedef enum _Elm_Policy_Quit
+    {
+      ELM_POLICY_QUIT_NONE = 0, /**< never quit application automatically */
+      ELM_POLICY_QUIT_LAST_WINDOW_CLOSED /**< quit when last window is closed */
+    } Elm_Policy_Quit;
+
+  typedef enum _Elm_Thumb_Animation_Setting
+    {
+       ELM_THUMB_ANIMATION_START = 0, /* Play animation once */
+       ELM_THUMB_ANIMATION_LOOP,      /* Keep playing animation until stop is requested */
+       ELM_THUMB_ANIMATION_STOP,
+       ELM_THUMB_ANIMATION_LAST
+    } Elm_Thumb_Animation_Setting;
+   
+   typedef struct _Elm_Theme Elm_Theme;
+   
+   typedef enum _Elm_Clock_Digedit
+     {
+        ELM_CLOCK_NONE         = 0,
+        ELM_CLOCK_HOUR_DECIMAL = 1 << 0,
+        ELM_CLOCK_HOUR_UNIT    = 1 << 1,
+        ELM_CLOCK_MIN_DECIMAL  = 1 << 2,
+        ELM_CLOCK_MIN_UNIT     = 1 << 3,
+        ELM_CLOCK_SEC_DECIMAL  = 1 << 4,
+        ELM_CLOCK_SEC_UNIT     = 1 << 5,
+        ELM_CLOCK_ALL         = (1 << 6) - 1
+     } Elm_Clock_Digedit;
+   
+#ifndef ELM_LIB_QUICKLAUNCH
+#define ELM_MAIN() int main(int argc, char **argv) {elm_init(argc, argv); return elm_main(argc, argv);}
+#else
+#define ELM_MAIN() int main(int argc, char **argv) {return elm_quicklaunch_fallback(argc, argv);}
+#endif
+
+/**************************************************************************/
+   /* General calls */
+   EAPI void         elm_init(int argc, char **argv);
+   EAPI void         elm_shutdown(void);
+   EAPI void         elm_run(void);
+   EAPI void         elm_exit(void);
+
+   EAPI void         elm_quicklaunch_init(int argc, char **argv);
+   EAPI void         elm_quicklaunch_sub_init(int argc, char **argv);
+   EAPI void         elm_quicklaunch_sub_shutdown(void);
+   EAPI void         elm_quicklaunch_shutdown(void);
+   EAPI void         elm_quicklaunch_seed(void);
+   EAPI Eina_Bool    elm_quicklaunch_prepare(int argc, char **argv);
+   EAPI Eina_Bool    elm_quicklaunch_fork(int argc, char **argv, char *cwd, void (postfork_func) (void *data), void *postfork_data);
+   EAPI void         elm_quicklaunch_cleanup(void);
+   EAPI int          elm_quicklaunch_fallback(int argc, char **argv);
+   EAPI char        *elm_quicklaunch_exe_path_get(const char *exe);
+
+   EAPI void         elm_need_efreet(void);
+   EAPI void         elm_need_e_dbus(void);
+   EAPI void        elm_need_ethumb(void);
+
+   EAPI Eina_Bool    elm_policy_set(unsigned int policy, int value);
+   EAPI int          elm_policy_get(unsigned int policy);
+   
+   EAPI void         elm_all_flush(void);
+       
+   EAPI void         elm_object_scale_set(Evas_Object *obj, double scale);
+   EAPI double       elm_object_scale_get(const Evas_Object *obj);
+   EAPI void         elm_object_style_set(Evas_Object *obj, const char *style);
+   EAPI const char  *elm_object_style_get(const Evas_Object *obj);
+   EAPI void         elm_object_disabled_set(Evas_Object *obj, Eina_Bool disabled);
+   EAPI Eina_Bool    elm_object_disabled_get(const Evas_Object *obj);
+
+   EAPI Eina_Bool    elm_object_widget_check(const Evas_Object *obj);
+   EAPI Evas_Object *elm_object_parent_widget_get(const Evas_Object *obj);
+   EAPI const char  *elm_object_widget_type_get(const Evas_Object *obj);
+
+   EAPI double       elm_scale_get(void);
+   EAPI void         elm_scale_set(double scale);
+   EAPI void         elm_scale_all_set(double scale);
+   EAPI Evas_Coord   elm_finger_size_get(void);
+   EAPI void         elm_finger_size_set(Evas_Coord size);
+   EAPI void         elm_finger_size_all_set(Evas_Coord size);
+       
+   EAPI void         elm_object_focus(Evas_Object *obj);
+   EAPI void         elm_object_unfocus(Evas_Object *obj);
+   EAPI void         elm_object_focus_allow_set(Evas_Object *obj, Eina_Bool enable);
+   EAPI Eina_Bool    elm_object_focus_allow_get(const Evas_Object *obj);
+
+   EAPI void         elm_object_scroll_hold_push(Evas_Object *obj);
+   EAPI void         elm_object_scroll_hold_pop(Evas_Object *obj);
+   EAPI void         elm_object_scroll_freeze_push(Evas_Object *obj);
+   EAPI void         elm_object_scroll_freeze_pop(Evas_Object *obj);
+
+   EAPI void         elm_coords_finger_size_adjust(int times_w, Evas_Coord *w, int times_h, Evas_Coord *h);
+
+   EAPI Elm_Theme   *elm_theme_new(void);
+  EAPI void         elm_theme_free(Elm_Theme *th);
+   EAPI void         elm_theme_overlay_add(Elm_Theme *th, const char *item);
+   EAPI void         elm_theme_overlay_del(Elm_Theme *th, const char *item);
+   EAPI void         elm_theme_extension_add(Elm_Theme *th, const char *item);
+   EAPI void         elm_theme_extension_del(Elm_Theme *th, const char *item);
+   EAPI void         elm_theme_set(Elm_Theme *th, const char *theme);
+   EAPI const char  *elm_theme_get(Elm_Theme *th);
+   EAPI void         elm_theme_flush(Elm_Theme *th);
+   EAPI void         elm_theme_full_flush(void);
+   
+   EAPI void         elm_theme_all_set(const char *theme);
+
+   EAPI void         elm_object_theme_set(Evas_Object *obj, Elm_Theme *th);
+   EAPI Elm_Theme   *elm_object_theme_get(Evas_Object *obj);
+   
+   EAPI Evas_Object *elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type);
+   EAPI void         elm_win_resize_object_add(Evas_Object *obj, Evas_Object *subobj);
+   EAPI void         elm_win_resize_object_del(Evas_Object *obj, Evas_Object *subobj);
+   EAPI void         elm_win_title_set(Evas_Object *obj, const char *title);
+   EAPI void         elm_win_autodel_set(Evas_Object *obj, Eina_Bool autodel);
+   EAPI void         elm_win_activate(Evas_Object *obj);
+   EAPI void         elm_win_lower(Evas_Object *obj);
+   EAPI void         elm_win_raise(Evas_Object *obj);
+   EAPI void         elm_win_borderless_set(Evas_Object *obj, Eina_Bool borderless);
+   EAPI Eina_Bool    elm_win_borderless_get(const Evas_Object *obj);
+   EAPI void         elm_win_shaped_set(Evas_Object *obj, Eina_Bool shaped);
+   EAPI Eina_Bool    elm_win_shaped_get(const Evas_Object *obj);
+   EAPI void         elm_win_alpha_set(Evas_Object *obj, Eina_Bool alpha);
+   EAPI Eina_Bool    elm_win_transparent_get(const Evas_Object *obj);
+   EAPI void         elm_win_transparent_set(Evas_Object *obj, Eina_Bool transparent);
+   EAPI Eina_Bool    elm_win_alpha_get(const Evas_Object *obj);
+   EAPI void         elm_win_override_set(Evas_Object *obj, Eina_Bool override);
+   EAPI Eina_Bool    elm_win_override_get(const Evas_Object *obj);
+   EAPI void         elm_win_fullscreen_set(Evas_Object *obj, Eina_Bool fullscreen);
+   EAPI Eina_Bool    elm_win_fullscreen_get(const Evas_Object *obj);
+   EAPI void         elm_win_maximized_set(Evas_Object *obj, Eina_Bool maximized);
+   EAPI Eina_Bool    elm_win_maximized_get(const Evas_Object *obj);
+   EAPI void         elm_win_iconified_set(Evas_Object *obj, Eina_Bool iconified);
+   EAPI Eina_Bool    elm_win_iconified_get(const Evas_Object *obj);
+   EAPI void         elm_win_layer_set(Evas_Object *obj, int layer);
+   EAPI int          elm_win_layer_get(const Evas_Object *obj);
+   EAPI void         elm_win_rotation_set(Evas_Object *obj, int rotation);
+   EAPI void         elm_win_rotation_with_resize_set(Evas_Object *obj, int rotation);
+   EAPI int          elm_win_rotation_get(const Evas_Object *obj);
+   EAPI void         elm_win_sticky_set(Evas_Object *obj, Eina_Bool sticky);
+   EAPI Eina_Bool    elm_win_sticky_get(const Evas_Object *obj);
+   EAPI void         elm_win_conformant_set(Evas_Object *obj, Eina_Bool conformant);
+   EAPI Eina_Bool    elm_win_conformant_get(const Evas_Object *obj);
+   EAPI void         elm_win_quickpanel_set(Evas_Object *obj, Eina_Bool quickpanel);
+   EAPI Eina_Bool    elm_win_quickpanel_get(const Evas_Object *obj);
+   EAPI void         elm_win_quickpanel_priority_major_set(Evas_Object *obj, int priority);
+   EAPI int          elm_win_quickpanel_priority_major_get(const Evas_Object *obj);
+   EAPI void         elm_win_quickpanel_priority_minor_set(Evas_Object *obj, int priority);
+   EAPI int          elm_win_quickpanel_priority_minor_get(const Evas_Object *obj);
+   EAPI void         elm_win_quickpanel_zone_set(Evas_Object *obj, int zone);
+
+   /*...
+    * ecore_x_icccm_hints_set -> accepts_focus (add to ecore_evas)
+    * ecore_x_icccm_hints_set -> window_group (add to ecore_evas)
+    * ecore_x_icccm_size_pos_hints_set -> request_pos (add to ecore_evas)
+    * ecore_x_icccm_client_leader_set -> l (add to ecore_evas)
+    * ecore_x_icccm_window_role_set -> role (add to ecore_evas)
+    * ecore_x_icccm_transient_for_set -> forwin (add to ecore_evas)
+    * ecore_x_netwm_window_type_set -> type (add to ecore_evas)
+    *
+    * (add to ecore_x) set netwm argb icon! (add to ecore_evas)
+    * (blank mouse, private mouse obj, defaultmouse)
+    *
+    */
+   EAPI void         elm_win_keyboard_mode_set(Evas_Object *obj, Elm_Win_Keyboard_Mode mode);
+   EAPI void         elm_win_keyboard_win_set(Evas_Object *obj, Eina_Bool is_keyboard);
+   
+   EAPI void         elm_win_screen_position_get(const Evas_Object *obj, int *x, int *y);
+       
+   EAPI Evas_Object *elm_win_inwin_add(Evas_Object *obj);
+   EAPI void         elm_win_inwin_activate(Evas_Object *obj);
+   EAPI void         elm_win_inwin_content_set(Evas_Object *obj, Evas_Object *content);
+   /* available styles:
+    * default
+    * minimal
+    * minimal_vertical
+    */
+
+   /* X specific calls - won't work on non-x engines (return 0) */
+   EAPI Ecore_X_Window elm_win_xwindow_get(const Evas_Object *obj);
+   /* smart callbacks called:
+    * "delete,request" - the user requested to delete the window
+    * "focus,in" - window got focus
+    * "focus,out" - window lost focus
+    * "moved" - window that holds the canvas was moved
+    */
+
+   EAPI Evas_Object *elm_bg_add(Evas_Object *parent);
+   EAPI void         elm_bg_file_set(Evas_Object *obj, const char *file, const char *group);
+   /* smart callbacks called:
+    */
+
+   EAPI Evas_Object *elm_icon_add(Evas_Object *parent);
+   EAPI Eina_Bool    elm_icon_file_set(Evas_Object *obj, const char *file, const char *group);
+   EAPI Eina_Bool    elm_icon_standard_set(Evas_Object *obj, const char *name);
+   EAPI void         elm_icon_smooth_set(Evas_Object *obj, Eina_Bool smooth);
+   EAPI void         elm_icon_no_scale_set(Evas_Object *obj, Eina_Bool no_scale);
+   EAPI void         elm_icon_scale_set(Evas_Object *obj, Eina_Bool scale_up, Eina_Bool scale_down);
+   EAPI void         elm_icon_fill_outside_set(Evas_Object *obj, Eina_Bool fill_outside);
+   EAPI void         elm_icon_prescale_set(Evas_Object *obj, int size);
+   /* smart callbacks called:
+    * "clicked" - the user clicked the icon
+    */
+
+   typedef enum _Elm_Image_Orient
+     {
+       ELM_IMAGE_ORIENT_NONE,
+       ELM_IMAGE_ROTATE_90_CW,
+       ELM_IMAGE_ROTATE_180_CW,
+       ELM_IMAGE_ROTATE_90_CCW,
+       ELM_IMAGE_FLIP_HORIZONTAL,
+       ELM_IMAGE_FLIP_VERTICAL,
+       ELM_IMAGE_FLIP_TRANSPOSE,
+       ELM_IMAGE_FLIP_TRANSVERSE
+     } Elm_Image_Orient;
+
+   EAPI Evas_Object *elm_image_add(Evas_Object *parent);
+   EAPI Eina_Bool    elm_image_file_set(Evas_Object *obj, const char *file, const char *group);
+   EAPI void         elm_image_smooth_set(Evas_Object *obj, Eina_Bool smooth);
+   EAPI void         elm_image_object_size_get(const Evas_Object *obj, int *w, int *h);
+   EAPI void         elm_image_no_scale_set(Evas_Object *obj, Eina_Bool no_scale);
+   EAPI void         elm_image_scale_set(Evas_Object *obj, Eina_Bool scale_up, Eina_Bool scale_down);
+   EAPI void         elm_image_fill_outside_set(Evas_Object *obj, Eina_Bool fill_outside);
+   EAPI void         elm_image_prescale_set(Evas_Object *obj, int size);
+   EAPI void         elm_image_orient_set(Evas_Object *obj, Elm_Image_Orient orient);
+   /* smart callbacks called:
+    * "clicked" - the user clicked the image
+    */
+
+   EAPI Evas_Object *elm_box_add(Evas_Object *parent);
+   EAPI void         elm_box_horizontal_set(Evas_Object *obj, Eina_Bool horizontal);
+   EAPI void         elm_box_homogenous_set(Evas_Object *obj, Eina_Bool homogenous);
+   EAPI void         elm_box_pack_start(Evas_Object *obj, Evas_Object *subobj);
+   EAPI void         elm_box_pack_end(Evas_Object *obj, Evas_Object *subobj);
+   EAPI void         elm_box_pack_before(Evas_Object *obj, Evas_Object *subobj, Evas_Object *before);
+   EAPI void         elm_box_pack_after(Evas_Object *obj, Evas_Object *subobj, Evas_Object *after);
+   EAPI void         elm_box_clear(Evas_Object *obj);
+   EAPI void         elm_box_unpack(Evas_Object *obj, Evas_Object *subobj);
+   EAPI void         elm_box_unpack_all(Evas_Object *obj);
+   /* smart callbacks called:
+    */
+
+   EAPI Evas_Object *elm_button_add(Evas_Object *parent);
+   EAPI void         elm_button_label_set(Evas_Object *obj, const char *label);
+   EAPI const char  *elm_button_label_get(const Evas_Object *obj);
+   EAPI void         elm_button_icon_set(Evas_Object *obj, Evas_Object *icon);
+   EAPI Evas_Object *elm_button_icon_get(const Evas_Object *obj);
+   EAPI void         elm_button_autorepeat_set(Evas_Object *obj, Eina_Bool on);
+   EAPI void         elm_button_autorepeat_initial_timeout_set(Evas_Object *obj, double t);
+   EAPI void         elm_button_autorepeat_gap_timeout_set(Evas_Object *obj, double t);
+
+   EAPI Evas_Object *elm_fileselector_button_add(Evas_Object *parent);
+   EAPI void         elm_fileselector_button_label_set(Evas_Object *obj, const char *label);
+   EAPI const char  *elm_fileselector_button_label_get(const Evas_Object *obj);
+   EAPI void         elm_fileselector_button_icon_set(Evas_Object *obj, Evas_Object *icon);
+   EAPI Evas_Object *elm_fileselector_button_icon_get(const Evas_Object *obj);
+   EAPI void         elm_fileselector_button_window_title_set(Evas_Object *obj, const char *title);
+   EAPI const char  *elm_fileselector_button_window_title_get(Evas_Object *obj);
+   EAPI void         elm_fileselector_button_window_size_set(Evas_Object *obj, Evas_Coord width, Evas_Coord height);
+   EAPI void         elm_fileselector_button_window_size_get(Evas_Object *obj, Evas_Coord *width, Evas_Coord *height);
+   EAPI void         elm_fileselector_button_path_set(Evas_Object *obj, const char *path);
+   EAPI const char  *elm_fileselector_button_path_get(Evas_Object *obj);
+   EAPI void         elm_fileselector_button_expandable_set(Evas_Object *obj, Eina_Bool value);
+   EAPI Eina_Bool    elm_fileselector_button_expandable_get(Evas_Object *obj);
+   EAPI void         elm_fileselector_button_folder_only_set(Evas_Object *obj, Eina_Bool value);
+   EAPI Eina_Bool    elm_fileselector_button_folder_only_get(Evas_Object *obj);
+   EAPI void         elm_fileselector_button_is_save_set(Evas_Object *obj, Eina_Bool value);
+   EAPI Eina_Bool    elm_fileselector_button_is_save_get(Evas_Object *obj);
+   EAPI void         elm_fileselector_button_inwin_mode_set(Evas_Object *obj, Eina_Bool value);
+   EAPI Eina_Bool    elm_fileselector_button_inwin_mode_get(Evas_Object *obj);
+   EAPI void         elm_fileselector_button_selected_set(Evas_Object *obj, const char *path);
+   EAPI const char  *elm_fileselector_button_selected_get(const Evas_Object *obj);
+
+   /* available styles:
+    * default
+    * anchor
+    * hoversel_vertical
+    * hoversel_vertical_entry
+    */
+   /* smart callbacks called:
+    * "clicked" - the user clicked the button
+    * "repeated" - the user pressed the button without releasing it
+    * "unpressed" - when the button is unpressed (released)
+    */
+
+   typedef enum _Elm_Scroller_Policy
+     {
+       ELM_SCROLLER_POLICY_AUTO = 0,
+       ELM_SCROLLER_POLICY_ON,
+       ELM_SCROLLER_POLICY_OFF,
+       ELM_SCROLLER_POLICY_LAST
+     }
+   Elm_Scroller_Policy;
+
+   EAPI Evas_Object *elm_scroller_add(Evas_Object *parent);
+   EAPI void         elm_scroller_content_set(Evas_Object *obj, Evas_Object *child);
+   EAPI void         elm_scroller_custom_widget_base_theme_set(Evas_Object *obj, const char *widget, const char *base);
+   EAPI void         elm_scroller_content_min_limit(Evas_Object *obj, Eina_Bool w, Eina_Bool h);
+   EAPI void         elm_scroller_region_show(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
+   EAPI void         elm_scroller_policy_set(Evas_Object *obj, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v);
+   EAPI void         elm_scroller_policy_get(const Evas_Object *obj, Elm_Scroller_Policy *policy_h, Elm_Scroller_Policy *policy_v);
+   EAPI void         elm_scroller_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
+   EAPI void         elm_scroller_child_size_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h);
+   EAPI void         elm_scroller_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce);
+   EAPI void         elm_scroller_page_relative_set(Evas_Object *obj, double h_pagerel, double v_pagerel);
+   EAPI void         elm_scroller_page_size_set(Evas_Object *obj, Evas_Coord h_pagesize, Evas_Coord v_pagesize);
+   EAPI void         elm_scroller_region_bring_in(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
+   /* smart callbacks called:
+    * "edge,left"
+    * "edge,right"
+    * "edge,top"
+    * "edge,bottom"
+    * "scroll"
+    * "scroll,anim,start"
+    * "scroll,anim,stop"
+    * "scroll,drag,start"
+    * "scroll,drag,stop"
+    */
+
+   EAPI Evas_Object *elm_label_add(Evas_Object *parent);
+   EAPI void         elm_label_label_set(Evas_Object *obj, const char *label);
+   EAPI const char  *elm_label_label_get(const Evas_Object *obj);
+   EAPI void         elm_label_line_wrap_set(Evas_Object *obj, Eina_Bool wrap);
+   EAPI Eina_Bool    elm_label_line_wrap_get(const Evas_Object *obj);
+   EAPI void         elm_label_wrap_width_set(Evas_Object *obj, Evas_Coord w);
+   EAPI Evas_Coord   elm_label_wrap_width_get(const Evas_Object *obj);
+   /* available styles:
+    * default
+    * marker
+    */
+   /* smart callbacks called:
+    */
+
+   EAPI Evas_Object *elm_toggle_add(Evas_Object *parent);
+   EAPI void         elm_toggle_label_set(Evas_Object *obj, const char *label);
+   EAPI const char  *elm_toggle_label_get(const Evas_Object *obj);
+   EAPI void         elm_toggle_icon_set(Evas_Object *obj, Evas_Object *icon);
+   EAPI Evas_Object *elm_toggle_icon_get(const Evas_Object *obj);
+   EAPI void         elm_toggle_states_labels_set(Evas_Object *obj, const char *onlabel, const char *offlabel);
+   EAPI void         elm_toggle_states_labels_get(const Evas_Object *obj, const char **onlabel, const char **offlabel);
+   EAPI void         elm_toggle_state_set(Evas_Object *obj, Eina_Bool state);
+   EAPI Eina_Bool    elm_toggle_state_get(const Evas_Object *obj);
+   EAPI void         elm_toggle_state_pointer_set(Evas_Object *obj, Eina_Bool *statep);
+   /* smart callbacks called:
+    * "changed" - the user toggled the state
+    */
+
+   EAPI Evas_Object *elm_frame_add(Evas_Object *parent);
+   EAPI void         elm_frame_label_set(Evas_Object *obj, const char *label);
+   EAPI const char  *elm_frame_label_get(const Evas_Object *obj);
+   EAPI void         elm_frame_content_set(Evas_Object *obj, Evas_Object *content);
+   /* available styles:
+    * default
+    * pad_small
+    * pad_medium
+    * pad_large
+    * pad_huge
+    * outdent_top
+    * outdent_bottom
+    */
+   /* smart callbacks called:
+    */
+
+   EAPI Evas_Object *elm_table_add(Evas_Object *parent);
+   EAPI void         elm_table_homogenous_set(Evas_Object *obj, Eina_Bool homogenous);
+   EAPI void        elm_table_padding_set(Evas_Object *obj, Evas_Coord horizontal, Evas_Coord vertical);
+   EAPI void         elm_table_pack(Evas_Object *obj, Evas_Object *subobj, int x, int y, int w, int h);
+   EAPI void         elm_table_unpack(Evas_Object *obj, Evas_Object *subobj);
+   EAPI void         elm_table_clear(Evas_Object *obj, Eina_Bool clear);
+       
+   typedef struct _Elm_Grid_Cell_Class Elm_Grid_Cell_Class;
+   typedef struct _Elm_Grid_Cell_Class_Func Elm_Grid_Cell_Class_Func;
+   typedef struct _Elm_Grid_Cell Elm_Grid_Cell;
+   typedef char        *(*GridCellLabelGetFunc) (const void *data, Evas_Object *obj, const char *part);
+   typedef Evas_Object *(*GridCellIconGetFunc)  (const void *data, Evas_Object *obj, const char *part);
+   typedef Eina_Bool    (*GridCellStateGetFunc) (const void *data, Evas_Object *obj, const char *part);
+   typedef void         (*GridCellDelFunc)      (const void *data, Evas_Object *obj);
+
+   struct _Elm_Grid_Cell_Class
+     {
+       const char *item_style;
+       struct _Elm_Grid_Cell_Class_Func
+          {
+            GridCellLabelGetFunc label_get;
+            GridCellIconGetFunc icon_get;
+            GridCellStateGetFunc state_get;
+            GridCellDelFunc del;
+         } func;
+     };
+
+   EAPI Evas_Object *elm_scrolled_grid_add(Evas_Object *parent);
+   EAPI void        elm_scrolled_grid_cell_size_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
+   EAPI void        elm_scrolled_grid_cell_size_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h);
+   EAPI void         elm_scrolled_grid_align_set(Evas_Object *obj, double align_x, double align_y);
+   EAPI void         elm_scrolled_grid_align_get(const Evas_Object *obj, double *align_x, double *align_y);
+   EAPI void        elm_scrolled_grid_cell_del(Elm_Grid_Cell *cell);
+   EAPI void        elm_scrolled_grid_always_select_mode_set(Evas_Object *obj, Eina_Bool always_select);
+   EAPI Eina_Bool    elm_scrolled_grid_always_select_mode_get(const Evas_Object *obj);
+   EAPI void        elm_scrolled_grid_no_select_mode_set(Evas_Object *obj, Eina_Bool no_select);
+   EAPI Eina_Bool    elm_scrolled_grid_no_select_mode_get(const Evas_Object *obj);
+   EAPI void        elm_scrolled_grid_multi_select_set(Evas_Object *obj, Eina_Bool multi);
+   EAPI Eina_Bool    elm_scrolled_grid_multi_select_get(const Evas_Object *obj);
+   EAPI void        elm_scrolled_grid_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce);
+   EAPI void        elm_scrolled_grid_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce);
+   EAPI void        elm_scrolled_grid_horizontal_set(Evas_Object *obj, Eina_Bool setting);
+   EAPI void        elm_scrolled_grid_clear(Evas_Object *obj);
+   EAPI void       *elm_scrolled_grid_cell_data_get(Elm_Grid_Cell *cell);
+   EAPI void        elm_scrolled_grid_cell_pos_get(const Elm_Grid_Cell *cell, unsigned int *x, unsigned int *y);
+   EAPI Eina_Bool    elm_scrolled_grid_cell_selected_get(const Elm_Grid_Cell *cell);
+   EAPI const Evas_Object *elm_scrolled_grid_cell_object_get(Elm_Grid_Cell *cell);
+   EAPI const Eina_List *elm_scrolled_grid_selected_cells_get(const Evas_Object *obj);
+   EAPI Elm_Grid_Cell *elm_scrolled_grid_cell_add(Evas_Object *obj, const Elm_Grid_Cell_Class *gcc,  const void *data, Evas_Smart_Cb func, const void *func_data);
+   /* smart callbacks called:
+    *
+    * selected - User has selected a cell.
+    * unselected - User has unselected a cell.
+    * clicked - User has double-clicked a cell.
+    * realized - An evas object for a cell was built.
+    * scroll - the content has been scrolled (moved).
+    * "scroll,drag,start" - dragging the contents around has started.
+    * "scroll,drat,stop" - dragging the contents around has stopped.
+    * drag - grid is being dragged.
+    * "drag,start,up" - grid has been dragged (not scrolled) up.
+    * "drag,start,down" - grid has been dragged (not scrolled) down.
+    * "drag,start,left" - grid has been dragged (not scrolled) left.
+    * "drag,start,rigth" - grid has been dragged (nto scrolled) right.
+    * "drag,stop" - grid is not being dragged.
+    */
+
+   EAPI Evas_Object *elm_clock_add(Evas_Object *parent);
+   EAPI void         elm_clock_time_set(Evas_Object *obj, int hrs, int min, int sec);
+   EAPI void         elm_clock_time_get(const Evas_Object *obj, int *hrs, int *min, int *sec);
+   EAPI void         elm_clock_edit_set(Evas_Object *obj, Eina_Bool edit);
+   EAPI Eina_Bool    elm_clock_edit_get(const Evas_Object *obj);
+   EAPI void        elm_clock_digit_edit_set(Evas_Object *obj, unsigned int digedit);
+   EAPI unsigned int elm_clock_digit_edit_get(const Evas_Object *obj);
+   EAPI void         elm_clock_show_am_pm_set(Evas_Object *obj, Eina_Bool am_pm);
+   EAPI Eina_Bool    elm_clock_show_am_pm_get(const Evas_Object *obj);
+   EAPI void         elm_clock_show_seconds_set(Evas_Object *obj, Eina_Bool seconds);
+   EAPI Eina_Bool    elm_clock_show_seconds_get(const Evas_Object *obj);
+   /* smart callbacks called:
+    * "changed" - the user changed the time
+    */
+
+   EAPI Evas_Object *elm_layout_add(Evas_Object *parent);
+   EAPI Eina_Bool    elm_layout_file_set(Evas_Object *obj, const char *file, const char *group);
+   EAPI Eina_Bool    elm_layout_theme_set(Evas_Object *obj, const char *clas, const char *group, const char *style);
+   EAPI void         elm_layout_content_set(Evas_Object *obj, const char *swallow, Evas_Object *content);
+   EAPI Evas_Object *elm_layout_edje_get(const Evas_Object *obj);
+   EAPI void         elm_layout_sizing_eval(Evas_Object *obj);
+   /* smart callbacks called:
+    */
+
+   typedef enum _Elm_Notify_Orient
+     {
+        ELM_NOTIFY_ORIENT_TOP,
+        ELM_NOTIFY_ORIENT_CENTER,
+        ELM_NOTIFY_ORIENT_BOTTOM,
+        ELM_NOTIFY_ORIENT_LEFT,
+        ELM_NOTIFY_ORIENT_RIGHT,
+        ELM_NOTIFY_ORIENT_TOP_LEFT,
+        ELM_NOTIFY_ORIENT_TOP_RIGHT,
+        ELM_NOTIFY_ORIENT_BOTTOM_LEFT,
+        ELM_NOTIFY_ORIENT_BOTTOM_RIGHT
+     } Elm_Notify_Orient;
+   EAPI Evas_Object *elm_notify_add(Evas_Object *parent);
+   EAPI void         elm_notify_content_set(Evas_Object *obj, Evas_Object *content);
+   EAPI void        elm_notify_parent_set(Evas_Object *obj, Evas_Object *parent);
+   EAPI void        elm_notify_orient_set(Evas_Object *obj, Elm_Notify_Orient orient);
+   EAPI void         elm_notify_timeout_set(Evas_Object *obj, int timeout);
+   EAPI void        elm_notify_timer_init(Evas_Object *obj);
+   EAPI void        elm_notify_repeat_events_set(Evas_Object *obj, Eina_Bool repeat);
+   /* smart callbacks called:
+    */
+   
+   typedef enum _Elm_Hover_Axis
+     {
+       ELM_HOVER_AXIS_NONE,
+         ELM_HOVER_AXIS_HORIZONTAL,
+         ELM_HOVER_AXIS_VERTICAL,
+         ELM_HOVER_AXIS_BOTH
+     } Elm_Hover_Axis;
+   EAPI Evas_Object *elm_hover_add(Evas_Object *parent);
+   EAPI void         elm_hover_target_set(Evas_Object *obj, Evas_Object *target);
+   EAPI Evas_Object *elm_hover_target_get(Evas_Object *obj);
+   EAPI void         elm_hover_parent_set(Evas_Object *obj, Evas_Object *parent);
+   EAPI Evas_Object *elm_hover_parent_get(Evas_Object *obj);
+   EAPI void         elm_hover_content_set(Evas_Object *obj, const char *swallow, Evas_Object *content);
+   EAPI const char  *elm_hover_best_content_location_get(const Evas_Object *obj, Elm_Hover_Axis pref_axis);
+   /* available styles:
+    * default
+    * popout
+    * menu
+    * hoversel_vertical
+    */
+   /* smart callbacks called:
+    * "clicked" - the user clicked the empty space in the hover to dismiss
+    */
+
+   typedef struct _Elm_Entry_Anchor_Info Elm_Entry_Anchor_Info;
+   struct _Elm_Entry_Anchor_Info
+     {
+       const char *name;
+       int button;
+       Evas_Coord x, y, w, h;
+     };
+   typedef enum _Elm_Icon_Type
+     {
+       ELM_ICON_NONE,
+         ELM_ICON_FILE,
+         ELM_ICON_STANDARD
+     } Elm_Icon_Type;
+   typedef struct _Elm_Hoversel_Item Elm_Hoversel_Item;
+   EAPI Evas_Object *elm_entry_add(Evas_Object *parent);
+   EAPI void         elm_entry_single_line_set(Evas_Object *obj, Eina_Bool single_line);
+   EAPI Eina_Bool    elm_entry_single_line_get(const Evas_Object *obj);
+   EAPI void         elm_entry_password_set(Evas_Object *obj, Eina_Bool password);
+   EAPI Eina_Bool    elm_entry_password_get(const Evas_Object *obj);
+   EAPI void         elm_entry_entry_set(Evas_Object *obj, const char *entry);
+   EAPI const char  *elm_entry_entry_get(const Evas_Object *obj);
+   EAPI const char  *elm_entry_selection_get(const Evas_Object *obj);
+   EAPI void         elm_entry_entry_insert(Evas_Object *obj, const char *entry);
+   EAPI void         elm_entry_line_wrap_set(Evas_Object *obj, Eina_Bool wrap);
+   EAPI void         elm_entry_line_char_wrap_set(Evas_Object *obj, Eina_Bool wrap);
+   EAPI void         elm_entry_editable_set(Evas_Object *obj, Eina_Bool editable);
+   EAPI Eina_Bool    elm_entry_editable_get(const Evas_Object *obj);
+   EAPI void         elm_entry_select_none(Evas_Object *obj);
+   EAPI void         elm_entry_select_all(Evas_Object *obj);
+   EAPI Eina_Bool    elm_entry_cursor_next(Evas_Object *obj);
+   EAPI Eina_Bool    elm_entry_cursor_prev(Evas_Object *obj);
+   EAPI Eina_Bool    elm_entry_cursor_up(Evas_Object *obj);
+   EAPI Eina_Bool    elm_entry_cursor_down(Evas_Object *obj);
+   EAPI void         elm_entry_cursor_begin_set(Evas_Object *obj);
+   EAPI void         elm_entry_cursor_end_set(Evas_Object *obj);
+   EAPI void         elm_entry_cursor_line_begin_set(Evas_Object *obj);
+   EAPI void         elm_entry_cursor_line_end_set(Evas_Object *obj);
+   EAPI void         elm_entry_cursor_selection_begin(Evas_Object *obj);
+   EAPI void         elm_entry_cursor_selection_end(Evas_Object *obj);
+   EAPI Eina_Bool    elm_entry_cursor_is_format_get(const Evas_Object *obj);
+   EAPI Eina_Bool    elm_entry_cursor_is_visible_format_get(const Evas_Object *obj);
+   EAPI const char  *elm_entry_cursor_content_get(const Evas_Object *obj);
+   EAPI void         elm_entry_selection_cut(Evas_Object *obj);
+   EAPI void         elm_entry_selection_copy(Evas_Object *obj);
+   EAPI void         elm_entry_selection_paste(Evas_Object *obj);
+   EAPI void         elm_entry_context_menu_clear(Evas_Object *obj);
+   EAPI void         elm_entry_context_menu_item_add(Evas_Object *obj, const char *label, const char *icon_file, Elm_Icon_Type icon_type, Evas_Smart_Cb func, const void *data);
+   EAPI void         elm_entry_context_menu_disabled_set(Evas_Object *obj, Eina_Bool disabled);
+   EAPI Eina_Bool    elm_entry_context_menu_disabled_get(const Evas_Object *obj);
+   EAPI void         elm_entry_item_provider_append(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *entry, const char *item), void *data);
+   EAPI void         elm_entry_item_provider_prepend(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *entry, const char *item), void *data);
+   EAPI void         elm_entry_item_provider_remove(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *entry, const char *item), void *data);
+   EAPI char        *elm_entry_markup_to_utf8(const char *s);
+   EAPI char        *elm_entry_utf8_to_markup(const char *s);
+   /* smart callbacks called:
+    * "changed" - the text content changed
+    * "selection,start" - the user started selecting text
+    * "selection,changed" - the user modified the selection size/location
+    * "selection,cleared" - the user cleared the selection
+    * "selection,paste" - the user requested a paste of text
+    * "selection,copy" - the user copied the text
+    * "selection,cut" - the user cut the text
+    * "cursor,changed" - the cursor changed position
+    * "anchor,clicked" - achor called was clicked | event_info = Elm_Entry_Anchor_Info
+    * "activated" - when the enter key is pressed (useful for single line)
+    * "press" - when finger/mouse is pressed down
+    * "clicked" - when finger/mouse is pressed and released (without a drag etc.)
+    * "clicked,double" - when finger/mouse is double-pressed
+    * "longpressed" - the entry has been longpressed
+    * "focused" - the entry has received keyboard focus
+    * "unfocused" - keyboard focus is gone
+    */
+
+   /* composite widgets - these basically put together basic widgets above
+    * in convenient packages that do more than basic stuff */
+   typedef enum _Elm_Text_Format
+     {
+       ELM_TEXT_FORMAT_PLAIN_UTF8,
+       ELM_TEXT_FORMAT_MARKUP_UTF8
+     } Elm_Text_Format;
+   EAPI Evas_Object *elm_notepad_add(Evas_Object *parent);
+   EAPI void         elm_notepad_file_set(Evas_Object *obj, const char *file, Elm_Text_Format format);
+   EAPI void         elm_notepad_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce);
+   /* smart callbacks called:
+    */
+
+   typedef struct _Elm_Entry_Anchorview_Info Elm_Entry_Anchorview_Info;
+   struct _Elm_Entry_Anchorview_Info
+     {
+       const char *name;
+       int button;
+       Evas_Object *hover;
+       struct
+          {
+             Evas_Coord x, y, w, h;
+         } anchor, hover_parent;
+       Eina_Bool hover_left : 1;
+       Eina_Bool hover_right : 1;
+       Eina_Bool hover_top : 1;
+       Eina_Bool hover_bottom : 1;
+     };
+   EAPI Evas_Object *elm_anchorview_add(Evas_Object *parent);
+   EAPI void         elm_anchorview_text_set(Evas_Object *obj, const char *text);
+   EAPI const char  *elm_anchorview_text_get(const Evas_Object *obj);
+
+   EAPI void         elm_anchorview_hover_parent_set(Evas_Object *obj, Evas_Object *parent);
+   EAPI void         elm_anchorview_hover_style_set(Evas_Object *obj, const char *style);
+   EAPI void         elm_anchorview_hover_end(Evas_Object *obj);
+   EAPI void         elm_anchorview_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce);
+   EAPI void         elm_anchorview_item_provider_append(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorview, const char *item), void *data);
+   EAPI void         elm_anchorview_item_provider_prepend(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorview, const char *item), void *data);
+   EAPI void         elm_anchorview_item_provider_remove(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorview, const char *item), void *data);
+   /* smart callbacks called:
+    * "anchor,clicked" - achor called was clicked | event_info = Elm_Entry_Anchorview_Info
+    */
+
+   typedef struct _Elm_Entry_Anchorblock_Info Elm_Entry_Anchorblock_Info;
+   struct _Elm_Entry_Anchorblock_Info
+     {
+       const char *name;
+       int button;
+       Evas_Object *hover;
+       struct
+          {
+            Evas_Coord x, y, w, h;
+         } anchor, hover_parent;
+       Eina_Bool hover_left : 1;
+       Eina_Bool hover_right : 1;
+       Eina_Bool hover_top : 1;
+       Eina_Bool hover_bottom : 1;
+     };
+   EAPI Evas_Object *elm_anchorblock_add(Evas_Object *parent);
+   EAPI void         elm_anchorblock_text_set(Evas_Object *obj, const char *text);
+   EAPI const char  *elm_anchorblock_text_get(const Evas_Object *obj);
+   EAPI void         elm_anchorblock_hover_parent_set(Evas_Object *obj, Evas_Object *parent);
+   EAPI void         elm_anchorblock_hover_style_set(Evas_Object *obj, const char *style);
+   EAPI void         elm_anchorblock_hover_end(Evas_Object *obj);
+   EAPI void         elm_anchorblock_item_provider_append(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorblock, const char *item), void *data);
+   EAPI void         elm_anchorblock_item_provider_prepend(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorblock, const char *item), void *data);
+   EAPI void         elm_anchorblock_item_provider_remove(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorblock, const char *item), void *data);
+   /* smart callbacks called:
+    * "anchor,clicked" - achor called was clicked | event_info = Elm_Entry_Anchorblock_Info
+    */
+
+   EAPI Evas_Object *elm_bubble_add(Evas_Object *parent);
+   EAPI void         elm_bubble_label_set(Evas_Object *obj, const char *label);
+   EAPI const char  *elm_bubble_label_get(const Evas_Object *obj);
+   EAPI void         elm_bubble_info_set(Evas_Object *obj, const char *info);
+   EAPI const char  *elm_bubble_info_get(const Evas_Object *obj);
+
+   EAPI void         elm_bubble_content_set(Evas_Object *obj, Evas_Object *content);
+   EAPI void         elm_bubble_icon_set(Evas_Object *obj, Evas_Object *icon);
+   EAPI Evas_Object *elm_bubble_icon_get(const Evas_Object *obj);
+   EAPI void         elm_bubble_corner_set(Evas_Object *obj, const char *corner);
+   /* smart callbacks called:
+    */
+
+   EAPI Evas_Object *elm_photo_add(Evas_Object *parent);
+   EAPI Eina_Bool    elm_photo_file_set(Evas_Object *obj, const char *file);
+   EAPI void         elm_photo_size_set(Evas_Object *obj, int size);
+   /* smart callbacks called:
+    * "clicked" - the user clicked the icon
+    */
+
+   EAPI Evas_Object *elm_thumb_add(Evas_Object *parent);
+   EAPI void        elm_thumb_file_set(Evas_Object *obj, const char *file, const char *key);
+   EAPI void        elm_thumb_file_get(const Evas_Object *obj, const char **file, const char **key);
+   EAPI void        elm_thumb_keep_aspect_set(Evas_Object *obj, Eina_Bool setting);
+   EAPI Eina_Bool    elm_thumb_keep_aspect_get(const Evas_Object *obj);
+   EAPI void        elm_thumb_align_set(Evas_Object *obj, float x_align, float y_align);
+   EAPI void        elm_thumb_align_get(const Evas_Object *obj, float *x, float *y);
+   EAPI void        elm_thumb_animate_set(Evas_Object *obj, Elm_Thumb_Animation_Setting s);
+   EAPI Elm_Thumb_Animation_Setting elm_thumb_animate_get(const Evas_Object *obj);
+   EAPI Eina_Bool    elm_thumb_ethumb_client_connected(void);
+#ifdef ELM_ETHUMB
+   EAPI Ethumb_Client *elm_thumb_ethumb_client_get(void);
+#else
+   EAPI void       *elm_thumb_ethumb_client_get(void);
+#endif
+   /* smart callbacks called:
+    * "clicked" - the user clicked the thumb
+    * "clicked,double" - the user double clicked the thumb
+    * "press" - the user pressed the thumb
+    * "generate,start" - the thumbnail generation started
+    * "generate,stop" - the thumbnail generation stopped
+    * "generate,error" - the thumbnail generation failed
+    * "load,error" - the thumbnail image loading failed
+    */
+
+   EAPI Evas_Object *elm_hoversel_add(Evas_Object *parent);
+   EAPI void         elm_hoversel_horizontal_set(Evas_Object *obj, Eina_Bool horizontal);
+   EAPI Eina_Bool    elm_hoversel_horizontal_get(const Evas_Object *obj);
+   EAPI void         elm_hoversel_hover_parent_set(Evas_Object *obj, Evas_Object *parent);
+   EAPI void         elm_hoversel_label_set(Evas_Object *obj, const char *label);
+   EAPI const char  *elm_hoversel_label_get(const Evas_Object *obj);
+   EAPI void         elm_hoversel_icon_set(Evas_Object *obj, Evas_Object *icon);
+   EAPI Evas_Object *elm_hoversel_icon_get(const Evas_Object *obj);
+   EAPI void         elm_hoversel_hover_begin(Evas_Object *obj);
+   EAPI void         elm_hoversel_hover_end(Evas_Object *obj);
+   EAPI Eina_Bool    elm_hoversel_expanded_get(Evas_Object *obj);
+   EAPI void         elm_hoversel_clear(Evas_Object *obj);
+   EAPI const Eina_List * elm_hoversel_items_get(const Evas_Object *obj);
+   EAPI Elm_Hoversel_Item *elm_hoversel_item_add(Evas_Object *obj, const char *label, const char *icon_file, Elm_Icon_Type icon_type, Evas_Smart_Cb func, const void *data);
+   EAPI void         elm_hoversel_item_del(Elm_Hoversel_Item *item);
+   EAPI void         elm_hoversel_item_del_cb_set(Elm_Hoversel_Item *it, Evas_Smart_Cb func);
+   EAPI void        *elm_hoversel_item_data_get(Elm_Hoversel_Item *it);
+   EAPI const char  *elm_hoversel_item_label_get(Elm_Hoversel_Item *it);
+   EAPI void         elm_hoversel_item_icon_set(Elm_Hoversel_Item *it, const char *icon_file, const char *icon_group, Elm_Icon_Type icon_type);
+   EAPI void         elm_hoversel_item_icon_get(Elm_Hoversel_Item *it, const char **icon_file, const char **icon_group, Elm_Icon_Type *icon_type);
+   /* smart callbacks called:
+    * "clicked" - the user clicked the hoversel button and popped up the sel
+    * "selected" - an item in the hoversel list is selected
+    * "dismissed" - the hover is dismissed
+    */
+
+   typedef struct _Elm_Toolbar_Item Elm_Toolbar_Item;
+   EAPI Evas_Object      *elm_toolbar_add(Evas_Object *parent);
+   EAPI void              elm_toolbar_icon_size_set(Evas_Object *obj, int icon_size);
+   EAPI int               elm_toolbar_icon_size_get(const Evas_Object *obj);
+   EAPI Elm_Toolbar_Item *elm_toolbar_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, Evas_Smart_Cb func, const void *data);
+   EAPI Evas_Object      *elm_toolbar_item_icon_get(Elm_Toolbar_Item *item);
+   EAPI const char       *elm_toolbar_item_label_get(const Elm_Toolbar_Item *item);
+   EAPI Eina_Bool         elm_toolbar_item_selected_get(const Elm_Toolbar_Item *item);
+   EAPI void              elm_toolbar_item_label_set(Elm_Toolbar_Item *item, const char *label);
+   EAPI void              elm_toolbar_item_del(Elm_Toolbar_Item *item);
+   EAPI void              elm_toolbar_item_del_cb_set(Elm_Toolbar_Item *it, Evas_Smart_Cb func);
+   EAPI void              elm_toolbar_item_select(Elm_Toolbar_Item *item);
+   EAPI Eina_Bool         elm_toolbar_item_disabled_get(Elm_Toolbar_Item *item);
+   EAPI void              elm_toolbar_item_disabled_set(Elm_Toolbar_Item *item, Eina_Bool disabled);
+   EAPI void              elm_toolbar_item_separator_set(Elm_Toolbar_Item *item, Eina_Bool separator);
+   EAPI Eina_Bool         elm_toolbar_item_separator_get(Elm_Toolbar_Item *item);
+   EAPI Eina_List        *elm_toolbar_item_get_all(Evas_Object *obj);
+   EAPI Elm_Toolbar_Item *elm_toolbar_item_get_first(Evas_Object *obj);
+   EAPI Elm_Toolbar_Item *elm_toolbar_item_get_last(Evas_Object *obj);
+   EAPI Elm_Toolbar_Item *elm_toolbar_item_get_next(Evas_Object *obj);
+   EAPI Elm_Toolbar_Item *elm_toolbar_item_select_next(Evas_Object *obj);
+   EAPI Elm_Toolbar_Item *elm_toolbar_item_select_first(Evas_Object *obj);
+   EAPI Elm_Toolbar_Item *elm_toolbar_item_select_last(Evas_Object *obj);
+   EAPI Elm_Toolbar_Item *elm_toolbar_item_find_by_label(Evas_Object *obj, const char *label);
+   EAPI void              elm_toolbar_scrollable_set(Evas_Object *obj, Eina_Bool scrollable);
+   EAPI Eina_Bool         elm_toolbar_scrollable_get(Evas_Object *obj);
+   EAPI void             elm_toolbar_homogenous_set(Evas_Object *obj, Eina_Bool homogenous);
+   EAPI Eina_Bool         elm_toolbar_homogenous_get(Evas_Object *obj);
+   EAPI void             elm_toolbar_menu_parent_set(Evas_Object *obj, Evas_Object *parent);
+   EAPI Evas_Object      *elm_toolbar_menu_parent_get(Evas_Object *obj);
+   EAPI void              elm_toolbar_item_unselect_all(Evas_Object *obj);
+   EAPI void              elm_toolbar_align_set(Evas_Object *obj, double align);
+   EAPI double            elm_toolbar_align_get(const Evas_Object *obj);
+   EAPI void             elm_toolbar_item_menu_set(Elm_Toolbar_Item *item, Eina_Bool menu);
+   EAPI Evas_Object      *elm_toolbar_item_menu_get(Elm_Toolbar_Item *item);
+   /* smart callbacks called:
+    * "clicked" - when the user clicks on a toolbar item and becomes selected
+    */
+
+   typedef struct _Menu_Item Elm_Menu_Item;
+   EAPI Evas_Object     *elm_menu_add(Evas_Object *parent);
+   EAPI void            elm_menu_parent_set(Evas_Object *obj, Evas_Object *parent);
+   EAPI void            elm_menu_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+   EAPI Evas_Object     *elm_menu_object_get(const Elm_Menu_Item *it);
+   EAPI Elm_Menu_Item   *elm_menu_item_add(Evas_Object *obj, Elm_Menu_Item *parent, Evas_Object *icon, const char *label, Evas_Smart_Cb func, const void *data);
+   EAPI void            elm_menu_item_label_set(Elm_Menu_Item *item, const char *label);
+   EAPI const char      *elm_menu_item_label_get(Elm_Menu_Item *item);
+   EAPI void            elm_menu_item_icon_set(Elm_Menu_Item *item, Evas_Object *icon);
+   EAPI Evas_Object     *elm_menu_item_icon_get(Elm_Menu_Item *item);
+   EAPI void            elm_menu_item_disabled_set(Elm_Menu_Item *item, Eina_Bool disabled);
+   EAPI Eina_Bool        elm_menu_item_disabled_get(Elm_Menu_Item *item);
+   EAPI Elm_Menu_Item   *elm_menu_item_separator_add(Evas_Object *obj, Elm_Menu_Item *parent);
+   EAPI Eina_Bool        elm_menu_item_is_separator(Elm_Menu_Item *item);
+   EAPI void            elm_menu_item_del(Elm_Menu_Item *item);
+   EAPI void            elm_menu_item_del_cb_set(Elm_Menu_Item *it, Evas_Smart_Cb func);
+   EAPI void           *elm_menu_item_data_get(const Elm_Menu_Item *it);
+   EAPI void            elm_menu_item_data_set(Elm_Menu_Item *item, const void *data);
+   EAPI const Eina_List *elm_menu_item_subitems_get(Elm_Menu_Item *item);
+   /* smart callbacks called:
+    * "clicked" - the user clicked the empty space in the menu to dismiss. event_info is NULL.
+    */
+
+   typedef enum _Elm_List_Mode
+     {
+       ELM_LIST_COMPRESS = 0,
+       ELM_LIST_SCROLL,
+       ELM_LIST_LIMIT,
+       ELM_LIST_LAST
+     } Elm_List_Mode;
+   typedef struct _Elm_List_Item Elm_List_Item;
+   EAPI Evas_Object     *elm_list_add(Evas_Object *parent);
+   EAPI Elm_List_Item   *elm_list_item_append(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data);
+   EAPI Elm_List_Item   *elm_list_item_prepend(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data);
+   EAPI Elm_List_Item   *elm_list_item_insert_before(Evas_Object *obj, Elm_List_Item *before, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data);
+   EAPI Elm_List_Item   *elm_list_item_insert_after(Evas_Object *obj, Elm_List_Item *after, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data);
+   EAPI Elm_List_Item   *elm_list_item_sorted_insert(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data, Eina_Compare_Cb cmp_func);
+   EAPI void             elm_list_clear(Evas_Object *obj);
+   EAPI void             elm_list_go(Evas_Object *obj);
+   EAPI void             elm_list_multi_select_set(Evas_Object *obj, Eina_Bool multi);
+   EAPI Eina_Bool       elm_list_multi_select_get(const Evas_Object *obj);
+   EAPI void             elm_list_horizontal_mode_set(Evas_Object *obj, Elm_List_Mode mode);
+   EAPI Elm_List_Mode   elm_list_horizontal_mode_get(const Evas_Object *obj);
+   EAPI void             elm_list_always_select_mode_set(Evas_Object *obj, Eina_Bool always_select);
+   EAPI Eina_Bool       elm_list_always_select_mode_get(const Evas_Object *obj);
+   EAPI const Eina_List *elm_list_items_get(const Evas_Object *obj);
+   EAPI Elm_List_Item   *elm_list_selected_item_get(const Evas_Object *obj);
+   EAPI const Eina_List *elm_list_selected_items_get(const Evas_Object *obj);
+   EAPI void             elm_list_item_selected_set(Elm_List_Item *item, Eina_Bool selected);
+   EAPI Eina_Bool        elm_list_item_selected_get(Elm_List_Item *item);
+   EAPI void             elm_list_item_show(Elm_List_Item *item);
+   EAPI void             elm_list_item_del(Elm_List_Item *item);
+   EAPI void             elm_list_item_del_cb_set(Elm_List_Item *item, Evas_Smart_Cb func);
+   EAPI void            *elm_list_item_data_get(const Elm_List_Item *item);
+   EAPI Evas_Object     *elm_list_item_icon_get(const Elm_List_Item *item);
+   EAPI void             elm_list_item_icon_set(Elm_List_Item *item, Evas_Object *icon);
+   EAPI Evas_Object     *elm_list_item_end_get(const Elm_List_Item *item);
+   EAPI void             elm_list_item_end_set(Elm_List_Item *item, Evas_Object *end);
+   EAPI Evas_Object     *elm_list_item_base_get(const Elm_List_Item *item);
+   EAPI const char      *elm_list_item_label_get(const Elm_List_Item *item);
+   EAPI void             elm_list_item_label_set(Elm_List_Item *item, const char *text);
+   EAPI Elm_List_Item   *elm_list_item_prev(const Elm_List_Item *it);
+   EAPI Elm_List_Item   *elm_list_item_next(const Elm_List_Item *it);
+   EAPI void             elm_list_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce);
+   EAPI void             elm_list_scroller_policy_set(Evas_Object *obj, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v);
+   EAPI void             elm_list_scroller_policy_get(const Evas_Object *obj, Elm_Scroller_Policy *policy_h, Elm_Scroller_Policy *policy_v);
+   /* smart callbacks called:
+    * "clicked" - when the user double-clicked an item
+    * "selected" - when the user selected an item
+    * "unselected" - when the user selected an item
+    * "longpressed" - an item in the hoversel list is long-pressed
+    */
+
+   // FIXME: incomplete - carousel. don't use this until this comment is removed
+   typedef struct _Elm_Carousel_Item Elm_Carousel_Item;
+   EAPI Evas_Object       *elm_carousel_add(Evas_Object *parent);
+   EAPI Elm_Carousel_Item *elm_carousel_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, Evas_Smart_Cb func, const void *data);
+   EAPI void               elm_carousel_item_del(Elm_Carousel_Item *item);
+   EAPI void               elm_carousel_item_select(Elm_Carousel_Item *item);
+   /* smart callbacks called:
+    * "clicked" - when the user clicks on a carousel item and becomes selected
+    */
+
+   EAPI Evas_Object *elm_slider_add(Evas_Object *parent);
+   EAPI void         elm_slider_label_set(Evas_Object *obj, const char *label);
+   EAPI const char  *elm_slider_label_get(const Evas_Object *obj);
+   EAPI void         elm_slider_icon_set(Evas_Object *obj, Evas_Object *icon);
+   EAPI Evas_Object *elm_slider_icon_get(const Evas_Object *obj);
+   EAPI void         elm_slider_span_size_set(Evas_Object *obj, Evas_Coord size);
+   EAPI Evas_Coord   elm_slider_span_size_get(const Evas_Object *obj);
+   EAPI void         elm_slider_unit_format_set(Evas_Object *obj, const char *format);
+   EAPI const char  *elm_slider_unit_format_get(const Evas_Object *obj);
+   EAPI void         elm_slider_indicator_format_set(Evas_Object *obj, const char *indicator);
+   EAPI const char  *elm_slider_indicator_format_get(const Evas_Object *obj);
+   EAPI void         elm_slider_indicator_format_function_set(Evas_Object *obj, const char *(*func)(double val));
+   EAPI void         elm_slider_horizontal_set(Evas_Object *obj, Eina_Bool horizontal);
+   EAPI Eina_Bool    elm_slider_horizontal_get(const Evas_Object *obj);
+   EAPI void         elm_slider_min_max_set(Evas_Object *obj, double min, double max);
+   EAPI void         elm_slider_min_max_get(const Evas_Object *obj, double *min, double *max);
+   EAPI void         elm_slider_value_set(Evas_Object *obj, double val);
+   EAPI double       elm_slider_value_get(const Evas_Object *obj);
+   EAPI void         elm_slider_inverted_set(Evas_Object *obj, Eina_Bool inverted);
+   EAPI Eina_Bool    elm_slider_inverted_get(const Evas_Object *obj);
+
+   typedef enum _Elm_Genlist_Item_Flags
+     {
+       ELM_GENLIST_ITEM_NONE = 0,
+       ELM_GENLIST_ITEM_SUBITEMS = (1 << 0)
+     } Elm_Genlist_Item_Flags;
+   typedef struct _Elm_Genlist_Item_Class Elm_Genlist_Item_Class;
+   typedef struct _Elm_Genlist_Item       Elm_Genlist_Item;
+   typedef struct _Elm_Genlist_Item_Class_Func Elm_Genlist_Item_Class_Func;
+   typedef char        *(*GenlistItemLabelGetFunc) (const void *data, Evas_Object *obj, const char *part);
+   typedef Evas_Object *(*GenlistItemIconGetFunc)  (const void *data, Evas_Object *obj, const char *part);
+   typedef Eina_Bool    (*GenlistItemStateGetFunc) (const void *data, Evas_Object *obj, const char *part);
+   typedef void         (*GenlistItemDelFunc)      (const void *data, Evas_Object *obj);
+
+   struct _Elm_Genlist_Item_Class
+     {
+       const char *item_style;
+       struct _Elm_Genlist_Item_Class_Func
+          {
+            GenlistItemLabelGetFunc label_get;
+            GenlistItemIconGetFunc icon_get;
+            GenlistItemStateGetFunc state_get;
+            GenlistItemDelFunc del;
+         } func;
+     };
+
+   EAPI Evas_Object      *elm_genlist_add(Evas_Object *parent);
+   EAPI void              elm_genlist_clear(Evas_Object *obj);
+   EAPI void              elm_genlist_multi_select_set(Evas_Object *obj, Eina_Bool multi);
+   EAPI Eina_Bool         elm_genlist_multi_select_get(const Evas_Object *obj);
+   EAPI void              elm_genlist_horizontal_mode_set(Evas_Object *obj, Elm_List_Mode mode);
+   EAPI Elm_List_Mode     elm_genlist_horizontal_mode_get(const Evas_Object *obj);
+   EAPI void              elm_genlist_always_select_mode_set(Evas_Object *obj, Eina_Bool always_select);
+   EAPI Eina_Bool         elm_genlist_always_select_mode_get(const Evas_Object *obj);
+   EAPI void              elm_genlist_no_select_mode_set(Evas_Object *obj, Eina_Bool no_select);
+   EAPI Eina_Bool         elm_genlist_no_select_mode_get(const Evas_Object *obj);
+   EAPI void              elm_genlist_compress_mode_set(Evas_Object *obj, Eina_Bool compress);
+   EAPI Eina_Bool         elm_genlist_compress_mode_get(const Evas_Object *obj);
+   EAPI void              elm_genlist_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce);
+   EAPI void              elm_genlist_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce);
+   EAPI void              elm_genlist_homogeneous_set(Evas_Object *obj, Eina_Bool homogeneous);
+   EAPI Eina_Bool         elm_genlist_homogeneous_get(const Evas_Object *obj);
+   EAPI void              elm_genlist_block_count_set(Evas_Object *obj, int n);
+   EAPI int               elm_genlist_block_count_get(const Evas_Object *obj);
+
+   /* operations to add items */
+   EAPI Elm_Genlist_Item *elm_genlist_item_append(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Genlist_Item *parent, Elm_Genlist_Item_Flags flags, Evas_Smart_Cb func, const void *func_data);
+   EAPI Elm_Genlist_Item *elm_genlist_item_prepend(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Genlist_Item *parent, Elm_Genlist_Item_Flags flags, Evas_Smart_Cb func, const void *func_data);
+   EAPI Elm_Genlist_Item *elm_genlist_item_insert_before(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Genlist_Item *before, Elm_Genlist_Item_Flags flags, Evas_Smart_Cb func, const void *func_data);
+   EAPI Elm_Genlist_Item *elm_genlist_item_insert_after(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Genlist_Item *after, Elm_Genlist_Item_Flags flags, Evas_Smart_Cb func, const void *func_data);
+   /* operations to retrieve existing items */
+   EAPI Elm_Genlist_Item *elm_genlist_selected_item_get(const Evas_Object *obj);
+   EAPI const Eina_List  *elm_genlist_selected_items_get(const Evas_Object *obj);
+   EAPI Eina_List        *elm_genlist_realized_items_get(const Evas_Object *obj);
+   EAPI Elm_Genlist_Item *elm_genlist_at_xy_item_get(const Evas_Object *obj, Evas_Coord x, Evas_Coord y, int *posret);
+   EAPI Elm_Genlist_Item *elm_genlist_first_item_get(const Evas_Object *obj);
+   EAPI Elm_Genlist_Item *elm_genlist_last_item_get(const Evas_Object *obj);
+   /* available item styles:
+    * default
+    * default_style - The text part is a textblock
+    * double_label
+    * icon_top_text_bottom
+    */
+
+   /* Genlist Item operation */
+   EAPI Elm_Genlist_Item *elm_genlist_item_next_get(const Elm_Genlist_Item *item);
+   EAPI Elm_Genlist_Item *elm_genlist_item_prev_get(const Elm_Genlist_Item *item);
+   EAPI Evas_Object      *elm_genlist_item_genlist_get(const Elm_Genlist_Item *item);
+   EAPI Elm_Genlist_Item *elm_genlist_item_parent_get(const Elm_Genlist_Item *it);
+   EAPI void              elm_genlist_item_subitems_clear(Elm_Genlist_Item *item);
+   EAPI void              elm_genlist_item_selected_set(Elm_Genlist_Item *item, Eina_Bool selected);
+   EAPI Eina_Bool         elm_genlist_item_selected_get(const Elm_Genlist_Item *item);
+   EAPI void              elm_genlist_item_expanded_set(Elm_Genlist_Item *item, Eina_Bool expanded);
+   EAPI Eina_Bool         elm_genlist_item_expanded_get(const Elm_Genlist_Item *item);
+   EAPI void              elm_genlist_item_disabled_set(Elm_Genlist_Item *item, Eina_Bool disabled);
+   EAPI Eina_Bool         elm_genlist_item_disabled_get(const Elm_Genlist_Item *item);
+   EAPI void              elm_genlist_item_display_only_set(Elm_Genlist_Item *it, Eina_Bool display_only);
+   EAPI Eina_Bool         elm_genlist_item_display_only_get(const Elm_Genlist_Item *it);
+   EAPI void              elm_genlist_item_show(Elm_Genlist_Item *item);
+   EAPI void              elm_genlist_item_bring_in(Elm_Genlist_Item *item);
+   EAPI void              elm_genlist_item_top_show(Elm_Genlist_Item *item);
+   EAPI void              elm_genlist_item_top_bring_in(Elm_Genlist_Item *item);
+   EAPI void             elm_genlist_item_middle_show(Elm_Genlist_Item *it);
+   EAPI void             elm_genlist_item_middle_bring_in(Elm_Genlist_Item *it);
+   EAPI void              elm_genlist_item_del(Elm_Genlist_Item *item);
+   EAPI const void       *elm_genlist_item_data_get(const Elm_Genlist_Item *item);
+   EAPI void              elm_genlist_item_data_set(Elm_Genlist_Item *it, const void *data);
+   EAPI const Evas_Object *elm_genlist_item_object_get(const Elm_Genlist_Item *it);
+   EAPI void              elm_genlist_item_update(Elm_Genlist_Item *item);
+
+   EAPI Evas_Object *elm_check_add(Evas_Object *parent);
+   EAPI void         elm_check_label_set(Evas_Object *obj, const char *label);
+   EAPI const char  *elm_check_label_get(const Evas_Object *obj);
+   EAPI void         elm_check_icon_set(Evas_Object *obj, Evas_Object *icon);
+   EAPI Evas_Object *elm_check_icon_get(const Evas_Object *obj);
+   EAPI void         elm_check_state_set(Evas_Object *obj, Eina_Bool state);
+   EAPI Eina_Bool    elm_check_state_get(const Evas_Object *obj);
+   EAPI void         elm_check_state_pointer_set(Evas_Object *obj, Eina_Bool *statep);
+
+   EAPI Evas_Object *elm_radio_add(Evas_Object *parent);
+   EAPI void         elm_radio_label_set(Evas_Object *obj, const char *label);
+   EAPI const char  *elm_radio_label_get(const Evas_Object *obj);
+   EAPI void         elm_radio_icon_set(Evas_Object *obj, Evas_Object *icon);
+   EAPI Evas_Object *elm_radio_icon_get(const Evas_Object *obj);
+   EAPI void         elm_radio_group_add(Evas_Object *obj, Evas_Object *group);
+   EAPI void         elm_radio_state_value_set(Evas_Object *obj, int value);
+   EAPI void         elm_radio_value_set(Evas_Object *obj, int value);
+   EAPI int          elm_radio_value_get(const Evas_Object *obj);
+   EAPI void         elm_radio_value_pointer_set(Evas_Object *obj, int *valuep);
+
+   EAPI Evas_Object *elm_pager_add(Evas_Object *parent);
+   EAPI void         elm_pager_content_push(Evas_Object *obj, Evas_Object *content);
+   EAPI void         elm_pager_content_pop(Evas_Object *obj);
+   EAPI void         elm_pager_content_promote(Evas_Object *obj, Evas_Object *content);
+   EAPI Evas_Object *elm_pager_content_bottom_get(const Evas_Object *obj);
+   EAPI Evas_Object *elm_pager_content_top_get(const Evas_Object *obj);
+   /* available item styles:
+    * default
+    * fade
+    * fade_translucide
+    */
+
+   typedef struct _Elm_Slideshow_Item_Class Elm_Slideshow_Item_Class;
+   typedef struct _Elm_Slideshow_Item_Class_Func Elm_Slideshow_Item_Class_Func;
+   typedef struct _Elm_Slideshow_Item       Elm_Slideshow_Item;
+   typedef Evas_Object *(*SlideshowItemGetFunc) (void *data, Evas_Object *obj);
+   typedef void         (*SlideshowItemDelFunc) (void *data, Evas_Object *obj);
+
+   struct _Elm_Slideshow_Item_Class
+     {
+       struct _Elm_Slideshow_Item_Class_Func {
+            SlideshowItemGetFunc get;
+            SlideshowItemDelFunc del;
+       } func;
+     };
+
+   EAPI Evas_Object *  elm_slideshow_add(Evas_Object *parent);
+   EAPI Elm_Slideshow_Item* elm_slideshow_item_add(Evas_Object *obj, const Elm_Slideshow_Item_Class *itc, const void *data);
+   EAPI void           elm_slideshow_show(Elm_Slideshow_Item *item);
+   EAPI void           elm_slideshow_next(Evas_Object *obj);
+   EAPI void           elm_slideshow_previous(Evas_Object *obj);
+   EAPI const Eina_List *elm_slideshow_transitions_get(const Evas_Object *obj);
+   EAPI void           elm_slideshow_transition_set(Evas_Object *obj, const char *);
+   EAPI const char     *elm_slideshow_transition_get(const Evas_Object *obj);
+   EAPI void            elm_slideshow_timeout_set(Evas_Object *obj ,int timeout);
+   EAPI int            elm_slideshow_timeout_get(const Evas_Object *obj);
+   EAPI void           elm_slideshow_loop_set(Evas_Object *obj, Eina_Bool loop);
+   EAPI Eina_Bool      elm_slideshow_loop_get(const Evas_Object *obj);
+   EAPI void           elm_slideshow_clear(Evas_Object *obj);
+   EAPI const Eina_List *elm_slideshow_items_get(const Evas_Object *obj);
+   EAPI void           elm_slideshow_item_del(Elm_Slideshow_Item *item);
+   EAPI void *         elm_slideshow_item_data_get(Elm_Slideshow_Item *item);
+   EAPI Elm_Slideshow_Item* elm_slideshow_item_current_get(const Evas_Object *obj);
+   EAPI Evas_Object*   elm_slideshow_item_object_get(Elm_Slideshow_Item* item);
+
+
+   EAPI Evas_Object *elm_fileselector_add(Evas_Object *parent);
+   EAPI void         elm_fileselector_is_save_set(Evas_Object *obj, Eina_Bool is_save);
+   EAPI Eina_Bool    elm_fileselector_is_save_get(const Evas_Object *obj);
+   EAPI void         elm_fileselector_folder_only_set(Evas_Object *obj, Eina_Bool only);
+   EAPI Eina_Bool    elm_fileselector_folder_only_get(const Evas_Object *obj);
+   EAPI void         elm_fileselector_buttons_ok_cancel_set(Evas_Object *obj, Eina_Bool buttons);
+   EAPI Eina_Bool    elm_fileselector_buttons_ok_cancel_get(const Evas_Object *obj);
+   EAPI Eina_Bool    elm_fileselector_expandable_get(const Evas_Object *obj);
+   EAPI void         elm_fileselector_expandable_set(Evas_Object *obj, Eina_Bool expand);
+   EAPI void         elm_fileselector_path_set(Evas_Object *obj, const char *path);
+   EAPI const char  *elm_fileselector_path_get(const Evas_Object *obj);
+   EAPI const char  *elm_fileselector_selected_get(const Evas_Object *obj);
+   EAPI Eina_Bool    elm_fileselector_selected_set(Evas_Object *obj, const char *path);
+
+   /* smart callbacks called:
+    * "selected" - the user click on a file
+    * "directory,open" - the list is populate with a new content. event_info is a directory.
+    * "done" - the user click on the ok or cancel buttons
+    */
+
+   EAPI Evas_Object *elm_progressbar_add(Evas_Object *parent);
+   EAPI void         elm_progressbar_pulse_set(Evas_Object *obj, Eina_Bool pulse);
+   EAPI Eina_Bool    elm_progressbar_pulse_get(const Evas_Object *obj);
+   EAPI void         elm_progressbar_pulse(Evas_Object *obj, Eina_Bool state);
+   EAPI void         elm_progressbar_value_set(Evas_Object *obj, double val);
+   EAPI double       elm_progressbar_value_get(const Evas_Object *obj);
+   EAPI void         elm_progressbar_label_set(Evas_Object *obj, const char *label);
+   EAPI const char  *elm_progressbar_label_get(const Evas_Object *obj);
+   EAPI void         elm_progressbar_icon_set(Evas_Object *obj, Evas_Object *icon);
+   EAPI Evas_Object *elm_progressbar_icon_get(const Evas_Object *obj);
+   EAPI void         elm_progressbar_span_size_set(Evas_Object *obj, Evas_Coord size);
+   EAPI Evas_Coord   elm_progressbar_span_size_get(const Evas_Object *obj);
+   EAPI void         elm_progressbar_unit_format_set(Evas_Object *obj, const char *format);
+   EAPI const char  *elm_progressbar_unit_format_get(const Evas_Object *obj);
+   EAPI void         elm_progressbar_horizontal_set(Evas_Object *obj, Eina_Bool horizontal);
+   EAPI Eina_Bool    elm_progressbar_horizontal_get(const Evas_Object *obj);
+   EAPI void         elm_progressbar_inverted_set(Evas_Object *obj, Eina_Bool inverted);
+   EAPI Eina_Bool    elm_progressbar_inverted_get(const Evas_Object *obj);
+   /* smart callbacks called:
+    */
+   /* available item styles:
+    * default
+    * wheel (simple style, no text, no progression, only pulse is available)
+    */
+
+   EAPI Evas_Object *elm_separator_add(Evas_Object *parent);
+   EAPI void         elm_separator_horizontal_set(Evas_Object *obj, Eina_Bool horizontal);
+   EAPI Eina_Bool    elm_separator_horizontal_get(const Evas_Object *obj);
+   /* smart callbacks called:
+    */
+
+   EAPI Evas_Object *elm_spinner_add(Evas_Object *parent);
+   EAPI void        elm_spinner_label_format_set(Evas_Object *obj, const char *fmt);
+   EAPI const char  *elm_spinner_label_format_get(const Evas_Object *obj);
+   EAPI void         elm_spinner_min_max_set(Evas_Object *obj, double min, double max);
+   EAPI void         elm_spinner_min_max_get(const Evas_Object *obj, double *min, double *max);
+   EAPI void        elm_spinner_step_set(Evas_Object *obj, double step);
+   EAPI double      elm_spinner_step_get(const Evas_Object *obj);
+   EAPI void        elm_spinner_value_set(Evas_Object *obj, double val);
+   EAPI double      elm_spinner_value_get(const Evas_Object *obj);
+   EAPI void         elm_spinner_wrap_set(Evas_Object *obj, Eina_Bool wrap);
+   EAPI Eina_Bool    elm_spinner_wrap_get(const Evas_Object *obj);
+   EAPI void        elm_spinner_editable_set(Evas_Object *obj, Eina_Bool editable);
+   EAPI Eina_Bool    elm_spinner_editable_get(const Evas_Object *obj);
+   EAPI void        elm_spinner_special_value_add(Evas_Object *obj, double value, const char *label);
+   /* smart callbacks called:
+    * "changed" - when the spinner value changes
+    * "delay,changed" - when the spinner value changed, but a small time after a change (use this if you only want to respond to a change once the spinner is held still for a short while).
+    */
+   /* available item styles:
+    * default
+    * vertical (two up/down buttons at the right side and text left aligned)
+    */
+
+   EAPI Evas_Object *elm_index_add(Evas_Object *parent);
+   EAPI void         elm_index_active_set(Evas_Object *obj, Eina_Bool active);
+   EAPI void         elm_index_item_level_set(Evas_Object *obj, int level);
+   EAPI int          elm_index_item_level_get(const Evas_Object *obj);
+   EAPI const void  *elm_index_item_selected_get(const Evas_Object *obj, int level);
+   EAPI void         elm_index_item_append(Evas_Object *obj, const char *letter, const void *item);
+   EAPI void         elm_index_item_prepend(Evas_Object *obj, const char *letter, const void *item);
+   EAPI void         elm_index_item_append_relative(Evas_Object *obj, const char *letter, const void *item, const void *relative);
+   EAPI void         elm_index_item_prepend_relative(Evas_Object *obj, const char *letter, const void *item, const void *relative);
+   EAPI void         elm_index_item_del(Evas_Object *obj, const void *item);
+   EAPI void         elm_index_item_clear(Evas_Object *obj);
+   EAPI void         elm_index_item_go(Evas_Object *obj, int level);
+   /* smart callbacks called:
+    * "changed" - when the selected index item changes
+    * "delay,changed" - when the selected index item changes, but after some small idle period
+    * "selected" - when the user releases heir finger and selects an item
+    */
+
+   typedef enum _Elm_Photocam_Zoom_Mode
+     {
+       ELM_PHOTOCAM_ZOOM_MODE_MANUAL = 0,
+       ELM_PHOTOCAM_ZOOM_MODE_AUTO_FIT,
+       ELM_PHOTOCAM_ZOOM_MODE_AUTO_FILL,
+       ELM_PHOTOCAM_ZOOM_MODE_LAST
+     } Elm_Photocam_Zoom_Mode;
+   EAPI Evas_Object *elm_photocam_add(Evas_Object *parent);
+   EAPI int          elm_photocam_file_set(Evas_Object *obj, const char *file);
+   EAPI const char * elm_photocam_file_get(const Evas_Object *obj);
+   EAPI void         elm_photocam_zoom_set(Evas_Object *obj, double zoom);
+   EAPI double       elm_photocam_zoom_get(const Evas_Object *obj);
+   EAPI void         elm_photocam_zoom_mode_set(Evas_Object *obj, Elm_Photocam_Zoom_Mode mode);
+   EAPI Elm_Photocam_Zoom_Mode elm_photocam_zoom_mode_get(const Evas_Object *obj);
+   EAPI void         elm_photocam_image_size_get(const Evas_Object *obj, int *w, int *h);
+   EAPI void         elm_photocam_region_get(const Evas_Object *obj, int *x, int *y, int *w, int *h);
+   EAPI void         elm_photocam_image_region_show(Evas_Object *obj, int x, int y, int w, int h);
+   EAPI void         elm_photocam_image_region_bring_in(Evas_Object *obj, int x, int y, int w, int h);
+   EAPI void         elm_photocam_paused_set(Evas_Object *obj, Eina_Bool paused);
+   EAPI Eina_Bool    elm_photocam_paused_get(const Evas_Object *obj);
+   EAPI Evas_Object *elm_photocam_internal_image_get(const Evas_Object *obj);
+   
+   /* smart callbacks called:
+    * "clicked" - when image clicked
+    * "press" - when mouse/finger held down initially on image
+    * "longpressed" - when mouse/finger held for long time on image
+    * "clicked,double" - when mouse/finger double-clicked
+    * "load" - when photo load begins
+    * "loaded" - when photo load done
+    * "load,details" - when detailed image load begins
+    * "loaded,details" - when detailed image load done
+    * "zoom,start" - when zooming started
+    * "zoom,stop" - when zooming stopped
+    * "zoom,change" - when auto zoom mode changed zoom level
+    * "scroll - the content has been scrolled (moved)
+    * "scroll,anim,start" - scrolling animation has started
+    * "scroll,anim,stop" - scrolling animation has stopped
+    * "scroll,drag,start" - dragging the contents around has started
+    * "scroll,drag,stop" - dragging the contents around has stopped
+    */
+
+   typedef enum _Elm_Map_Zoom_Mode
+     {
+       ELM_MAP_ZOOM_MODE_MANUAL,
+       ELM_MAP_ZOOM_MODE_AUTO_FIT,
+       ELM_MAP_ZOOM_MODE_AUTO_FILL,
+       ELM_MAP_ZOOM_MODE_LAST
+     } Elm_Map_Zoom_Mode;
+
+   typedef enum _Elm_Map_Sources
+     {
+       ELM_MAP_SOURCE_MAPNIK,
+       ELM_MAP_SOURCE_OSMARENDER,
+       ELM_MAP_SOURCE_CYCLEMAP,
+       ELM_MAP_SOURCE_MAPLINT,
+       ELM_MAP_SOURCE_CUSTOM_1,
+       ELM_MAP_SOURCE_CUSTOM_2,
+       ELM_MAP_SOURCE_CUSTOM_3,
+       ELM_MAP_SOURCE_CUSTOM_4,
+       ELM_MAP_SOURCE_CUSTOM_5,
+       ELM_MAP_SOURCE_CUSTOM_6,
+       ELM_MAP_SOURCE_CUSTOM_7,
+       ELM_MAP_SOURCE_LAST
+     } Elm_Map_Sources;
+
+   typedef struct _Elm_Map_Marker Elm_Map_Marker;
+   typedef struct _Elm_Map_Marker_Class Elm_Map_Marker_Class;
+   typedef struct _Elm_Map_Group_Class Elm_Map_Group_Class;
+   typedef Evas_Object *(*ElmMapMarkerGetFunc)      (Evas_Object *obj, Elm_Map_Marker *marker, void *data);
+   typedef void         (*ElmMapMarkerDelFunc)      (Evas_Object *obj, Elm_Map_Marker *marker, void *data, Evas_Object *o);
+   typedef Evas_Object *(*ElmMapMarkerIconGetFunc)  (Evas_Object *obj, Elm_Map_Marker *marker, void *data);
+   typedef Evas_Object *(*ElmMapGroupIconGetFunc)  (Evas_Object *obj, void *data);
+   typedef char *(*ElmMapSourceURLFunc) (int x, int y, int zoom);
+
+   EAPI Evas_Object *elm_map_add(Evas_Object *parent);
+   EAPI void         elm_map_zoom_set(Evas_Object *obj, int zoom);
+   EAPI double       elm_map_zoom_get(const Evas_Object *obj);
+   EAPI void         elm_map_zoom_mode_set(Evas_Object *obj, Elm_Map_Zoom_Mode mode);
+   EAPI Elm_Map_Zoom_Mode elm_map_zoom_mode_get(const Evas_Object *obj);
+   EAPI void        elm_map_geo_region_get(const Evas_Object *obj, double *lon, double *lat);
+   EAPI void         elm_map_geo_region_bring_in(Evas_Object *obj, double lon, double lat);
+   EAPI void         elm_map_geo_region_show(Evas_Object *obj, double lon, double lat);
+   EAPI void         elm_map_paused_set(Evas_Object *obj, Eina_Bool paused);
+   EAPI Eina_Bool    elm_map_paused_get(const Evas_Object *obj);
+   EAPI void        elm_map_paused_markers_set(Evas_Object *obj, Eina_Bool paused);
+   EAPI Eina_Bool    elm_map_paused_markers_get(const Evas_Object *obj);
+   EAPI void        elm_map_utils_convert_coord_into_geo(int x, int y, int size, double *lon, double *lat);
+   EAPI void         elm_map_utils_convert_geo_into_coord(double lon, double lat, int size, int *x, int *y);
+   EAPI Elm_Map_Marker *elm_map_marker_add(Evas_Object *obj, double lon, double lat, Elm_Map_Marker_Class *clas, Elm_Map_Group_Class *clas_group, void *data);
+   EAPI void        elm_map_max_marker_per_group_set(Evas_Object *obj, int max);
+   EAPI void        elm_map_marker_remove(Elm_Map_Marker *marker);
+   EAPI void        elm_map_marker_bring_in(Elm_Map_Marker *marker);
+   EAPI void        elm_map_marker_show(Elm_Map_Marker *marker);
+   EAPI void        elm_map_markers_list_show(Eina_List *markers);
+   EAPI Evas_Object *elm_map_marker_object_get(Elm_Map_Marker *marker);
+   EAPI void        elm_map_marker_update(Elm_Map_Marker *marker);
+   EAPI void        elm_map_bubbles_close(Evas_Object *obj);
+
+   EAPI Elm_Map_Group_Class * elm_map_group_class_new(Evas_Object *obj);
+   EAPI void         elm_map_group_class_style_set(Elm_Map_Group_Class *clas, const char *style);
+   EAPI void         elm_map_group_class_icon_cb_set(Elm_Map_Group_Class *clas, ElmMapGroupIconGetFunc icon_get);
+   EAPI void        elm_map_group_class_data_set(Elm_Map_Group_Class *clas, void *data);
+   EAPI void         elm_map_group_class_zoom_displayed_set(Elm_Map_Group_Class *clas, int zoom);
+   EAPI void        elm_map_group_class_zoom_grouped_set(Elm_Map_Group_Class *clas, int zoom);
+   EAPI void         elm_map_group_class_hide_set(Evas_Object *obj, Elm_Map_Group_Class *clas, Eina_Bool hide);
+
+   EAPI Elm_Map_Marker_Class * elm_map_marker_class_new(Evas_Object *obj);
+   EAPI void         elm_map_marker_class_style_set(Elm_Map_Marker_Class *clas, const char *style);
+   EAPI void         elm_map_marker_class_icon_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerIconGetFunc icon_get);
+   EAPI void         elm_map_marker_class_get_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerGetFunc get);
+   EAPI void         elm_map_marker_class_del_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerDelFunc del);
+
+   EAPI void         elm_map_source_set(Evas_Object *obj, Elm_Map_Sources source);
+   EAPI Elm_Map_Sources elm_map_source_get(const Evas_Object *obj);
+   EAPI void         elm_map_source_custom_api_set(Elm_Map_Sources source, const char *label, 
+                               int zoom_min, int zoom_max, ElmMapSourceURLFunc url_cb);
+   EAPI int          elm_map_source_zoom_min_get(Elm_Map_Sources source);
+   EAPI int         elm_map_source_zoom_max_get(Elm_Map_Sources source);
+   EAPI const char * elm_map_source_name_get(Elm_Map_Sources source);
+   /* smart callbacks called:
+    * "clicked" - when image clicked
+    * "press" - when mouse/finger held down initially on image
+    * "longpressed" - when mouse/finger held for long time on image
+    * "clicked,double" - when mouse/finger double-clicked
+    * "load,details" - when detailed image load begins
+    * "loaded,details" - when detailed image load done
+    * "zoom,start" - when zooming started
+    * "zoom,stop" - when zooming stopped
+    * "zoom,change" - when auto zoom mode changed zoom level
+    * "scroll - the content has been scrolled (moved)
+    * "scroll,anim,start" - scrolling animation has started
+    * "scroll,anim,stop" - scrolling animation has stopped
+    * "scroll,drag,start" - dragging the contents around has started
+    * "scroll,drag,stop" - dragging the contents around has stopped
+    */
+
+   typedef enum _Elm_Panel_Orient
+     {
+        ELM_PANEL_ORIENT_TOP,
+          ELM_PANEL_ORIENT_BOTTOM,
+          ELM_PANEL_ORIENT_LEFT,
+          ELM_PANEL_ORIENT_RIGHT,
+     } Elm_Panel_Orient;
+   EAPI Evas_Object          *elm_panel_add(Evas_Object *parent);
+   EAPI void                  elm_panel_orient_set(Evas_Object *obj, Elm_Panel_Orient orient);
+   EAPI Elm_Panel_Orient      elm_panel_orient_get(Evas_Object *obj);
+   EAPI void                  elm_panel_content_set(Evas_Object *obj, Evas_Object *content);
+   EAPI void                  elm_panel_hidden_set(Evas_Object *obj, Eina_Bool hidden);
+   EAPI Eina_Bool             elm_panel_hidden_get(Evas_Object *obj);
+   EAPI void                  elm_panel_toggle(Evas_Object *obj);
+
+   typedef enum _Elm_Flip_Mode
+     {
+        ELM_FLIP_ROTATE_Y_CENTER_AXIS,
+          ELM_FLIP_ROTATE_X_CENTER_AXIS,
+          ELM_FLIP_ROTATE_XZ_CENTER_AXIS,
+          ELM_FLIP_ROTATE_YZ_CENTER_AXIS
+     } Elm_Flip_Mode;
+   
+   EAPI Evas_Object *elm_flip_add(Evas_Object *parent);
+   EAPI void         elm_flip_content_front_set(Evas_Object *obj, Evas_Object *content);
+   EAPI void         elm_flip_content_back_set(Evas_Object *obj, Evas_Object *content);
+   EAPI Evas_Object *elm_flip_content_front_get(const Evas_Object *obj);
+   EAPI Evas_Object *elm_flip_content_back_get(const Evas_Object *obj);
+   EAPI Eina_Bool    elm_flip_front_get(const Evas_Object *obj);
+   EAPI void         elm_flip_perspective_set(Evas_Object *obj, Evas_Coord foc, Evas_Coord x, Evas_Coord y);
+   EAPI void         elm_flip_go(Evas_Object *obj, Elm_Flip_Mode mode);
+   /* smart callbacks called:
+    * "animate,done" - when a flip animation is finished
+    */
+   
+   EAPI Evas_Object *elm_scrolled_entry_add(Evas_Object *parent);
+   EAPI void         elm_scrolled_entry_single_line_set(Evas_Object *obj, Eina_Bool single_line);
+   EAPI Eina_Bool    elm_scrolled_entry_single_line_get(const Evas_Object *obj);
+   EAPI void         elm_scrolled_entry_password_set(Evas_Object *obj, Eina_Bool password);
+   EAPI Eina_Bool    elm_scrolled_entry_password_get(const Evas_Object *obj);
+   EAPI void         elm_scrolled_entry_entry_set(Evas_Object *obj, const char *entry);
+   EAPI const char  *elm_scrolled_entry_entry_get(const Evas_Object *obj);
+   EAPI const char  *elm_scrolled_entry_selection_get(const Evas_Object *obj);
+   EAPI void         elm_scrolled_entry_entry_insert(Evas_Object *obj, const char *entry);
+   EAPI void         elm_scrolled_entry_line_wrap_set(Evas_Object *obj, Eina_Bool wrap);
+   EAPI void         elm_scrolled_entry_line_char_wrap_set(Evas_Object *obj, Eina_Bool wrap);
+   EAPI void         elm_scrolled_entry_editable_set(Evas_Object *obj, Eina_Bool editable);
+   EAPI Eina_Bool    elm_scrolled_entry_editable_get(const Evas_Object *obj);
+   EAPI void         elm_scrolled_entry_select_none(Evas_Object *obj);
+   EAPI void         elm_scrolled_entry_select_all(Evas_Object *obj);
+   EAPI Eina_Bool    elm_scrolled_entry_cursor_next(Evas_Object *obj);
+   EAPI Eina_Bool    elm_scrolled_entry_cursor_prev(Evas_Object *obj);
+   EAPI Eina_Bool    elm_scrolled_entry_cursor_up(Evas_Object *obj);
+   EAPI Eina_Bool    elm_scrolled_entry_cursor_down(Evas_Object *obj);
+   EAPI void         elm_scrolled_entry_cursor_begin_set(Evas_Object *obj);
+   EAPI void         elm_scrolled_entry_cursor_end_set(Evas_Object *obj);
+   EAPI void         elm_scrolled_entry_cursor_line_begin_set(Evas_Object *obj);
+   EAPI void         elm_scrolled_entry_cursor_line_end_set(Evas_Object *obj);
+   EAPI void         elm_scrolled_entry_cursor_selection_begin(Evas_Object *obj);
+   EAPI void         elm_scrolled_entry_cursor_selection_end(Evas_Object *obj);
+   EAPI Eina_Bool    elm_scrolled_entry_cursor_is_format_get(const Evas_Object *obj);
+   EAPI Eina_Bool    elm_scrolled_entry_cursor_is_visible_format_get(const Evas_Object *obj);
+   EAPI const char  *elm_scrolled_entry_cursor_content_get(const Evas_Object *obj);
+   EAPI void         elm_scrolled_entry_selection_cut(Evas_Object *obj);
+   EAPI void         elm_scrolled_entry_selection_copy(Evas_Object *obj);
+   EAPI void         elm_scrolled_entry_selection_paste(Evas_Object *obj);
+   EAPI void         elm_scrolled_entry_context_menu_clear(Evas_Object *obj);
+   EAPI void         elm_scrolled_entry_context_menu_item_add(Evas_Object *obj, const char *label, const char *icon_file, Elm_Icon_Type icon_type, Evas_Smart_Cb func, const void *data);
+   EAPI void         elm_scrolled_entry_context_menu_disabled_set(Evas_Object *obj, Eina_Bool disabled);
+   EAPI Eina_Bool    elm_scrolled_entry_context_menu_disabled_get(const Evas_Object *obj);
+   EAPI void         elm_scrolled_entry_scrollbar_policy_set(Evas_Object *obj, Elm_Scroller_Policy h, Elm_Scroller_Policy v);
+   EAPI void         elm_scrolled_entry_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce);
+
+   EAPI Evas_Object *elm_conformant_add(Evas_Object *parent);
+   EAPI void         elm_conformant_content_set(Evas_Object *obj, Evas_Object *content);
+
+   EAPI Evas_Object *elm_mapbuf_add(Evas_Object *parent);
+   EAPI void         elm_mapbuf_content_set(Evas_Object *obj, Evas_Object *content);
+   EAPI void         elm_mapbuf_enabled_set(Evas_Object *obj, Eina_Bool enabled);
+   EAPI Eina_Bool    elm_mapbuf_enabled_get(const Evas_Object *obj);
+   EAPI void         elm_mapbuf_smooth_set(Evas_Object *obj, Eina_Bool smooth);
+   EAPI Eina_Bool    elm_mapbuf_smooth_get(const Evas_Object *obj);
+   EAPI void         elm_mapbuf_alpha_set(Evas_Object *obj, Eina_Bool alpha);
+   EAPI Eina_Bool    elm_mapbuf_alpha_get(const Evas_Object *obj);
+       
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
new file mode 100644 (file)
index 0000000..f2711bf
--- /dev/null
@@ -0,0 +1,99 @@
+AUTOMAKE_OPTIONS     = 1.4 foreign
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_builddir) \
+-I$(top_srcdir) \
+-I$(top_srcdir)/src/lib \
+-I$(top_builddir)/src/lib \
+-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
+-DPACKAGE_LIB_DIR=\"$(libdir)\" \
+@ELEMENTARY_CFLAGS@ \
+@ELEMENTARY_X_CFLAGS@ \
+@ELEMENTARY_FB_CFLAGS@ \
+@ELEMENTARY_SDL_CFLAGS@ \
+@ELEMENTARY_WIN32_CFLAGS@ \
+@ELEMENTARY_WINCE_CFLAGS@ \
+@ELEMENTARY_EDBUS_CFLAGS@ \
+@ELEMENTARY_EFREET_CFLAGS@ \
+@ELEMENTARY_ETHUMB_CFLAGS@
+
+if ELEMENTARY_WINDOWS_BUILD
+AM_CPPFLAGS += -DELEMENTARY_BUILD
+endif
+
+lib_LTLIBRARIES = libelementary.la
+
+include_HEADERS = Elementary.h
+
+libelementary_la_SOURCES = \
+elm_priv.h \
+elm_main.c \
+elm_theme.c \
+elm_module.c \
+\
+elm_win.c \
+elm_widget.c \
+elm_bg.c \
+elm_icon.c \
+elm_image.c \
+elm_box.c \
+elm_button.c \
+elm_scroller.c \
+elm_label.c \
+elm_toggle.c \
+elm_frame.c \
+elm_table.c \
+elm_scrolled_grid.c \
+elm_clock.c \
+elm_layout.c \
+elm_hover.c \
+elm_entry.c \
+elm_bubble.c \
+elm_photo.c \
+elm_toolbar.c \
+elm_list.c \
+elm_carousel.c \
+elm_slider.c \
+elm_genlist.c \
+elm_check.c \
+elm_radio.c \
+elm_pager.c \
+elm_progressbar.c \
+elm_separator.c \
+elm_spinner.c \
+elm_index.c \
+elm_photocam.c \
+elm_notify.c \
+elm_slideshow.c \
+elm_menu.c \
+elm_panel.c \
+elm_map.c \
+elm_flip.c \
+elm_conform.c \
+elm_mapbuf.c \
+elm_thumb.c \
+elm_config.c \
+\
+elc_anchorblock.c \
+elc_anchorview.c \
+elc_fileselector.c \
+elc_fileselector_button.c \
+elc_hoversel.c \
+elc_notepad.c \
+elc_scrolled_entry.c \
+\
+els_pan.c \
+els_pan.h \
+els_scroller.c \
+els_scroller.h \
+els_box.c \
+els_box.h \
+els_icon.c \
+els_icon.h
+
+
+libelementary_la_CFLAGS =
+libelementary_la_LIBADD = @my_libs@ @dlopen_libs@ @ELEMENTARY_LIBS@ @ELEMENTARY_X_LIBS@ @ELEMENTARY_FB_LIBS@ @ELEMENTARY_SDL_LIBS@ @ELEMENTARY_WIN32_LIBS@ @ELEMENTARY_WINCE_LIBS@ @ELEMENTARY_EDBUS_LIBS@ @ELEMENTARY_EFREET_LIBS@ @ELEMENTARY_ETHUMB_LIBS@
+libelementary_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@
diff --git a/src/lib/elc_anchorblock.c b/src/lib/elc_anchorblock.c
new file mode 100644 (file)
index 0000000..11d21f3
--- /dev/null
@@ -0,0 +1,416 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Anchorblock Anchorblock
+ *
+ * Anchorblock is for displaying tet that contains markup with anchors like:
+ * \<a href=1234\>something\</\> in it. These will be drawn differently and will
+ * be able to be clicked on by the user to display a popup. This popup then
+ * is intended to contain extra options such as "call", "add to contacts",
+ * "open web page" etc.
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * anchor,clicked - anchor called was clicked. event_info is anchor info -
+ * Elm_Entry_Anchorview_Info
+ */
+typedef struct _Widget_Data Widget_Data;
+typedef struct _Elm_Anchorblock_Item_Provider Elm_Anchorblock_Item_Provider;
+
+struct _Widget_Data
+{
+   Evas_Object *entry;
+   Evas_Object *hover_parent;
+   Evas_Object *pop, *hover;
+   Eina_List *item_providers;
+   const char *hover_style;
+};
+
+struct _Elm_Anchorblock_Item_Provider
+{
+   Evas_Object *(*func) (void *data, Evas_Object *anchorblock, const char *item);
+   void *data;
+};
+
+static const char *widtype = NULL;
+
+static const char SIG_ANCHOR_CLICKED[] = "anchor,clicked";
+static const Evas_Smart_Cb_Description _signals[] = {
+  {SIG_ANCHOR_CLICKED, ""}, /* TODO: declare the type properly, as data is
+                            * being passed
+                            */
+  {NULL, NULL}
+};
+
+static void _del_pre_hook(Evas_Object *obj);
+static void _del_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _parent_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+static void
+_del_pre_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   evas_object_event_callback_del_full(wd->entry, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                       _changed_size_hints, obj);
+   elm_anchorblock_hover_end(obj);
+   elm_anchorblock_hover_parent_set(obj, NULL);
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_Anchorblock_Item_Provider *ip;
+   if (!wd) return;
+   if (wd->hover_style) eina_stringshare_del(wd->hover_style);
+   EINA_LIST_FREE(wd->item_providers, ip)
+     {
+        free(ip);
+     }
+   free(wd);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   if (!wd) return;
+   evas_object_size_hint_min_get(wd->entry, &minw, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+}
+
+static void
+_hover_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   elm_anchorblock_hover_end(data);
+}
+
+static void
+_anchor_clicked(void *data, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Elm_Entry_Anchor_Info *info = event_info;
+   Evas_Object *hover_parent;
+   Elm_Entry_Anchorblock_Info ei;
+   Evas_Coord x, w, y, h, px, py;
+   if (!wd) return;
+   wd->pop = elm_icon_add(obj);
+   evas_object_move(wd->pop, info->x, info->y);
+   evas_object_resize(wd->pop, info->w, info->h);
+   wd->hover = elm_hover_add(obj);
+   if (wd->hover_style)
+     elm_object_style_set(wd->hover, wd->hover_style);
+   hover_parent = wd->hover_parent;
+   if (!hover_parent) hover_parent = obj;
+   elm_hover_parent_set(wd->hover, hover_parent);
+   elm_hover_target_set(wd->hover, wd->pop);
+   ei.name = info->name;
+   ei.button = info->button;
+   ei.hover = wd->hover;
+   ei.anchor.x = info->x;
+   ei.anchor.y = info->y;
+   ei.anchor.w = info->w;
+   ei.anchor.h = info->h;
+   evas_object_geometry_get(hover_parent, &x, &y, &w, &h);
+   ei.hover_parent.x = x;
+   ei.hover_parent.y = y;
+   ei.hover_parent.w = w;
+   ei.hover_parent.h = h;
+   px = info->x + (info->w / 2);
+   py = info->y + (info->h / 2);
+   ei.hover_left = 1;
+   if (px < (x + (w / 3))) ei.hover_left = 0;
+   ei.hover_right = 1;
+   if (px > (x + ((w * 2) / 3))) ei.hover_right = 0;
+   ei.hover_top = 1;
+   if (py < (y + (h / 3))) ei.hover_top = 0;
+   ei.hover_bottom = 1;
+   if (py > (y + ((h * 2) / 3))) ei.hover_bottom = 0;
+   evas_object_smart_callback_call(data, SIG_ANCHOR_CLICKED, &ei);
+   evas_object_smart_callback_add(wd->hover, "clicked", _hover_clicked, data);
+   evas_object_show(wd->hover);
+}
+
+static void
+_parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   wd->hover_parent = NULL;
+}
+
+static Evas_Object *
+_item_provider(void *data, Evas_Object *entry, const char *item)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Object *o;
+   Eina_List *l;
+   Elm_Anchorblock_Item_Provider *ip;
+   
+   EINA_LIST_FOREACH(wd->item_providers, l, ip)
+     {
+        o = ip->func(ip->data, data, item);
+        if (o) return o;
+     }
+   return NULL;
+}
+
+/**
+ * Add a new Anchorblock object
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Anchorblock
+ */
+EAPI Evas_Object *
+elm_anchorblock_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "anchorblock");
+   elm_widget_type_set(obj, "anchorblock");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_pre_hook_set(obj, _del_pre_hook);
+   elm_widget_del_hook_set(obj, _del_hook);
+
+   wd->entry = elm_entry_add(parent);
+   elm_entry_item_provider_prepend(wd->entry, _item_provider, obj);
+   elm_widget_resize_object_set(obj, wd->entry);
+   elm_entry_editable_set(wd->entry, 0);
+   evas_object_size_hint_weight_set(wd->entry, 1.0, 1.0);
+   evas_object_size_hint_align_set(wd->entry, -1.0, -1.0);
+
+   evas_object_event_callback_add(wd->entry, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                 _changed_size_hints, obj);
+
+   elm_entry_entry_set(wd->entry, "");
+
+   evas_object_smart_callback_add(wd->entry, "anchor,clicked",
+                                 _anchor_clicked, obj);
+
+   _sizing_eval(obj);
+
+   // TODO: convert Elementary to subclassing of Evas_Smart_Class
+   // TODO: and save some bytes, making descriptions per-class and not instance!
+   evas_object_smart_callbacks_descriptions_set(obj, _signals);
+   return obj;
+}
+
+/**
+ * Set the text markup of the anchorblock
+ *
+ * This sets the text of the anchorblock to be the text given as @p text. This
+ * text is in markup format with \<a href=XXX\> beginning an achor with the
+ * string link of 'XXX', and \</\> or \</a\> ending the link. Other markup can
+ * be used dependign on the style support.
+ *
+ * @param obj The anchorblock object
+ * @param text The text to set, or NULL to clear
+ *
+ * @ingroup Anchorblock
+ */
+EAPI void
+elm_anchorblock_text_set(Evas_Object *obj, const char *text)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_entry_set(wd->entry, text);
+   if (wd->hover) evas_object_del(wd->hover);
+   if (wd->pop) evas_object_del(wd->pop);
+   wd->hover = NULL;
+   wd->pop = NULL;
+   _sizing_eval(obj);
+}
+
+/**
+  * Get the markup text set for the anchorblock
+  *
+  * This retrieves back the string set by @c elm_anchorblock_text_set().
+  *
+  * @param obj The anchorblock object
+  * @return text The markup text set or @c NULL, either if it was not set
+  * or an error ocurred
+  *
+  * @ingroup Anchorblock
+  */
+EAPI const char*
+elm_anchorblock_text_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return elm_entry_entry_get(wd->entry);
+}
+
+/**
+ * Set the parent of the hover popup
+ *
+ * This sets the parent of the hover that anchorblock will create. See hover
+ * objects for more information on this.
+ *
+ * @param obj The anchorblock object
+ * @param parent The parent the hover should use
+ *
+ * @ingroup Anchorblock
+ */
+EAPI void
+elm_anchorblock_hover_parent_set(Evas_Object *obj, Evas_Object *parent)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->hover_parent)
+     evas_object_event_callback_del_full(wd->hover_parent, EVAS_CALLBACK_DEL, _parent_del, obj);
+   wd->hover_parent = parent;
+   if (wd->hover_parent)
+     evas_object_event_callback_add(wd->hover_parent, EVAS_CALLBACK_DEL, _parent_del, obj);
+}
+
+/**
+ * Set the style that the hover should use
+ *
+ * This sets the style for the hover that anchorblock will create. See hover
+ * objects for more information
+ *
+ * @param obj The anchorblock object
+ * @param style The style to use
+ *
+ * @ingroup Anchorblock
+ */
+EAPI void
+elm_anchorblock_hover_style_set(Evas_Object *obj, const char *style)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->hover_style, style);
+}
+
+/**
+ * Stop the hover popup in the anchorblock
+ *
+ * This will stop the hover popup in the anchorblock if it is currently active.
+ *
+ * @param obj The anchorblock object
+ *
+ * @ingroup Anchorblock
+ */
+EAPI void
+elm_anchorblock_hover_end(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->hover) evas_object_del(wd->hover);
+   if (wd->pop) evas_object_del(wd->pop);
+   wd->hover = NULL;
+   wd->pop = NULL;
+}
+
+/**
+ * This appends a custom item provider to the list for that anchorblock
+ *
+ * This appends the given callback. The list is walked from beginning to end
+ * with each function called given the item href string in the text. If the
+ * function returns an object handle other than NULL (it should create an
+ * and object to do this), then this object is used to replace that item. If
+ * not the next provider is called until one provides an item object, or the
+ * default provider in anchorblock does.
+ * 
+ * @param obj The anchorblock object
+ * @param func The function called to provide the item object
+ * @param data The data passed to @p func
+ *
+ * @ingroup Anchorblock
+ */
+EAPI void
+elm_anchorblock_item_provider_append(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorblock, const char *item), void *data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (!func) return;
+   Elm_Anchorblock_Item_Provider *ip = calloc(1, sizeof(Elm_Anchorblock_Item_Provider));
+   if (!ip) return;
+   ip->func = func;
+   ip->data = data;
+   wd->item_providers = eina_list_append(wd->item_providers, ip);
+}
+
+/**
+ * This prepends a custom item provider to the list for that anchorblock
+ *
+ * This prepends the given callback. See elm_anchorblock_item_provider_append() for
+ * more information
+ * 
+ * @param obj The anchorblock object
+ * @param func The function called to provide the item object
+ * @param data The data passed to @p func
+ *
+ * @ingroup Anchorblock
+ */
+EAPI void
+elm_anchorblock_item_provider_prepend(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorblock, const char *item), void *data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (!func) return;
+   Elm_Anchorblock_Item_Provider *ip = calloc(1, sizeof(Elm_Anchorblock_Item_Provider));
+   if (!ip) return;
+   ip->func = func;
+   ip->data = data;
+   wd->item_providers = eina_list_prepend(wd->item_providers, ip);
+}
+
+/**
+ * This removes a custom item provider to the list for that anchorblock
+ *
+ * This removes the given callback. See elm_anchorblock_item_provider_append() for
+ * more information
+ * 
+ * @param obj The anchorblock object
+ * @param func The function called to provide the item object
+ * @param data The data passed to @p func
+ *
+ * @ingroup Anchorblock
+ */
+EAPI void
+elm_anchorblock_item_provider_remove(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorblock, const char *item), void *data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Eina_List *l;
+   Elm_Anchorblock_Item_Provider *ip;
+   if (!wd) return;
+   if (!func) return;
+   EINA_LIST_FOREACH(wd->item_providers, l, ip)
+     {
+        if ((ip->func == func) && (ip->data == data))
+          {
+             wd->item_providers = eina_list_remove_list(wd->item_providers, l);
+             free(ip);
+             return;
+          }
+     }
+}
diff --git a/src/lib/elc_anchorview.c b/src/lib/elc_anchorview.c
new file mode 100644 (file)
index 0000000..2055bd3
--- /dev/null
@@ -0,0 +1,431 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Anchorview Anchorview
+ *
+ * This is just like the Anchorblock object, but provides a scroller to hold
+ * the text automatically.
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * anchor,clicked - achor called was clicked. event_info is anchor info -
+ * Elm_Entry_Anchorview_Info
+ */
+typedef struct _Widget_Data Widget_Data;
+typedef struct _Elm_Anchorview_Item_Provider Elm_Anchorview_Item_Provider;
+
+struct _Widget_Data
+{
+   Evas_Object *scroller, *entry;
+   Evas_Object *hover_parent;
+   Evas_Object *pop, *hover;
+   Eina_List *item_providers;
+   const char *hover_style;
+};
+
+struct _Elm_Anchorview_Item_Provider
+{
+   Evas_Object *(*func) (void *data, Evas_Object *anchorview, const char *item);
+   void *data;
+};
+
+static const char *widtype = NULL;
+
+static const char SIG_ANCHOR_CLICKED[] = "anchor,clicked";
+static const Evas_Smart_Cb_Description _signals[] = {
+  {SIG_ANCHOR_CLICKED, ""}, /* TODO: declare the type properly, as data is
+                            * being passed
+                            */
+  {NULL, NULL}
+};
+
+static void _del_pre_hook(Evas_Object *obj);
+static void _del_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _parent_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+static void
+_del_pre_hook(Evas_Object *obj)
+{
+   elm_anchorview_hover_end(obj);
+   elm_anchorview_hover_parent_set(obj, NULL);
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_Anchorview_Item_Provider *ip;
+   if (!wd) return;
+   if (wd->hover_style) eina_stringshare_del(wd->hover_style);
+   EINA_LIST_FREE(wd->item_providers, ip)
+     {
+        free(ip);
+     }
+   free(wd);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   if (!wd) return;
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+}
+
+static void
+_hover_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   elm_anchorview_hover_end(data);
+}
+
+static void
+_anchor_clicked(void *data, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Elm_Entry_Anchor_Info *info = event_info;
+   Evas_Object *hover_parent;
+   Elm_Entry_Anchorview_Info ei;
+   Evas_Coord x, w, y, h, px, py;
+   if (!wd) return;
+   wd->pop = elm_icon_add(obj);
+   evas_object_move(wd->pop, info->x, info->y);
+   evas_object_resize(wd->pop, info->w, info->h);
+   wd->hover = elm_hover_add(obj);
+   if (wd->hover_style) elm_object_style_set(wd->hover, wd->hover_style);
+   hover_parent = wd->hover_parent;
+   if (!hover_parent) hover_parent = obj;
+   elm_hover_parent_set(wd->hover, hover_parent);
+   elm_hover_target_set(wd->hover, wd->pop);
+   ei.name = info->name;
+   ei.button = info->button;
+   ei.hover = wd->hover;
+   ei.anchor.x = info->x;
+   ei.anchor.y = info->y;
+   ei.anchor.w = info->w;
+   ei.anchor.h = info->h;
+   evas_object_geometry_get(hover_parent, &x, &y, &w, &h);
+   ei.hover_parent.x = x;
+   ei.hover_parent.y = y;
+   ei.hover_parent.w = w;
+   ei.hover_parent.h = h;
+   px = info->x + (info->w / 2);
+   py = info->y + (info->h / 2);
+   ei.hover_left = 1;
+   if (px < (x + (w / 3))) ei.hover_left = 0;
+   ei.hover_right = 1;
+   if (px > (x + ((w * 2) / 3))) ei.hover_right = 0;
+   ei.hover_top = 1;
+   if (py < (y + (h / 3))) ei.hover_top = 0;
+   ei.hover_bottom = 1;
+   if (py > (y + ((h * 2) / 3))) ei.hover_bottom = 0;
+   evas_object_smart_callback_call(data, SIG_ANCHOR_CLICKED, &ei);
+   evas_object_smart_callback_add(wd->hover, "clicked", _hover_clicked, data);
+   evas_object_show(wd->hover);
+}
+
+static void
+_parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   wd->hover_parent = NULL;
+}
+
+static Evas_Object *
+_item_provider(void *data, Evas_Object *entry, const char *item)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Object *o;
+   Eina_List *l;
+   Elm_Anchorview_Item_Provider *ip;
+   
+   EINA_LIST_FOREACH(wd->item_providers, l, ip)
+     {
+        o = ip->func(ip->data, data, item);
+        if (o) return o;
+     }
+   return NULL;
+}
+
+/**
+ * Add a new Anchorview object
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Anchorview
+ */
+EAPI Evas_Object *
+elm_anchorview_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "anchorview");
+   elm_widget_type_set(obj, "anchorview");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_pre_hook_set(obj, _del_pre_hook);
+   elm_widget_del_hook_set(obj, _del_hook);
+
+   wd->scroller = elm_scroller_add(parent);
+   elm_widget_resize_object_set(obj, wd->scroller);
+   wd->entry = elm_entry_add(parent);
+   elm_entry_item_provider_prepend(wd->entry, _item_provider, obj);
+   elm_entry_editable_set(wd->entry, 0);
+   evas_object_size_hint_weight_set(wd->entry, 1.0, 1.0);
+   evas_object_size_hint_align_set(wd->entry, -1.0, -1.0);
+   elm_scroller_content_set(wd->scroller, wd->entry);
+   evas_object_show(wd->entry);
+
+   evas_object_event_callback_add(wd->entry, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                 _changed_size_hints, obj);
+
+   elm_entry_entry_set(wd->entry, "");
+
+   evas_object_smart_callback_add(wd->entry, "anchor,clicked",
+                                 _anchor_clicked, obj);
+
+   _sizing_eval(obj);
+
+   // TODO: convert Elementary to subclassing of Evas_Smart_Class
+   // TODO: and save some bytes, making descriptions per-class and not instance!
+   evas_object_smart_callbacks_descriptions_set(obj, _signals);
+   return obj;
+}
+
+/**
+  * Set the text markup of the anchorview
+  *
+  * This sets the text of the anchorview to be the text given as @p text. This
+  * text is in markup format with \<a href=XXX\> beginning an achor with the
+  * string link of 'XXX', and \</\> or \</a\> ending the link. Other markup can
+  * be used dependign on the style support.
+  *
+  * @param obj The anchorview object
+  * @param text The text to set, or NULL to clear
+  *
+  * @ingroup Anchorview
+  */
+EAPI void
+elm_anchorview_text_set(Evas_Object *obj, const char *text)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_entry_set(wd->entry, text);
+   if (wd->hover) evas_object_del(wd->hover);
+   if (wd->pop) evas_object_del(wd->pop);
+   wd->hover = NULL;
+   wd->pop = NULL;
+   _sizing_eval(obj);
+}
+
+/**
+  * Get the markup text set for the anchorview
+  *
+  * This retrieves back the string set by @c elm_anchorview_text_set().
+  *
+  * @param obj The anchorview object
+  * @return text The markup text set or @c NULL, either if it was not set
+  * or an error ocurred
+  *
+  * @ingroup Anchorview
+  */
+EAPI const char*
+elm_anchorview_text_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return elm_entry_entry_get(wd->entry);
+}
+
+/**
+  * Set the parent of the hover popup
+  *
+  * This sets the parent of the hover that anchorview will create. See hover
+  * objects for more information on this.
+  *
+  * @param obj The anchorview object
+  * @param parent The parent the hover should use
+  *
+  * @ingroup Anchorview
+  */
+EAPI void
+elm_anchorview_hover_parent_set(Evas_Object *obj, Evas_Object *parent)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->hover_parent)
+     evas_object_event_callback_del_full(wd->hover_parent, EVAS_CALLBACK_DEL, _parent_del, obj);
+   wd->hover_parent = parent;
+   if (wd->hover_parent)
+     evas_object_event_callback_add(wd->hover_parent, EVAS_CALLBACK_DEL, _parent_del, obj);
+}
+
+/**
+  * Set the style that the hover should use
+  *
+  * This sets the style for the hover that anchorview will create. See hover
+  * objects for more information
+  *
+  * @param obj The anchorview object
+  * @param style The style to use
+  *
+  * @ingroup Anchorview
+  */
+EAPI void
+elm_anchorview_hover_style_set(Evas_Object *obj, const char *style)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->hover_style, style);
+}
+
+/**
+  * Stop the hover popup in the anchorview
+  *
+  * This will stop the hover popup in the anchorview if it is currently active.
+  *
+  * @param obj The anchorview object
+  *
+  * @ingroup Anchorview
+  */
+EAPI void
+elm_anchorview_hover_end(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->hover) evas_object_del(wd->hover);
+   if (wd->pop) evas_object_del(wd->pop);
+   wd->hover = NULL;
+   wd->pop = NULL;
+}
+
+/**
+ * Set bounce mode
+ *
+ * This will enable or disable the scroller bounce mode for the anchorview. See
+ * elm_scroller_bounce_set() for details
+ *
+ * @param obj The anchorview anchorview
+ * @param h_bounce Allow bounce horizontally
+ * @param v_bounce Allow bounce vertically
+ *
+ * @ingroup Anchorview
+ */
+EAPI void
+elm_anchorview_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_scroller_bounce_set(wd->scroller, h_bounce, v_bounce);
+}
+
+/**
+ * This appends a custom item provider to the list for that anchorview
+ *
+ * This appends the given callback. The list is walked from beginning to end
+ * with each function called given the item href string in the text. If the
+ * function returns an object handle other than NULL (it should create an
+ * and object to do this), then this object is used to replace that item. If
+ * not the next provider is called until one provides an item object, or the
+ * default provider in anchorview does.
+ * 
+ * @param obj The anchorview object
+ * @param func The function called to provide the item object
+ * @param data The data passed to @p func
+ *
+ * @ingroup Anchorview
+ */
+EAPI void
+elm_anchorview_item_provider_append(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorview, const char *item), void *data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (!func) return;
+   Elm_Anchorview_Item_Provider *ip = calloc(1, sizeof(Elm_Anchorview_Item_Provider));
+   if (!ip) return;
+   ip->func = func;
+   ip->data = data;
+   wd->item_providers = eina_list_append(wd->item_providers, ip);
+}
+
+/**
+ * This prepends a custom item provider to the list for that anchorview
+ *
+ * This prepends the given callback. See elm_anchorview_item_provider_append() for
+ * more information
+ * 
+ * @param obj The anchorview object
+ * @param func The function called to provide the item object
+ * @param data The data passed to @p func
+ *
+ * @ingroup Anchorview
+ */
+EAPI void
+elm_anchorview_item_provider_prepend(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorview, const char *item), void *data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (!func) return;
+   Elm_Anchorview_Item_Provider *ip = calloc(1, sizeof(Elm_Anchorview_Item_Provider));
+   if (!ip) return;
+   ip->func = func;
+   ip->data = data;
+   wd->item_providers = eina_list_prepend(wd->item_providers, ip);
+}
+
+/**
+ * This removes a custom item provider to the list for that anchorview
+ *
+ * This removes the given callback. See elm_anchorview_item_provider_append() for
+ * more information
+ * 
+ * @param obj The anchorview object
+ * @param func The function called to provide the item object
+ * @param data The data passed to @p func
+ *
+ * @ingroup Anchorview
+ */
+EAPI void
+elm_anchorview_item_provider_remove(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorview, const char *item), void *data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Eina_List *l;
+   Elm_Anchorview_Item_Provider *ip;
+   if (!wd) return;
+   if (!func) return;
+   EINA_LIST_FOREACH(wd->item_providers, l, ip)
+     {
+        if ((ip->func == func) && (ip->data == data))
+          {
+             wd->item_providers = eina_list_remove_list(wd->item_providers, l);
+             free(ip);
+             return;
+          }
+     }
+}
diff --git a/src/lib/elc_fileselector.c b/src/lib/elc_fileselector.c
new file mode 100644 (file)
index 0000000..90a2e09
--- /dev/null
@@ -0,0 +1,809 @@
+/**
+ * @defgroup Fileselector Fileselector
+ *
+ * A fileselector is a widget that allows a user to navigate through a tree
+ * of files.  It contains buttons for Home(~) and Up(..) as well as cancel/ok
+ * buttons to confirm/cancel a selection.  This widget is currently very much
+ * in progress.
+ *
+ * TODO
+ * userdefined icon/label cb
+ * show/hide/add buttons ???
+ * need a background ???
+ * show/Hide hidden files
+ * double click to choose a file
+ * multiselection
+ * make variable/function names that are sensible
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * "selected" - the user clicks on a file
+ * "directory,open" - the list is populated with a new content. event_info is a directory.
+ * "done" - the user clicks on the ok or cancel button
+ */
+
+#include <Elementary.h>
+#include "elm_priv.h"
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *vbox, *entry, *entry2, *list, *scr2;
+   const char *path;
+   const char *selection;
+   Eina_Bool only_folder;
+   Eina_Bool expand;
+   Ecore_Idler *sel_idler;
+
+   struct
+   {
+    Evas_Object *bx;
+    Evas_Object *ok;
+    Evas_Object *cancel;
+   } buttons;
+};
+
+struct sel_data
+{
+   Evas_Object *fs;
+   const char *path;
+};
+
+Elm_Genlist_Item_Class itc;
+
+static const char *widtype = NULL;
+
+static const char SIG_DIRECTORY_OPEN[]= "directory,open";
+static const char SIG_DONE[] = "done";
+static const char SIG_SELECTED[] = "selected";
+static const Evas_Smart_Cb_Description _signals[] = {
+  {SIG_DIRECTORY_OPEN, "s"},
+  {SIG_DONE, "s"},
+  {SIG_SELECTED, "s"},
+  {NULL, NULL}
+};
+
+static void _populate(Evas_Object *obj, const char *path, Elm_Genlist_Item *parent);
+static void _do_anchors(Evas_Object *obj, const char *path);
+
+/***  ELEMENTARY WIDGET  ***/
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd;
+   void *sd;
+
+   wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   if (wd->path) eina_stringshare_del(wd->path);
+   if (wd->selection) eina_stringshare_del(wd->selection);
+   if (wd->sel_idler)
+     {
+       sd = ecore_idler_del(wd->sel_idler);
+       free(sd);
+     }
+   free(wd);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1;
+   if (!wd) return;
+   evas_object_size_hint_min_get(wd->vbox, &minw, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+//   printf("***** SIZING EVAL [min %d %d] *************\n", minw, minh);
+}
+
+/***  GENLIST "MODEL"  ***/
+static char*
+_itc_label_get(const void *data, Evas_Object *obj __UNUSED__, const char *source __UNUSED__)
+{
+   //~ printf("LABEL_GET: %s\n", (char*) data);
+   return strdup(ecore_file_file_get(data)); // NOTE this will be free() by the caller
+}
+
+static Evas_Object*
+_itc_icon_get(const void *data, Evas_Object *obj, const char *source)
+{
+   Evas_Object *ic;
+
+   //~ printf("ICON GET for %s (source: %s)\n", (char*)data, source);
+   if (!strcmp(source, "elm.swallow.icon"))
+     {
+       ic = elm_icon_add(obj);
+       if (ecore_file_is_dir((char*)data))
+         elm_icon_standard_set(ic, "folder");
+       else
+         elm_icon_standard_set(ic, "file");
+       evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+       evas_object_show(ic);
+       return ic;
+     }
+   return NULL;
+}
+
+static Eina_Bool
+_itc_state_get(const void *data __UNUSED__, Evas_Object *obj __UNUSED__, const char *source __UNUSED__)
+{
+   return EINA_FALSE;
+}
+
+static void
+_itc_del(const void *data, Evas_Object *obj __UNUSED__)
+{
+   //~ printf("DEL DATA [%s]\n", (char*)data);
+   eina_stringshare_del(data);
+}
+
+static void
+_expand_done(void *data, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Elm_Genlist_Item *it = event_info;
+   const char *path = elm_genlist_item_data_get(it);
+//   printf("EXPAND %s\n", path);
+   _populate(data, path, it);
+}
+
+static void
+_contract_done(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Elm_Genlist_Item *it = event_info;
+//   const char *path = elm_genlist_item_data_get(it);
+//   printf("CONTRACT %s\n", path);
+   elm_genlist_item_subitems_clear(it);
+}
+
+static void
+_expand_req(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Elm_Genlist_Item *it = event_info;
+   elm_genlist_item_expanded_set(it, 1);
+}
+
+static void
+_contract_req(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Elm_Genlist_Item *it = event_info;
+   elm_genlist_item_expanded_set(it, 0);
+}
+
+/***  PRIVATES  ***/
+static int
+_sel_do(void *data)
+{
+   struct sel_data *sd;
+   const char *path;
+   Widget_Data *wd;
+   const char *p;
+
+   sd = data;
+   wd = elm_widget_data_get(sd->fs);
+   path = sd->path;
+
+   if (ecore_file_is_dir(path))
+     {
+       //      printf("SELECTED DIR: %s\n", path);
+        if (wd->expand)
+          {
+             _do_anchors(sd->fs, path);
+             if (wd->entry2) elm_entry_entry_set(wd->entry2, "");
+          }
+        else
+          {
+             // keep a ref to path 'couse it will be destroyed by _populate
+             p = eina_stringshare_add(path);
+             _populate(sd->fs, p, NULL);
+             eina_stringshare_del(p);
+          }
+       goto end;
+     }
+   else
+     {
+       //      printf("SELECTED FILE: %s\n", path);
+       if (wd->entry2)
+         elm_entry_entry_set(wd->entry2, ecore_file_file_get(path));
+     }
+
+   evas_object_smart_callback_call(sd->fs, SIG_SELECTED, (void*)path);
+
+ end:
+   wd->sel_idler = NULL;
+   free(sd);
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_sel(void *data, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   struct sel_data *sd;
+   Widget_Data *wd;
+   void *old_sd;
+
+   wd = elm_widget_data_get(data);
+   if (!wd) return;
+
+   sd = malloc(sizeof(*sd));
+   sd->fs = data;
+   sd->path = elm_genlist_item_data_get(event_info);
+
+   if (wd->sel_idler)
+     {
+       old_sd = ecore_idler_del(wd->sel_idler);
+       free(old_sd);
+     }
+   wd->sel_idler = ecore_idler_add(_sel_do, sd);
+}
+
+static void
+_up(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Evas_Object *fs = data;
+   Widget_Data *wd = elm_widget_data_get(fs);
+   if (!wd) return;
+   char *parent = ecore_file_dir_get(wd->path);
+   _populate(fs, parent, NULL);
+   free(parent);
+}
+
+static void
+_home(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Evas_Object *fs = data;
+   _populate(fs, getenv("HOME"), NULL);
+}
+
+static void
+_ok(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Evas_Object *fs = data;
+   evas_object_smart_callback_call(fs, SIG_DONE,
+                                  (void*)elm_fileselector_selected_get(fs));
+}
+
+static void
+_canc(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Evas_Object *fs = data;
+   evas_object_smart_callback_call(fs, SIG_DONE, NULL);
+}
+
+static void
+_anchor_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Evas_Object *fs = data;
+   Widget_Data *wd = elm_widget_data_get(fs);
+   Elm_Entry_Anchor_Info *info = event_info;
+   const char *p;
+   if (!wd) return;
+   //~ printf("ANCHOR CLICKED %s\n", info->name);
+   // keep a ref to path 'couse it will be destroyed by _populate
+   p = eina_stringshare_add(info->name);
+   _populate(fs, p, NULL);
+   evas_object_smart_callback_call(data, SIG_SELECTED, (void*)p);
+   eina_stringshare_del(p);
+}
+
+static void
+_do_anchors(Evas_Object *obj, const char *path)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   char **tok, buf[PATH_MAX*3];
+   int i, j;
+   if (!wd) return;
+   //~ printf("ANCHORIZE...\n");
+   buf[0] = '\0';
+   tok = eina_str_split(path, "/", 0);
+   for (i = 0; tok[i]; i++)
+     {
+       if (strlen(tok[i]) < 1) continue;
+       //~ printf("TOK: %s\n", tok[i]);
+       eina_strlcat(buf, "/<a href=", sizeof(buf));
+       for (j = 0; j <= i; j++)
+         {
+            if (strlen(tok[j]) < 1) continue;
+            //~ printf("REV: %s\n",tok[j]);
+            eina_strlcat(buf, "/", sizeof(buf));
+            eina_strlcat(buf, tok[j], sizeof(buf));
+         }
+       eina_strlcat(buf, ">", sizeof(buf));
+       eina_strlcat(buf, tok[i], sizeof(buf));
+       eina_strlcat(buf, "</a>", sizeof(buf));
+     }
+   free(tok[0]);
+   free(tok);
+
+   //~ printf("ANCHOR: %s\n", buf);
+   elm_entry_entry_set(wd->entry, buf);
+}
+
+static void
+_populate(Evas_Object *obj, const char *path, Elm_Genlist_Item *parent)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   DIR *dir;
+   struct dirent *dp;
+   char buf[PATH_MAX];
+   char *real;
+   Eina_List *files = NULL, *dirs = NULL, *l;
+
+   if ((!wd) || (!ecore_file_is_dir(path))) return;
+   dir = opendir(path);
+   if (!dir) return;
+   evas_object_smart_callback_call(obj, SIG_DIRECTORY_OPEN, (void*)path);
+   if (!parent)
+     {
+       elm_genlist_clear(wd->list);
+       eina_stringshare_replace(&wd->path, path);
+       _do_anchors(obj, path);
+     }
+
+   if (wd->entry2) elm_entry_entry_set(wd->entry2, "");
+   while ((dp = readdir(dir)) != NULL)
+     {
+       if (dp->d_name[0] == '.') continue; // TODO make this configurable
+
+       snprintf(buf, sizeof(buf), "%s/%s", path, dp->d_name);
+       real = ecore_file_realpath(buf); //TODO this will resolv symlinks...I dont like it
+       if (ecore_file_is_dir(real))
+         dirs = eina_list_append(dirs, real);
+       else if(!wd->only_folder)
+         files = eina_list_append(files, real);
+     }
+   closedir(dir);
+
+   files = eina_list_sort(files, eina_list_count(files), EINA_COMPARE_CB(strcoll));
+   dirs = eina_list_sort(dirs, eina_list_count(dirs), EINA_COMPARE_CB(strcoll));
+   EINA_LIST_FOREACH(dirs, l, real)
+     {
+       //~ printf("DIR: %s\n", real);
+       elm_genlist_item_append(wd->list, &itc,
+                               eina_stringshare_add(real), /* item data */
+                               parent,
+                               wd->expand ? ELM_GENLIST_ITEM_SUBITEMS :
+                                ELM_GENLIST_ITEM_NONE,
+                               NULL, NULL);
+       free(real);
+     }
+   eina_list_free(dirs);
+
+   EINA_LIST_FOREACH(files, l, real)
+     {
+       //~ printf("FILE: %s [%p]\n", real, wd->list);
+       elm_genlist_item_append(wd->list, &itc,
+                               eina_stringshare_add(real), /* item data */
+                               parent, ELM_GENLIST_ITEM_NONE,
+                               NULL, NULL);
+       free(real);
+     }
+   eina_list_free(files);
+}
+
+/***  API  ***/
+/**
+ * Add a new Fileselector object
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Fileselector
+ */
+EAPI Evas_Object *
+elm_fileselector_add(Evas_Object *parent)
+{
+   Evas_Object *obj, *ic, *bt, *box;
+   Widget_Data *wd;
+
+   // Elementary Widget
+   wd = ELM_NEW(Widget_Data);
+   wd->expand = EINA_FALSE;
+   obj = elm_widget_add(evas_object_evas_get(parent));
+   ELM_SET_WIDTYPE(widtype, "fileselector");
+   elm_widget_type_set(obj, "fileselector");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+
+   // TODO Do we need a bg object? a frame?
+   // vbox
+   wd->vbox = elm_box_add(parent);
+   evas_object_size_hint_weight_set(wd->vbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_widget_resize_object_set(obj, wd->vbox);
+   evas_object_show(wd->vbox);
+
+   // buttons box
+   box = elm_box_add(parent);
+   elm_box_horizontal_set(box, 1);
+   elm_widget_sub_object_add(obj, box);
+   elm_box_pack_end(wd->vbox, box);
+   evas_object_size_hint_align_set(box, 0.0, 0.0);
+   evas_object_show(box);
+
+   // up btn
+   ic = elm_icon_add(parent);
+   elm_icon_standard_set(ic, "arrow_up");
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+   bt = elm_button_add(parent);
+   elm_button_icon_set(bt, ic);
+   elm_button_label_set(bt, "Up");
+   evas_object_size_hint_align_set(bt, 0.0, 0.0);
+   elm_widget_sub_object_add(obj, bt);
+   elm_box_pack_end(box, bt);
+   evas_object_smart_callback_add(bt, "clicked", _up, obj);
+   evas_object_show(bt);
+
+   // home btn
+   ic = elm_icon_add(parent);
+   elm_icon_standard_set(ic, "home");
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+   bt = elm_button_add(parent);
+   elm_button_icon_set(bt, ic);
+   elm_button_label_set(bt, "Home");
+   evas_object_size_hint_align_set(bt, 0.0, 0.0);
+   elm_widget_sub_object_add(obj, bt);
+   elm_box_pack_end(box, bt);
+   evas_object_smart_callback_add(bt, "clicked", _home, obj);
+   evas_object_show(bt);
+
+   // genlist
+   itc.item_style = "default";
+   itc.func.label_get = _itc_label_get;
+   itc.func.icon_get = _itc_icon_get;
+   itc.func.state_get = _itc_state_get;
+   itc.func.del = _itc_del;
+
+   wd->list = elm_genlist_add(parent);
+   evas_object_size_hint_align_set(wd->list, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(wd->list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_min_set(wd->list, 100, 100);
+   elm_widget_sub_object_add(obj, wd->list);
+   elm_box_pack_end(wd->vbox, wd->list);
+   evas_object_show(wd->list);
+
+   evas_object_smart_callback_add(wd->list, "selected", _sel, obj);
+   evas_object_smart_callback_add(wd->list, "expand,request", _expand_req, obj);
+   evas_object_smart_callback_add(wd->list, "contract,request", _contract_req, obj);
+   evas_object_smart_callback_add(wd->list, "expanded", _expand_done, obj);
+   evas_object_smart_callback_add(wd->list, "contracted", _contract_done, obj);
+
+   // path entry
+   wd->entry = elm_entry_add(parent);
+   elm_widget_sub_object_add(obj, wd->entry);
+   elm_entry_editable_set(wd->entry, 0);
+   elm_entry_single_line_set(wd->entry, EINA_FALSE);
+   elm_entry_line_char_wrap_set(wd->entry, EINA_TRUE);
+   evas_object_size_hint_weight_set(wd->entry, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(wd->entry, EVAS_HINT_FILL, 0.0);
+   elm_box_pack_end(wd->vbox, wd->entry);
+   evas_object_show(wd->entry);
+   evas_object_smart_callback_add(wd->entry, "anchor,clicked", _anchor_clicked, obj);
+
+   // name entry scroller
+   wd->scr2 = elm_scroller_add(parent);
+   elm_scroller_content_min_limit(wd->scr2, 0, 1);
+   elm_scroller_policy_set(wd->scr2, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
+   evas_object_size_hint_weight_set(wd->scr2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(wd->scr2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(wd->vbox, wd->scr2);
+   evas_object_show(wd->scr2);
+
+   elm_fileselector_buttons_ok_cancel_set(obj, 1);
+
+   // Is this the right way to show sub-objs ?? or use the show/hide cbs ??
+   //~ evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _show, obj);
+   //~ evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+   //~ _changed_size_hints, obj);
+   _sizing_eval(obj);
+
+   // TODO: convert Elementary to subclassing of Evas_Smart_Class
+   // TODO: and save some bytes, making descriptions per-class and not instance!
+   evas_object_smart_callbacks_descriptions_set(obj, _signals);
+   return obj;
+}
+
+/**
+ * This enables/disables the file name entry box where the user can
+ * type in a name for the file to be saved as.
+ *
+ * @param obj The fileselector object
+ * @param is_save If true, the fileselector is a save dialog
+ *
+ * @ingroup Fileselector
+ */
+EAPI void
+elm_fileselector_is_save_set(Evas_Object *obj, Eina_Bool is_save)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (is_save)
+     {
+       if (wd->entry2) return;
+       wd->entry2 = elm_entry_add(elm_widget_parent_get(obj));
+       elm_widget_sub_object_add(obj, wd->entry2);
+       elm_entry_editable_set(wd->entry2, 1);
+       elm_entry_single_line_set(wd->entry2, EINA_TRUE);
+       evas_object_size_hint_weight_set(wd->entry2, EVAS_HINT_EXPAND, 0.0);
+       evas_object_size_hint_align_set(wd->entry2, EVAS_HINT_FILL, 0.0);
+       elm_scroller_content_set(wd->scr2, wd->entry2);
+       evas_object_show(wd->entry2);
+     }
+   else
+     {
+       evas_object_del(wd->entry2);
+       wd->entry2 = NULL;
+     }
+}
+
+/**
+ * This returns whether the fileselector is a "save" type fileselector
+ *
+ * @param obj The fileselector object
+ * @return If true, the fileselector is a save type.
+ *
+ * @ingroup Fileselector
+ */
+EAPI Eina_Bool
+elm_fileselector_is_save_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->entry2 ? EINA_TRUE : EINA_FALSE;
+}
+
+
+/**
+ * This enables/disables folder-only view in the fileselector.
+ *
+ * @param obj The fileselector object
+ * @param only If true, the fileselector will only display directories.
+ * If false, files are displayed also.
+ *
+ * @ingroup Fileselector
+ */
+EAPI void
+elm_fileselector_folder_only_set(Evas_Object *obj, Eina_Bool only)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->only_folder == only) return;
+   wd->only_folder = only;
+}
+
+
+/**
+ * This gets the state of file display in the fileselector.
+ *
+ * @param obj The fileselector object
+ * @return If true, files are not being shown in the fileselector.
+ * If false, files are being shown.
+ *
+ * @ingroup Fileselector
+ */
+EAPI Eina_Bool
+elm_fileselector_folder_only_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->only_folder;
+}
+
+
+/**
+ * This enables/disables the file name entry box where the user can
+ * type in the name of a file to be selected.
+ *
+ * @param obj The fileselector object
+ * @param only If true, a box containing ok and cancel buttons is created.
+ * If false, the box and the buttons are destroyed.
+ *
+ * @ingroup Fileselector
+ */
+EAPI void
+elm_fileselector_buttons_ok_cancel_set(Evas_Object *obj, Eina_Bool only)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *box, *bt;
+   if (!wd) return;
+   if (only)
+     {
+       if (wd->buttons.bx) return;
+        // buttons box
+        box = elm_box_add(obj);
+        wd->buttons.bx = box;
+        elm_box_horizontal_set(box, 1);
+        elm_widget_sub_object_add(obj, box);
+        elm_box_pack_end(wd->vbox, box);
+        evas_object_show(box);
+
+        // cancel btn
+        bt = elm_button_add(obj);
+        wd->buttons.cancel = bt;
+        elm_button_label_set(bt, "Cancel");
+        elm_widget_sub_object_add(obj, bt);
+        elm_box_pack_end(box, bt);
+        evas_object_smart_callback_add(bt, "clicked", _canc, obj);
+        evas_object_show(bt);
+
+        // ok btn
+        bt = elm_button_add(obj);
+        wd->buttons.ok = bt;
+        elm_button_label_set(bt, "OK");
+        elm_widget_sub_object_add(obj, bt);
+        elm_box_pack_end(box, bt);
+        evas_object_smart_callback_add(bt, "clicked", _ok, obj);
+        evas_object_show(bt);
+     }
+   else
+     {
+        evas_object_del(wd->buttons.bx);
+        evas_object_del(wd->buttons.ok);
+        evas_object_del(wd->buttons.cancel);
+       wd->buttons.bx = NULL;
+     }
+}
+
+
+/**
+ * This gets the state of the box containing ok and cancel buttons.
+ *
+ * @param obj The fileselector object
+ * @return If true, the box exists.
+ * If false, the box does not exist.
+ *
+ * @ingroup Fileselector
+ */
+EAPI Eina_Bool
+elm_fileselector_buttons_ok_cancel_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->buttons.bx ? EINA_TRUE : EINA_FALSE;
+}
+
+
+/**
+ * This enables tree view in the fileselector.  Arrows are created on the
+ * sides of directories, allowing them to expand in place.
+ *
+ * @param obj The fileselector object
+ * @param expand If true, tree view is enabled.
+ * If false, tree view is disabled.
+ *
+ * @ingroup Fileselector
+ */
+EAPI void
+elm_fileselector_expandable_set(Evas_Object *obj, Eina_Bool expand)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd;
+
+   wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   wd->expand = expand;
+}
+
+/**
+ * This gets the state of tree view in the fileselector.
+ *
+ * @param obj The fileselector object
+ * @return If true, tree view is enabled and folders will be expandable.
+ * If false, tree view is disabled.
+ *
+ * @ingroup Fileselector
+ */
+EAPI Eina_Bool
+elm_fileselector_expandable_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->expand;
+}
+
+/**
+ * This sets the path that the fileselector will display.
+ *
+ * @param obj The fileselector object
+ * @param path The path of the fileselector
+ *
+ * @ingroup Fileselector
+ */
+EAPI void
+elm_fileselector_path_set(Evas_Object *obj, const char *path)
+{
+   _populate(obj, path, NULL);
+}
+
+/**
+ * This gets the path that the fileselector displays.
+ *
+ * @param obj The fileselector object
+ * @return The path that the fileselector is displaying
+ *
+ * @ingroup Fileselector
+ */
+EAPI const char *
+elm_fileselector_path_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->path;
+}
+
+/**
+ * This gets the currently selected path in the file selector.
+ *
+ * @param obj The file selector object
+ * @return The absolute path of the selected object in the fileselector
+ *
+ * @ingroup Fileselector
+ */
+EAPI const char *
+elm_fileselector_selected_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_Genlist_Item *it;
+   if (!wd) return NULL;
+   if (wd->entry2)
+     {
+       const char *name;
+       char buf[PATH_MAX];
+
+       name = elm_entry_entry_get(wd->entry2);
+       //TODO remove <br>
+       snprintf(buf, sizeof(buf), "%s/%s", wd->path, name);
+       eina_stringshare_replace(&wd->selection, buf);
+       return wd->selection;
+     }
+
+   it = elm_genlist_selected_item_get(wd->list);
+   if (it) return elm_genlist_item_data_get(it);
+
+   return wd->path;
+}
+
+/**
+ * This sets the currently selected path in the file selector.
+ *
+ * @param obj The file selector object
+ * @param path The path to a file or directory
+ * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. The
+ * latter case occurs if the directory or file pointed to do not
+ * exist.
+ *
+ * @ingroup Fileselector
+ */
+EAPI Eina_Bool
+elm_fileselector_selected_set(Evas_Object *obj, const char *path)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+
+   if (ecore_file_is_dir(path)) _populate(obj, path, NULL);
+   else
+     {
+       if (!ecore_file_exists(path)) return EINA_FALSE;
+
+       _populate(obj, ecore_file_dir_get(path), NULL);
+       if (wd->entry2)
+         {
+            elm_entry_entry_set(wd->entry2, ecore_file_file_get(path));
+            eina_stringshare_replace(&wd->selection, path);
+         }
+     }
+
+   return EINA_TRUE;
+}
diff --git a/src/lib/elc_fileselector_button.c b/src/lib/elc_fileselector_button.c
new file mode 100644 (file)
index 0000000..f753588
--- /dev/null
@@ -0,0 +1,752 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+ /**
+ * @defgroup File_Selector_Button File Selector Button
+ *
+ * A button that, when clicked, creates an Elementary window (or inner
+ * window) with an Elementary File Selector within. When a file is
+ * chosen, the (inner) window is closed and the selected file is
+ * exposed as an evas_object_smart_callback_call() of the button.
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *btn, *icon, *fs;
+   const char *window_title;
+   const char *btn_label;
+   Evas_Coord w, h;
+   struct {
+      const char *path;
+      Eina_Bool expandable:1;
+      Eina_Bool folder_only:1;
+      Eina_Bool is_save:1;
+   } fsd;
+   Eina_Bool inwin_mode:1;
+};
+
+static const char DEFAULT_WINDOW_TITLE[] = "Select a file";
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _disable_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+static void _signal_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_pressed(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_unpressed(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _on_focus_hook(void *data, Evas_Object *obj);
+static void _selection_done(void *data, Evas_Object *obj, void *event_info);
+
+static const char SIG_CLICKED[] = "clicked";
+static const char SIG_UNPRESSED[] = "unpressed";
+static const char SIG_FILE_CHOSEN[] = "file,chosen";
+static const Evas_Smart_Cb_Description _signals[] = {
+  {SIG_CLICKED, ""},
+  {SIG_UNPRESSED, ""},
+  {SIG_FILE_CHOSEN, "s"},
+  {NULL, NULL}
+};
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Evas_Object *win;
+   Widget_Data *wd;
+
+   wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   if (wd->btn_label) eina_stringshare_del(wd->btn_label);
+   if (wd->window_title) eina_stringshare_del(wd->window_title);
+   if (wd->fsd.path) eina_stringshare_del(wd->fsd.path);
+   if (wd->fs)
+     {
+       win = evas_object_data_del(obj, "win");
+       evas_object_del(win);
+     }
+   free(wd);
+}
+
+static void
+_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (elm_widget_focus_get(obj))
+     {
+       edje_object_signal_emit(wd->btn, "elm,action,focus", "elm");
+       evas_object_focus_set(wd->btn, 1);
+     }
+   else
+     {
+       edje_object_signal_emit(wd->btn, "elm,action,unfocus", "elm");
+       evas_object_focus_set(wd->btn, 0);
+     }
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _elm_theme_object_set(obj, wd->btn, "button", "base", elm_widget_style_get(obj));
+   if (wd->icon)
+     edje_object_part_swallow(wd->btn, "elm.swallow.content", wd->icon);
+   if (wd->btn_label)
+     edje_object_signal_emit(wd->btn, "elm,state,text,visible", "elm");
+   else
+     edje_object_signal_emit(wd->btn, "elm,state,text,hidden", "elm");
+   if (wd->icon)
+     edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm");
+   else
+     edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");
+   edje_object_part_text_set(wd->btn, "elm.text", wd->btn_label);
+   edje_object_message_signal_process(wd->btn);
+   edje_object_scale_set(wd->btn, elm_widget_scale_get(obj) *  \
+                        _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+static void
+_disable_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (elm_widget_disabled_get(obj))
+     edje_object_signal_emit(wd->btn, "elm,state,disabled", "elm");
+   else
+     edje_object_signal_emit(wd->btn, "elm,state,enabled", "elm");
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+
+   if (!wd) return;
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   edje_object_size_min_restricted_calc(wd->btn, &minw, &minh, minw, minh);
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (obj != wd->icon) return;
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *sub = event_info;
+   if (!wd) return;
+   if (sub == wd->icon)
+     {
+       edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");
+       evas_object_event_callback_del_full(sub,
+                                           EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                           _changed_size_hints, obj);
+       wd->icon = NULL;
+       edje_object_message_signal_process(wd->btn);
+       _sizing_eval(obj);
+     }
+}
+
+static void
+_signal_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+
+   evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
+
+   /* safe guard when the theme does not emit the 'unpress' signal */
+   _signal_unpressed(data, obj, emission, source);
+}
+
+static Evas_Object *
+_parent_win_get(Evas_Object *obj)
+{
+   Evas_Object *ret;
+
+   ret = elm_object_parent_widget_get(obj);
+   if (!ret) return NULL;
+
+   if (strcmp(elm_widget_type_get(ret), "win") != 0)
+     {
+       DBG("Widget type (%s) is not \"win\", going up\n",
+           elm_widget_type_get(ret));
+       return _parent_win_get(ret);
+     }
+
+   return ret;
+}
+
+static Evas_Object *
+_new_window_add(Widget_Data *wd)
+{
+   Evas_Object *win, *bg;
+
+   win = elm_win_add(NULL, "fileselector_button", ELM_WIN_DIALOG_BASIC);
+   elm_win_title_set(win, wd->window_title);
+   elm_win_autodel_set(win, EINA_TRUE);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   evas_object_resize(win, wd->w, wd->h);
+   return win;
+}
+
+static void
+_fs_launch(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Evas_Object *fs_btn, *win, *iw;
+   Eina_Bool win_fallback;
+   Widget_Data *wd;
+
+   fs_btn = data;
+   wd = elm_widget_data_get(fs_btn);
+
+   if (!wd) return;
+   if (wd->fs) return;
+
+   win_fallback = EINA_FALSE;
+   if (wd->inwin_mode)
+     {
+       win = _parent_win_get(fs_btn);
+
+       if (!win)
+         {
+            ERR("No elementary window found as parent of the file selector "
+                "button! Launching the file selector inside a new elementary"
+                " window, then.");
+            win_fallback = EINA_TRUE;
+         }
+       else
+         {
+            iw = elm_win_inwin_add(win);
+            evas_object_data_set(fs_btn, "win", iw);
+         }
+     }
+
+   if (!wd->inwin_mode || win_fallback)
+     {
+       win = _new_window_add(wd);
+       evas_object_data_set(fs_btn, "win", win);
+     }
+
+   wd->fs = elm_fileselector_add(win);
+   elm_fileselector_expandable_set(wd->fs, wd->fsd.expandable);
+   elm_fileselector_folder_only_set(wd->fs, wd->fsd.folder_only);
+   elm_fileselector_is_save_set(wd->fs, wd->fsd.is_save);
+   elm_fileselector_selected_set(wd->fs, wd->fsd.path);
+   evas_object_size_hint_weight_set(wd->fs, EVAS_HINT_EXPAND,
+                                   EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(wd->fs, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_smart_callback_add(wd->fs, "done", _selection_done, fs_btn);
+   evas_object_show(wd->fs);
+
+   if (wd->inwin_mode && !win_fallback)
+     {
+       elm_win_inwin_content_set(iw, wd->fs);
+       elm_win_inwin_activate(iw);
+     }
+   else
+     {
+       elm_win_resize_object_add(win, wd->fs);
+       evas_object_show(win);
+     }
+}
+
+static void
+_selection_done(void *data, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Evas_Object *fs_btn, *win;
+   const char *file;
+   Widget_Data *wd;
+
+   file = event_info;
+   fs_btn = data;
+
+   wd = elm_widget_data_get(fs_btn);
+   if (!wd) return;
+
+   win = evas_object_data_del(fs_btn, "win");
+
+   evas_object_smart_callback_call(fs_btn, SIG_FILE_CHOSEN, event_info);
+   if (file) eina_stringshare_replace(&wd->fsd.path, file);
+
+   wd->fs = NULL;
+   evas_object_del(win);
+}
+
+static void
+_signal_pressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+}
+
+static void
+_signal_unpressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   evas_object_smart_callback_call(data, SIG_UNPRESSED, NULL);
+}
+
+/**
+ * Add a new file selector button into the parent object.
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI Evas_Object *
+elm_fileselector_button_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   wd->window_title = eina_stringshare_add(DEFAULT_WINDOW_TITLE);
+   wd->fsd.path = eina_stringshare_add(getenv("HOME"));
+   wd->w = 400;
+   wd->h = 400;
+
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "fileselector_button");
+   elm_widget_type_set(obj, "fileselector_button");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_disable_hook_set(obj, _disable_hook);
+   elm_widget_can_focus_set(obj, 1);
+
+   wd->btn = edje_object_add(e);
+   _elm_theme_object_set(obj, wd->btn, "button", "base", "default");
+   edje_object_signal_callback_add(wd->btn, "elm,action,click", "",
+                                   _signal_clicked, obj);
+   edje_object_signal_callback_add(wd->btn, "elm,action,click", "",
+                                   _fs_launch, obj);
+   edje_object_signal_callback_add(wd->btn, "elm,action,press", "",
+                                   _signal_pressed, obj);
+   edje_object_signal_callback_add(wd->btn, "elm,action,unpress", "",
+                                   _signal_unpressed, obj);
+   elm_widget_resize_object_set(obj, wd->btn);
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+
+   _sizing_eval(obj);
+
+   // TODO: convert Elementary to subclassing of Evas_Smart_Class
+   // TODO: and save some bytes, making descriptions per-class and not instance!
+   evas_object_smart_callbacks_descriptions_set(obj, _signals);
+   return obj;
+}
+
+/**
+ * Set the label used in the file selector button.
+ *
+ * @param obj The button object
+ * @param label The text label text to be displayed on the button
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI void
+elm_fileselector_button_label_set(Evas_Object *obj, const char *label)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->btn_label, label);
+   if (label)
+     edje_object_signal_emit(wd->btn, "elm,state,text,visible", "elm");
+   else
+     edje_object_signal_emit(wd->btn, "elm,state,text,hidden", "elm");
+   edje_object_message_signal_process(wd->btn);
+   edje_object_part_text_set(wd->btn, "elm.text", label);
+   _sizing_eval(obj);
+}
+
+EAPI const char *
+elm_fileselector_button_label_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->btn_label;
+}
+
+/**
+ * Set the path to start the button's file selector with, when clicked.
+ *
+ * @param obj The button object
+ * @param path Path to a file/directory
+ *
+ * Default path is "HOME" environment variable's value.
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI void
+elm_fileselector_button_selected_set(Evas_Object *obj, const char *path)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   eina_stringshare_replace(&wd->fsd.path, path);
+}
+
+/**
+ * Get the <b>last</b> path which the button's file selector was set to.
+ *
+ * @param obj The button object
+ * @param path Path to a file/directory
+ *
+ * Default path is "HOME" environment variable's value.
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI const char *
+elm_fileselector_button_selected_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->fsd.path;
+}
+
+/**
+ * Set the title of the file selector button's window.
+ *
+ * @param obj The button object
+ * @param title The title string
+ *
+ * Note that it will only take any effect if the fileselector button
+ * not at "inwin mode".
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI void
+elm_fileselector_button_window_title_set(Evas_Object *obj, const char *title)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->window_title, title);
+}
+
+/**
+ * Get the title of the file selector button's window.
+ *
+ * @param obj The button object
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI const char *
+elm_fileselector_button_window_title_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->window_title;
+}
+
+/**
+ * Set the size of the file selector button's window.
+ *
+ * @param obj The button object
+ * @param width The width
+ * @param height The height
+ *
+ * Note that it will only take any effect if the fileselector button not at
+ * "inwin mode". Default size for the window (when applicable) is 400x400.
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI void
+elm_fileselector_button_window_size_set(Evas_Object *obj, Evas_Coord width, Evas_Coord height)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   wd->w = width;
+   wd->h = height;
+}
+
+/**
+ * Get the size of the file selector button's window.
+ *
+ * @param obj The button object
+ * @param width Pointer into which to store the width value
+ * @param height Pointer into which to store the height value
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI void
+elm_fileselector_button_window_size_get(Evas_Object *obj, Evas_Coord *width, Evas_Coord *height)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   if (width) *width = wd->w;
+   if (height) *height = wd->h;
+}
+
+/**
+ * Set the starting path of the file selector button's window.
+ *
+ * @param obj The button object
+ * @param path The path string
+ *
+ * It must be a <b>directory</b> path.
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI void
+elm_fileselector_button_path_set(Evas_Object *obj, const char *path)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->fsd.path, path);
+}
+
+/**
+ * Get the <b>last</b> path of the file selector button's window.
+ *
+ * @param obj The button object
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI const char *
+elm_fileselector_button_path_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->fsd.path;
+}
+
+/**
+ * Set whether the button's file selector is to present itself as an
+ * Elementary Generic List (which will expand its entries for nested
+ * directories) or as canonical list, which will be rendered again
+ * with the contents of each selected directory.
+ *
+ * @param obj The button object
+ * @param value The expandable flag
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI void
+elm_fileselector_button_expandable_set(Evas_Object *obj, Eina_Bool value)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   wd->fsd.expandable = value;
+}
+
+/**
+ * Get the button's file selector expandable flag.
+ *
+ * @param obj The button object
+ * @return value The expandable flag
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI Eina_Bool
+elm_fileselector_button_expandable_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+
+   return wd->fsd.expandable;
+}
+
+/**
+ * Set whether the button's file selector list is to display folders
+ * only or the directory contents, as well.
+ *
+ * @param obj The button object
+ * @param value The "folder only" flag
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI void
+elm_fileselector_button_folder_only_set(Evas_Object *obj, Eina_Bool value)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   wd->fsd.folder_only = value;
+}
+
+/**
+ * Get the button's file selector "folder only" flag.
+ *
+ * @param obj The button object
+ * @return value The "folder only" flag
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI Eina_Bool
+elm_fileselector_button_folder_only_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+
+   return wd->fsd.folder_only;
+}
+
+/**
+ * Set whether the button's file selector has an editable text entry
+ * which will hold its current selection.
+ *
+ * @param obj The button object
+ * @param value The "is save" flag
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI void
+elm_fileselector_button_is_save_set(Evas_Object *obj, Eina_Bool value)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   wd->fsd.is_save = value;
+}
+
+/**
+ * Get the button's file selector "is save" flag.
+ *
+ * @param obj The button object
+ * @return value The "is save" flag
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI Eina_Bool
+elm_fileselector_button_is_save_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+
+   return wd->fsd.is_save;
+}
+
+/**
+ * Set whether the button's file selector will raise an Elementary
+ * Inner Window, instead of a dedicated Elementary Window. By default,
+ * it won't.
+ *
+ * @param obj The button object
+ * @param value The "inwin mode" flag
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI void
+elm_fileselector_button_inwin_mode_set(Evas_Object *obj, Eina_Bool value)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   wd->inwin_mode = value;
+}
+
+/**
+ * Get the button's file selector "inwin mode" flag.
+ *
+ * @param obj The button object
+ * @return value The "inwin mode" flag
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI Eina_Bool
+elm_fileselector_button_inwin_mode_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+
+   return wd->inwin_mode;
+}
+
+/**
+ * Set the icon used for the button
+ *
+ * @param obj The button object
+ * @param icon  The image for the button
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI void
+elm_fileselector_button_icon_set(Evas_Object *obj, Evas_Object *icon)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if ((wd->icon != icon) && (wd->icon))
+     elm_widget_sub_object_del(obj, wd->icon);
+   if ((icon) && (wd->icon != icon))
+     {
+       wd->icon = icon;
+       elm_widget_sub_object_add(obj, icon);
+       evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                      _changed_size_hints, obj);
+       edje_object_part_swallow(wd->btn, "elm.swallow.content", icon);
+       edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm");
+       edje_object_message_signal_process(wd->btn);
+       _sizing_eval(obj);
+     }
+   else
+     wd->icon = icon;
+}
+
+/**
+ * Get the icon used for the button
+ *
+ * @param obj The button object
+ * @return The image for the button
+ *
+ * @ingroup File_Selector_Button
+ */
+EAPI Evas_Object *
+elm_fileselector_button_icon_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->icon;
+}
diff --git a/src/lib/elc_hoversel.c b/src/lib/elc_hoversel.c
new file mode 100644 (file)
index 0000000..ddcb156
--- /dev/null
@@ -0,0 +1,653 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Hoversel
+ *
+ * A hoversel is a button that pops up a list of items (automatically
+ * choosing the direction to display) that have a lable and/or an icon to
+ * select from. It is a convenience widget to avoid the need to do all the
+ * piecing together yourself. It is intended for a small number of items in
+ * the hoversel menu (no more than 8), though is capable of many more.
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * clicked  - the user clicked the hoversel button and popped up the sel
+ *
+ * selected - an item in the hoversel list is selected. event_info is the item
+ * selected - Elm_Hoversel_Item
+ *
+ * dismissed - the hover is dismissed
+ */
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *btn, *hover;
+   Evas_Object *hover_parent;
+   Eina_List *items;
+   Eina_Bool horizontal : 1;
+};
+
+struct _Elm_Hoversel_Item
+{
+   Evas_Object *obj;
+   const char *label;
+   const char *icon_file;
+   const char *icon_group;
+   Elm_Icon_Type icon_type;
+   Evas_Smart_Cb func;
+   Evas_Smart_Cb del_cb;
+   void *data;
+};
+
+static const char *widtype = NULL;
+static void _del_pre_hook(Evas_Object *obj);
+static void _del_hook(Evas_Object *obj);
+static void _disable_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _parent_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+static void
+_del_pre_hook(Evas_Object *obj)
+{
+   Elm_Hoversel_Item *it;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_hoversel_hover_end(obj);
+   elm_hoversel_hover_parent_set(obj, NULL);
+   EINA_LIST_FREE(wd->items, it)
+     {
+       if (it->del_cb) it->del_cb((void *)it->data, it->obj, it);
+       eina_stringshare_del(it->label);
+       eina_stringshare_del(it->icon_file);
+       eina_stringshare_del(it->icon_group);
+       free(it);
+     }
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   char buf[4096];
+   if (!wd) return;
+   elm_hoversel_hover_end(obj);
+   if (wd->horizontal)
+     snprintf(buf, sizeof(buf), "hoversel_horizontal/%s", elm_widget_style_get(obj));
+   else
+     snprintf(buf, sizeof(buf), "hoversel_vertical/%s", elm_widget_style_get(obj));
+   elm_object_style_set(wd->btn, buf);
+}
+
+static void
+_disable_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (elm_widget_disabled_get(obj))
+     elm_widget_disabled_set(wd->btn, 1);
+   else
+     elm_widget_disabled_set(wd->btn, 0);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   if (!wd) return;
+   evas_object_size_hint_min_get(wd->btn, &minw, &minh);
+   evas_object_size_hint_max_get(wd->btn, &maxw, &maxh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+}
+
+static void
+_hover_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   elm_hoversel_hover_end(data);
+}
+
+static void
+_item_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Elm_Hoversel_Item *it = data;
+   Evas_Object *obj2 = it->obj;
+
+   elm_hoversel_hover_end(obj2);
+   if (it->func) it->func(it->data, obj2, it);
+   evas_object_smart_callback_call(obj2, "selected", it);
+}
+
+static void
+_activate(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *bt, *bx, *ic;
+   const Eina_List *l;
+   const Elm_Hoversel_Item *it;
+   char buf[4096];
+
+   if (!wd) return;
+   if (elm_widget_disabled_get(obj)) return;
+   wd->hover = elm_hover_add(obj);
+   if (wd->horizontal)
+     snprintf(buf, sizeof(buf), "hoversel_horizontal/%s", elm_widget_style_get(obj));
+   else
+     snprintf(buf, sizeof(buf), "hoversel_vertical/%s", elm_widget_style_get(obj));
+   elm_object_style_set(wd->hover, buf);
+   evas_object_smart_callback_add(wd->hover, "clicked", _hover_clicked, obj);
+   elm_hover_parent_set(wd->hover, wd->hover_parent);
+   elm_hover_target_set(wd->hover, wd->btn);
+
+   bx = elm_box_add(wd->hover);
+   elm_box_homogenous_set(bx, 1);
+   
+   elm_box_horizontal_set(bx, wd->horizontal);
+   
+   if (wd->horizontal)
+     snprintf(buf, sizeof(buf), "hoversel_horizontal_entry/%s",
+              elm_widget_style_get(obj));
+   else
+     snprintf(buf, sizeof(buf), "hoversel_vertical_entry/%s",
+              elm_widget_style_get(obj));
+   EINA_LIST_FOREACH(wd->items, l, it)
+     {
+       bt = elm_button_add(wd->hover);
+       elm_object_style_set(bt, buf);
+       elm_button_label_set(bt, it->label);
+       if (it->icon_file)
+         {
+            ic = elm_icon_add(obj);
+            elm_icon_scale_set(ic, 0, 1);
+            if (it->icon_type == ELM_ICON_FILE)
+              elm_icon_file_set(ic, it->icon_file, it->icon_group);
+            else if (it->icon_type == ELM_ICON_STANDARD)
+              elm_icon_standard_set(ic, it->icon_file);
+            elm_button_icon_set(bt, ic);
+            evas_object_show(ic);
+         }
+       evas_object_size_hint_weight_set(bt, 1.0, 0.0);
+       evas_object_size_hint_align_set(bt, -1.0, -1.0);
+       elm_box_pack_end(bx, bt);
+       evas_object_smart_callback_add(bt, "clicked", _item_clicked, it);
+       evas_object_show(bt);
+     }
+
+   if (wd->horizontal)
+     elm_hover_content_set(wd->hover,
+                           elm_hover_best_content_location_get(wd->hover,
+                                                               ELM_HOVER_AXIS_HORIZONTAL),
+                           bx);
+   else
+     elm_hover_content_set(wd->hover,
+                           elm_hover_best_content_location_get(wd->hover,
+                                                               ELM_HOVER_AXIS_VERTICAL),
+                           bx);
+   evas_object_show(bx);
+
+   evas_object_show(wd->hover);
+   evas_object_smart_callback_call(obj, "clicked", NULL);
+
+//   if (wd->horizontal) evas_object_hide(wd->btn);
+}
+
+static void
+_button_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _activate(data);
+}
+
+static void
+_parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   wd->hover_parent = NULL;
+}
+
+/**
+ * Add a new Hoversel object
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Hoversel
+ */
+EAPI Evas_Object *
+elm_hoversel_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+   char buf[4096];
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "hoversel");
+   elm_widget_type_set(obj, "hoversel");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_pre_hook_set(obj, _del_pre_hook);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_disable_hook_set(obj, _disable_hook);
+
+   wd->btn = elm_button_add(parent);
+   if (wd->horizontal)
+     snprintf(buf, sizeof(buf), "hoversel_horizontal/%s", elm_widget_style_get(obj));
+   else
+     snprintf(buf, sizeof(buf), "hoversel_vertical/%s", elm_widget_style_get(obj));
+   elm_object_style_set(wd->btn, buf);
+   elm_widget_resize_object_set(obj, wd->btn);
+   evas_object_event_callback_add(wd->btn, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                 _changed_size_hints, obj);
+   evas_object_smart_callback_add(wd->btn, "clicked", _button_clicked, obj);
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Set the Hover parent
+ *
+ * Sets the hover parent object. Should probably be the window that the hoversel
+ * is in.  See Hover objects for more information.
+ *
+ * @param obj The hoversel object
+ * @param parent The parent to use
+ *
+ * @ingroup Hoversel
+ */
+EAPI void
+elm_hoversel_hover_parent_set(Evas_Object *obj, Evas_Object *parent)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->hover_parent)
+     evas_object_event_callback_del_full(wd->hover_parent, EVAS_CALLBACK_DEL,
+                                    _parent_del, obj);
+   wd->hover_parent = parent;
+   if (wd->hover_parent)
+     evas_object_event_callback_add(wd->hover_parent, EVAS_CALLBACK_DEL,
+                                    _parent_del, obj);
+}
+
+/**
+ * Set the hoversel button label
+ *
+ * This sets the label of the button that is always visible (before it is
+ * clicked and expanded). Also see elm_button_label_set().
+ *
+ * @param obj The hoversel object
+ * @param label The label text.
+ *
+ * @ingroup Hoversel
+ */
+EAPI void
+elm_hoversel_label_set(Evas_Object *obj, const char *label)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_button_label_set(wd->btn, label);
+}
+
+/**
+ * Get the hoversel button label
+ *
+ * @param obj The hoversel object
+ * @return The label text.
+ *
+ * @ingroup Hoversel
+ */
+EAPI const char *
+elm_hoversel_label_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if ((!wd) || (!wd->btn)) return NULL;
+   return elm_button_label_get(wd->btn);
+}
+
+/**
+ * This sets the hoversel to expand horizontally.  The initial button
+ * will display horizontally regardless of this setting.
+ *
+ * @param obj The hoversel object
+ * @param horizontal If true, the hover will expand horizontally to the right.
+ *
+ * @ingroup Hoversel
+ */
+EAPI void
+elm_hoversel_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->horizontal = !!horizontal;
+}
+
+
+/**
+ * This returns whether the hoversel is set to expand horizontally.
+ *
+ * @param obj The hoversel object
+ * @return If true, the hover will expand horizontally to the right.
+ *
+ * @ingroup Hoversel
+ */
+EAPI Eina_Bool
+elm_hoversel_horizontal_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->horizontal;
+}
+
+/**
+ * Set the icon of the hoversel button
+ *
+ * Sets the icon of the button that is always visible (before it is clicked
+ * and expanded). Also see elm_button_icon_set().
+ *
+ * @param obj The hoversel object
+ * @param icon The icon object
+ *
+ * @ingroup Hoversel
+ */
+EAPI void
+elm_hoversel_icon_set(Evas_Object *obj, Evas_Object *icon)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_button_icon_set(wd->btn, icon);
+}
+
+/**
+ * Get the icon of the hoversel button
+ *
+ * Get the icon of the button that is always visible (before it is clicked
+ * and expanded). Also see elm_button_icon_get().
+ *
+ * @param obj The hoversel object
+ * @return The icon object
+ *
+ * @ingroup Hoversel
+ */
+EAPI Evas_Object *
+elm_hoversel_icon_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if ((!wd) || (!wd->btn)) return NULL;
+   return elm_button_icon_get(wd->btn);
+}
+
+/**
+ * This triggers the hoversel popup from code, the same as though the
+ * user clicked the button.
+ *
+ * @param obj The hoversel object
+ *
+ * @ingroup Hoversel
+ */
+EAPI void
+elm_hoversel_hover_begin(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->hover) return;
+   _activate(obj);
+}
+
+/**
+ * This ends the hoversel popup as though the user clicked outside the hover.
+ *
+ * @param obj The hoversel object
+ *
+ * @ingroup Hoversel
+ */
+EAPI void
+elm_hoversel_hover_end(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (!wd->hover) return;
+   evas_object_del(wd->hover);
+   wd->hover = NULL;
+   evas_object_smart_callback_call(obj, "dismissed", NULL);
+}
+
+/**
+ * Returns whether the hoversel is expanded.
+ *
+ * @param obj The hoversel object
+ * @return  This will return EINA_TRUE if the hoversel
+ * is expanded or EINA_FALSE if it is not expanded.
+ *
+ * @ingroup Hoversel
+ */
+EAPI Eina_Bool
+elm_hoversel_expanded_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return (wd->hover) ? EINA_TRUE : EINA_FALSE;
+}
+  
+/**
+ * This will remove all the children items from the hoversel. (should not be
+ * called while the hoversel is active; use elm_hoversel_expanded_get()
+ * to check first).
+ *
+ * @param obj The hoversel object
+ *
+ * @ingroup Hoversel
+ */
+EAPI void
+elm_hoversel_clear(Evas_Object *obj)
+{
+   Elm_Hoversel_Item *it;
+   Eina_List *l, *ll;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   EINA_LIST_FOREACH_SAFE(wd->items, l, ll, it) elm_hoversel_item_del(it);
+}
+
+/**
+ * Get the list of items within the given hoversel.
+ *
+ * @param obj The hoversel object
+ * @return Returns a list of Elm_Hoversel_Item*
+ *
+ * @ingroup Hoversel
+ */
+EAPI const Eina_List *
+elm_hoversel_items_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->items;
+}
+
+/**
+ * Add an item to the hoversel button
+ *
+ * This adds an item to the hoversel to show when it is clicked. Note: if you
+ * need to use an icon from an edje file then use elm_hoversel_item_icon_set()
+ * right after the this function, and set icon_file to NULL here.
+ *
+ * @param obj The hoversel object
+ * @param label The text label to use for the item (NULL if not desired)
+ * @param icon_file An image file path on disk to use for the icon or standard
+ * icon name (NULL if not desired)
+ * @param icon_type The icon type if relevant
+ * @param func Convenience function to call when this item is selected
+ * @param data Data to pass to item-related functions
+ * @return A handle to the item added.
+ *
+ * @ingroup Hoversel
+ */
+EAPI Elm_Hoversel_Item *
+elm_hoversel_item_add(Evas_Object *obj, const char *label, const char *icon_file, Elm_Icon_Type icon_type, Evas_Smart_Cb func, const void *data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   Elm_Hoversel_Item *it = calloc(1, sizeof(Elm_Hoversel_Item));
+   if (!it) return NULL;
+   wd->items = eina_list_append(wd->items, it);
+   it->obj = obj;
+   it->label = eina_stringshare_add(label);
+   it->icon_file = eina_stringshare_add(icon_file);
+   it->icon_type = icon_type;
+   it->func = func;
+   it->data = (void *)data;
+   return it;
+}
+
+/**
+ * Delete an item from the hoversel
+ *
+ * This deletes the item from the hoversel (should not be called while the
+ * hoversel is active; use elm_hoversel_expanded_get()
+ * to check first).
+ *
+ * @param it The item to delete
+ *
+ * @ingroup Hoversel
+ */
+EAPI void
+elm_hoversel_item_del(Elm_Hoversel_Item *it)
+{
+   if (!it) return;
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+   if (it->del_cb) it->del_cb((void *)it->data, it->obj, it);
+   if (!wd) return;
+   elm_hoversel_hover_end(it->obj);
+   wd->items = eina_list_remove(wd->items, it);
+   eina_stringshare_del(it->label);
+   eina_stringshare_del(it->icon_file);
+   eina_stringshare_del(it->icon_group);
+   free(it);
+}
+
+/**
+ * Set the function called when an item within the hoversel
+ * is freed. That function will receive these parameters:
+ *
+ * void *item_data
+ * Evas_Object *the_item_object
+ * Elm_Hoversel_Item *the_object_struct
+ *
+ * @param it The item to set the callback on
+ * @param func The function called
+ *
+ * @ingroup Hoversel
+ */
+EAPI void
+elm_hoversel_item_del_cb_set(Elm_Hoversel_Item *it, Evas_Smart_Cb func)
+{
+   if (!it) return;
+   it->del_cb = func;
+}
+
+/**
+ * This returns the data pointer supplied with elm_hoversel_item_add() that
+ * will be passed to associated function callbacks.
+ *
+ * @param it The item to get the data from
+ * @return The data pointer set with elm_hoversel_item_add()
+ *
+ * @ingroup Hoversel
+ */
+EAPI void *
+elm_hoversel_item_data_get(Elm_Hoversel_Item *it)
+{
+   if (!it) return NULL;
+   return it->data;
+}
+
+/**
+ * This returns the label text of the given hoversel item.
+ *
+ * @param it The item to get the label
+ * @return The label text of the hoversel item
+ *
+ * @ingroup Hoversel
+ */
+EAPI const char *
+elm_hoversel_item_label_get(Elm_Hoversel_Item *it)
+{
+   if (!it) return NULL;
+   return it->label;
+}
+
+/**
+ * This sets the icon for the given hoversel item. The icon can be loaded from
+ * the standard set, from an image file, or from an edje file.
+ *
+ * @param it The item to set the icon
+ * @param icon_file An image file path on disk to use for the icon or standard
+ * icon name
+ * @param icon_group The edje group to use if @p icon_file is an edje file. Set this
+ * to NULL if the icon is not an edje file
+ * @param icon_type The icon type
+ *
+ * @ingroup Hoversel
+ */
+EAPI void
+elm_hoversel_item_icon_set(Elm_Hoversel_Item *it, const char *icon_file, const char *icon_group, Elm_Icon_Type icon_type)
+{
+   if (!it) return;
+   eina_stringshare_replace(&it->icon_file, icon_file);
+   eina_stringshare_replace(&it->icon_group, icon_group);
+   it->icon_type = icon_type;
+}
+
+/**
+ * Get the icon object of the hoversel item
+ *
+ * @param it The item to get the icon from
+ * @param icon_file The image file path on disk used for the icon or standard
+ * icon name
+ * @param icon_group The edje group used if @p icon_file is an edje file. NULL
+ * if the icon is not an edje file
+ * @param icon_type The icon type
+ *
+ * @ingroup Hoversel
+ */
+EAPI void
+elm_hoversel_item_icon_get(Elm_Hoversel_Item *it, const char **icon_file, const char **icon_group, Elm_Icon_Type *icon_type)
+{
+   if (!it) return;
+   if (icon_file) *icon_file = it->icon_file;
+   if (icon_group) *icon_group = it->icon_group;
+   if (icon_type) *icon_type = it->icon_type;
+}
+
diff --git a/src/lib/elc_notepad.c b/src/lib/elc_notepad.c
new file mode 100644 (file)
index 0000000..743303e
--- /dev/null
@@ -0,0 +1,352 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+/**
+ * @defgroup Notepad Notepad
+ *
+ * The notepad is an object for quickly loading a text file, displaying it,
+ * allowing editing of it and saving of changes back to the file loaded.
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * NONE
+ *
+ * A notepad object contains a scroller and an entry. It is a convenience
+ * widget that loads a text file indicated, puts it in the scrollable entry
+ * and allows the user to edit it. Changes are written back to the original
+ * file after a short delay. The file to load and save to is specified by
+ * elm_notepad_file_set().
+ */
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *scr, *entry;
+   const char *file;
+   Elm_Text_Format format;
+   Ecore_Timer *delay_write;
+   Eina_Bool can_write : 1;
+   Eina_Bool auto_write : 1;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _on_focus_hook(void *data, Evas_Object *obj);
+static void _load(Evas_Object *obj);
+static void _save(Evas_Object *obj);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->file) eina_stringshare_del(wd->file);
+   if (wd->delay_write)
+     {
+       ecore_timer_del(wd->delay_write);
+       _save(obj);
+     }
+   free(wd);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   evas_object_size_hint_min_set(obj, -1, -1);
+   evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+static void
+_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (elm_widget_focus_get(obj)) elm_widget_focus_steal(wd->entry);
+}
+
+static char *
+_buf_append(char *buf, const char *str, int *len, int *alloc)
+{
+   int len2 = strlen(str);
+   if ((*len + len2) >= *alloc)
+     {
+       char *buf2 = realloc(buf, *alloc + len2 + 512);
+       if (!buf2) return NULL;
+       buf = buf2;
+       *alloc += 512 + len2;
+     }
+   strcpy(buf + *len, str);
+   *len += len2;
+   return buf;
+}
+
+static char *
+_load_file(const char *file)
+{
+   FILE *f;
+   size_t size;
+   int alloc = 0, len = 0;
+   char *text = NULL, buf[4096];
+
+   f = fopen(file, "rb");
+   if (!f) return NULL;
+   while ((size = fread(buf, 1, sizeof(buf), f)))
+     {
+       buf[size] = 0;
+       text = _buf_append(text, buf, &len, &alloc);
+     }
+   fclose(f);
+   return text;
+}
+
+static char *
+_load_plain(const char *file)
+{
+   char *text, *text2;
+
+   text = _load_file(file);
+   if (text)
+     {
+       text2 = elm_entry_utf8_to_markup(text);
+       free(text);
+       return text2;
+     }
+   return NULL;
+}
+
+static void
+_load(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   char *text;
+   if (!wd) return;
+   if (!wd->file)
+     {
+       elm_entry_entry_set(wd->entry, "");
+       return;
+     }
+   switch (wd->format)
+     {
+     case ELM_TEXT_FORMAT_PLAIN_UTF8:
+       text = _load_plain(wd->file);
+       break;
+     case ELM_TEXT_FORMAT_MARKUP_UTF8:
+       text = _load_file(wd->file);
+       break;
+     default:
+       elm_entry_entry_set(wd->entry, "Unknown Text Format");
+       text = NULL;
+     }
+   if (text)
+     {
+       elm_entry_entry_set(wd->entry, text);
+       free(text);
+     }
+   else
+     elm_entry_entry_set(wd->entry, "");
+}
+
+static void
+_save_markup_utf8(const char *file, const char *text)
+{
+   FILE *f;
+   
+   if ((!text) || (text[0] == 0))
+     {
+       ecore_file_unlink(file);
+       return;
+     }
+   f = fopen(file, "wb");
+   if (!f)
+     {
+       // FIXME: report a write error
+       return;
+     }
+   fputs(text, f); // FIXME: catch error
+   fclose(f);
+}
+
+static void
+_save_plain_utf8(const char *file, const char *text)
+{
+   char *text2;
+   
+   text2 = elm_entry_markup_to_utf8(text);
+   if (text2)
+     {
+       _save_markup_utf8(file, text2);
+       free(text2);
+     }
+}
+
+static void
+_save(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (!wd->file) return;
+   switch (wd->format)
+     {
+      case ELM_TEXT_FORMAT_PLAIN_UTF8:
+       _save_plain_utf8(wd->file, elm_entry_entry_get(wd->entry));
+       break;
+      case ELM_TEXT_FORMAT_MARKUP_UTF8:
+       _save_markup_utf8(wd->file, elm_entry_entry_get(wd->entry));
+       break;
+      default:
+       break;
+     }
+}
+
+static int
+_delay_write(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return 0;
+   _save(data);
+   wd->delay_write = NULL;
+   return 0;
+}
+
+static void
+_entry_changed(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (wd->delay_write)
+     {
+       ecore_timer_del(wd->delay_write);
+       wd->delay_write = NULL;
+     }
+   if (!wd->auto_write) return;
+   wd->delay_write = ecore_timer_add(2.0, _delay_write, data);
+}
+
+static void
+_hold_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_widget_scroll_hold_push(wd->scr);
+}
+
+static void
+_hold_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_widget_scroll_hold_pop(wd->scr);
+}
+
+static void
+_freeze_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_widget_scroll_hold_push(wd->scr);
+}
+
+static void
+_freeze_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_widget_scroll_hold_pop(wd->scr);
+}
+
+/**
+ * Add a new notepad to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Notepad
+ */
+EAPI Evas_Object *
+elm_notepad_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "notepad");
+   elm_widget_type_set(obj, "notepad");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_can_focus_set(obj, 1);
+
+   wd->scr = elm_scroller_add(parent);
+   elm_widget_resize_object_set(obj, wd->scr);
+   wd->entry = elm_entry_add(parent);
+   evas_object_size_hint_weight_set(wd->entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(wd->entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_scroller_content_set(wd->scr, wd->entry);
+   evas_object_show(wd->entry);
+
+   elm_entry_entry_set(wd->entry, "");
+   evas_object_smart_callback_add(wd->entry, "changed", _entry_changed, obj);
+   
+   evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
+   evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
+   evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
+   evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
+   
+   wd->auto_write = EINA_TRUE;
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * This sets the file (and implicitly loads it) for the text to display and
+ * then edit. All changes are written back to the file after a short delay.
+ *
+ * @param obj The notepad object
+ * @param file The path to the file to load and save
+ * @param format The file format
+ *
+ *
+ * @ingroup Notepad
+ */
+EAPI void
+elm_notepad_file_set(Evas_Object *obj, const char *file, Elm_Text_Format format)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->delay_write)
+     {
+       ecore_timer_del(wd->delay_write);
+       wd->delay_write = NULL;
+     }
+   _save(obj);
+   eina_stringshare_replace(&wd->file, file);
+   wd->format = format;
+   _load(obj);
+}
+
+/**
+ * This will enable or disable the scroller bounce mode for the notepad. See
+ * elm_scroller_bounce_set() for details
+ *
+ * @param obj The notepad object
+ * @param h_bounce Allow bounce horizontally
+ * @param v_bounce Allow bounce vertically
+ *
+ * @ingroup Notepad
+ */
+EAPI void
+elm_notepad_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_scroller_bounce_set(wd->scr, h_bounce, v_bounce);
+}
diff --git a/src/lib/elc_scrolled_entry.c b/src/lib/elc_scrolled_entry.c
new file mode 100644 (file)
index 0000000..d593df6
--- /dev/null
@@ -0,0 +1,935 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Scrolled_Entry Scrolled_Entry
+ *
+ * A scrolled entry is a convenience widget which shows
+ * a box that the user can enter text into.  Unlike an
+ * @ref Entry widget, scrolled entries scroll with user
+ * input so that the window will not expand if the length
+ * of text inside the entry exceeds the initial size of the
+ * widget.
+ *
+ * Signals that you can add callbacks for are:
+ * "changed" - The text within the entry was changed
+ * "activated" - The entry has received focus and the cursor
+ * "press" - The entry has been clicked
+ * "longpressed" - The entry has been clicked for a couple seconds
+ * "clicked" - The entry has been clicked
+ * "clicked,double" - The entry has been double clicked
+ * "focused" - The entry has received focus
+ * "unfocused" - The entry has lost focus
+ * "selection,paste" - A paste action has occurred
+ * "selection,copy" - A copy action has occurred
+ * "selection,cut" - A cut action has occurred
+ * "selection,start" - A selection has begun
+ * "selection,changed" - The selection has changed
+ * "selection,cleared" - The selection has been cleared
+ * "cursor,changed" - The cursor has changed
+ * "anchor,clicked" - The anchor has been clicked
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *scroller;
+   Evas_Object *entry;
+   Elm_Scroller_Policy policy_h, policy_v;
+   Eina_Bool single_line : 1;
+};
+
+static const char *widtype = NULL;
+
+static const char SIG_CHANGED[] = "changed";
+static const char SIG_ACTIVATED[] = "activated";
+static const char SIG_PRESS[] = "press";
+static const char SIG_LONGPRESSED[] = "longpressed";
+static const char SIG_CLICKED[] = "clicked";
+static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
+static const char SIG_FOCUSED[] = "focused";
+static const char SIG_UNFOCUSED[] = "unfocused";
+static const char SIG_SELECTION_PASTE[] = "selection,paste";
+static const char SIG_SELECTION_COPY[] = "selection,copy";
+static const char SIG_SELECTION_CUT[] = "selection,cut";
+static const char SIG_SELECTION_START[] = "selection,start";
+static const char SIG_SELECTION_CHANGED[] = "selection,changed";
+static const char SIG_SELECTION_CLEARED[] = "selection,cleared";
+static const char SIG_CURSOR_CHANGED[] = "cursor,changed";
+static const char SIG_ANCHOR_CLICKED[] = "anchor,clicked";
+static const Evas_Smart_Cb_Description _signals[] = {
+  {SIG_CHANGED, ""},
+  {SIG_ACTIVATED, ""},
+  {SIG_PRESS, ""},
+  {SIG_LONGPRESSED, ""},
+  {SIG_CLICKED, ""},
+  {SIG_CLICKED_DOUBLE, ""},
+  {SIG_FOCUSED, ""},
+  {SIG_UNFOCUSED, ""},
+  {SIG_SELECTION_PASTE, ""},
+  {SIG_SELECTION_COPY, ""},
+  {SIG_SELECTION_CUT, ""},
+  {SIG_SELECTION_START, ""},
+  {SIG_SELECTION_CHANGED, ""},
+  {SIG_SELECTION_CLEARED, ""},
+  {SIG_CURSOR_CHANGED, ""},
+  {SIG_ANCHOR_CLICKED, ""},
+  {NULL, NULL}
+};
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_object_style_set(wd->entry, elm_widget_style_get(obj));
+   elm_object_style_set(wd->scroller, elm_widget_style_get(obj));
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw, minh;
+   if (!wd) return;
+   evas_object_size_hint_min_get(wd->scroller, &minw, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   if (wd->single_line)
+     evas_object_size_hint_max_set(obj, -1, minh);
+   else
+     evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+static void
+_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (elm_widget_focus_get(obj))
+     elm_widget_focus_steal(wd->entry);
+}
+
+static void
+_disable_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_object_disabled_set(wd->entry, elm_widget_disabled_get(obj));
+}
+
+static void
+_entry_changed(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+   evas_object_smart_callback_call(data, SIG_CHANGED, NULL);
+}
+
+static void
+_entry_activated(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_ACTIVATED, NULL);
+}
+
+static void
+_entry_press(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_PRESS, NULL);
+}
+
+static void
+_entry_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
+}
+
+static void
+_entry_clicked_double(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_CLICKED_DOUBLE, NULL);
+}
+
+static void
+_entry_cursor_changed(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_CURSOR_CHANGED, NULL);
+}
+
+static void
+_entry_anchor_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_ANCHOR_CLICKED, NULL);
+}
+
+static void
+_entry_selection_start(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_SELECTION_START, NULL);
+}
+
+static void
+_entry_selection_changed(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_SELECTION_CHANGED, NULL);
+}
+
+static void
+_entry_selection_cleared(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_SELECTION_CLEARED, NULL);
+}
+
+static void
+_entry_selection_paste(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_SELECTION_PASTE, NULL);
+}
+
+static void
+_entry_selection_copy(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_SELECTION_COPY, NULL);
+}
+
+static void
+_entry_selection_cut(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_SELECTION_CUT, NULL);
+}
+
+static void
+_entry_longpressed(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_LONGPRESSED, NULL);
+}
+
+static void
+_entry_focused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_FOCUSED, NULL);
+}
+
+static void
+_entry_unfocused(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_UNFOCUSED, NULL);
+}
+
+
+/**
+ * This adds a scrolled entry to @p parent object.
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI Evas_Object *
+elm_scrolled_entry_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "scrolled_entry");
+   elm_widget_type_set(obj, "scrolled_entry");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_disable_hook_set(obj, _disable_hook);
+   elm_widget_can_focus_set(obj, 1);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   wd->scroller = elm_scroller_add(parent);
+   elm_widget_resize_object_set(obj, wd->scroller);
+   elm_scroller_bounce_set(wd->scroller, 0, 0);
+   
+   wd->entry = elm_entry_add(parent);
+   evas_object_size_hint_weight_set(wd->entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(wd->entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_scroller_content_set(wd->scroller, wd->entry);
+   evas_object_show(wd->entry);
+
+   evas_object_smart_callback_add(wd->entry, "changed", _entry_changed, obj);
+   evas_object_smart_callback_add(wd->entry, "activated", _entry_activated, obj);
+   evas_object_smart_callback_add(wd->entry, "press", _entry_press, obj);
+   evas_object_smart_callback_add(wd->entry, "clicked", _entry_clicked, obj);
+   evas_object_smart_callback_add(wd->entry, "clicked,double", _entry_clicked_double, obj);
+   evas_object_smart_callback_add(wd->entry, "cursor,changed", _entry_cursor_changed, obj);
+   evas_object_smart_callback_add(wd->entry, "anchor,clicked", _entry_anchor_clicked, obj);
+   evas_object_smart_callback_add(wd->entry, "selection,start", _entry_selection_start, obj);
+   evas_object_smart_callback_add(wd->entry, "selection,changed", _entry_selection_changed, obj);
+   evas_object_smart_callback_add(wd->entry, "selection,cleared", _entry_selection_cleared, obj);
+   evas_object_smart_callback_add(wd->entry, "selection,paste", _entry_selection_paste, obj);
+   evas_object_smart_callback_add(wd->entry, "selection,copy", _entry_selection_copy, obj);
+   evas_object_smart_callback_add(wd->entry, "selection,cut", _entry_selection_cut, obj);
+   evas_object_smart_callback_add(wd->entry, "longpressed", _entry_longpressed, obj);
+   evas_object_smart_callback_add(wd->entry, "focused", _entry_focused, obj);
+   evas_object_smart_callback_add(wd->entry, "unfocused", _entry_unfocused, obj);
+
+   _sizing_eval(obj);
+
+   // TODO: convert Elementary to subclassing of Evas_Smart_Class
+   // TODO: and save some bytes, making descriptions per-class and not instance!
+   evas_object_smart_callbacks_descriptions_set(obj, _signals);
+   return obj;
+}
+
+/**
+ * This sets the scrolled entry object not to line wrap.  All input will
+ * be on a single line, and the entry box will scroll with user input.
+ *
+ * @param obj The scrolled entry object
+ * @param single_line If true, the text in the scrolled entry
+ * will be on a single line.
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_single_line_set(Evas_Object *obj, Eina_Bool single_line)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->single_line == single_line) return;
+   elm_entry_single_line_set(wd->entry, single_line);
+   wd->single_line = single_line;
+   if (single_line)
+     {
+       elm_scroller_policy_set(wd->scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
+       elm_scroller_content_min_limit(wd->scroller, 0, 1);
+     }
+   else
+     {
+       elm_scroller_policy_set(wd->scroller, wd->policy_h, wd->policy_v);
+       elm_scroller_content_min_limit(wd->scroller, 0, 0);
+     }
+   _sizing_eval(obj);
+}
+
+/**
+ * This returns true if the scrolled entry has been set to single line mode.
+ * See also elm_scrolled_entry_single_line_set().
+ *
+ * @param obj The scrolled entry object
+ * @return single_line If true, the text in the scrolled entry is set to display
+ * on a single line.
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI Eina_Bool
+elm_scrolled_entry_single_line_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return elm_entry_single_line_get(wd->entry);
+}
+
+
+/**
+ * This sets the scrolled entry object to password mode.  All text entered
+ * and/or displayed within the widget will be replaced with asterisks (*).
+ *
+ * @param obj The scrolled entry object
+ * @param password If true, password mode is enabled.
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_password_set(Evas_Object *obj, Eina_Bool password)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_password_set(wd->entry, password);
+}
+
+/**
+ * This returns whether password mode is enabled.
+ * See also elm_scrolled_entry_password_set().
+ *
+ * @param obj The scrolled entry object
+ * @return If true, the scrolled entry is set to display all characters
+ * as asterisks (*).
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI Eina_Bool
+elm_scrolled_entry_password_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return elm_entry_password_get(wd->entry);
+}
+
+
+/**
+ * This sets the text displayed within the scrolled entry to @p entry.
+ *
+ * @param obj The scrolled entry object
+ * @param entry The text to be displayed
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_entry_set(Evas_Object *obj, const char *entry)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_entry_set(wd->entry, entry);
+}
+
+/**
+ * This returns the text currently shown in object @p entry.
+ * See also elm_scrolled_entry_entry_set().
+ *
+ * @param obj The scrolled entry object
+ * @return The currently displayed text or NULL on failure
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI const char *
+elm_scrolled_entry_entry_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return elm_entry_entry_get(wd->entry);
+}
+
+/**
+ * This returns all selected text within the scrolled entry.
+ *
+ * @param obj The scrolled entry object
+ * @return The selected text within the scrolled entry or NULL on failure
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI const char *
+elm_scrolled_entry_selection_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return elm_entry_selection_get(wd->entry);
+}
+
+/**
+ * This inserts text in @p entry at the beginning of the scrolled entry
+ * object.
+ *
+ * @param obj The scrolled entry object
+ * @param entry The text to insert
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_entry_insert(Evas_Object *obj, const char *entry)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_entry_insert(wd->entry, entry);
+}
+
+/**
+ * This enables word line wrapping in the scrolled entry object.  It is the opposite
+ * of elm_scrolled_entry_single_line_set().  Additionally, setting this disables
+ * character line wrapping.
+ * See also elm_scrolled_entry_line_char_wrap_set().
+ *
+ * @param obj The scrolled entry object
+ * @param wrap If true, the scrolled entry will be wrapped once it reaches the end
+ * of the object. Wrapping will occur at the end of the word before the end of the
+ * object.
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_line_wrap_set(Evas_Object *obj, Eina_Bool wrap)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_line_wrap_set(wd->entry, wrap);
+}
+
+/**
+ * This enables character line wrapping in the scrolled entry object.  It is the opposite
+ * of elm_scrolled_entry_single_line_set().  Additionally, setting this disables
+ * word line wrapping.
+ * See also elm_scrolled_entry_line_wrap_set().
+ *
+ * @param obj The scrolled entry object
+ * @param wrap If true, the scrolled entry will be wrapped once it reaches the end
+ * of the object. Wrapping will occur immediately upon reaching the end of the object.
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_line_char_wrap_set(Evas_Object *obj, Eina_Bool wrap)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_line_char_wrap_set(wd->entry, wrap);
+}
+
+/**
+ * This sets the editable attribute of the scrolled entry.
+ *
+ * @param obj The scrolled entry object
+ * @param editable If true, the scrolled entry will be editable by the user.
+ * If false, it will be set to the disabled state.
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_editable_set(Evas_Object *obj, Eina_Bool editable)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_editable_set(wd->entry, editable);
+}
+
+/**
+ * This gets the editable attribute of the scrolled entry.
+ * See also elm_scrolled_entry_editable_set().
+ *
+ * @param obj The scrolled entry object
+ * @return If true, the scrolled entry is editable by the user.
+ * If false, it is not editable by the user
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI Eina_Bool
+elm_scrolled_entry_editable_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return elm_entry_editable_get(wd->entry);
+}
+
+
+/**
+ * This drops any existing text selection within the scrolled entry.
+ *
+ * @param obj The scrolled entry object
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_select_none(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_select_none(wd->entry);
+}
+
+/**
+ * This selects all text within the scrolled entry.
+ *
+ * @param obj The scrolled entry object
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_select_all(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_select_all(wd->entry);
+}
+
+/**
+ * This moves the cursor one place to the right within the entry.
+ *
+ * @param obj The scrolled entry object
+ * @return EINA_TRUE upon success, EINA_FALSE upon failure
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI Eina_Bool
+elm_scrolled_entry_cursor_next(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   return elm_entry_cursor_next(wd->entry);
+}
+
+/**
+ * This moves the cursor one place to the left within the entry.
+ *
+ * @param obj The scrolled entry object
+ * @return EINA_TRUE upon success, EINA_FALSE upon failure
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI Eina_Bool
+elm_scrolled_entry_cursor_prev(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   return elm_entry_cursor_prev(wd->entry);
+}
+
+/**
+ * This moves the cursor one line up within the entry.
+ *
+ * @param obj The scrolled entry object
+ * @return EINA_TRUE upon success, EINA_FALSE upon failure
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI Eina_Bool
+elm_scrolled_entry_cursor_up(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   return elm_entry_cursor_up(wd->entry);
+}
+
+/**
+ * This moves the cursor one line down within the entry.
+ *
+ * @param obj The scrolled entry object
+ * @return EINA_TRUE upon success, EINA_FALSE upon failure
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI Eina_Bool
+elm_scrolled_entry_cursor_down(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   return elm_entry_cursor_down(wd->entry);
+}
+
+/**
+ * This moves the cursor to the beginning of the entry.
+ *
+ * @param obj The scrolled entry object
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_cursor_begin_set(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_cursor_begin_set(wd->entry);
+}
+
+/**
+ * This moves the cursor to the end of the entry.
+ *
+ * @param obj The scrolled entry object
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_cursor_end_set(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_cursor_end_set(wd->entry);
+}
+
+/**
+ * This moves the cursor to the beginning of the current line.
+ *
+ * @param obj The scrolled entry object
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_cursor_line_begin_set(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_cursor_line_begin_set(wd->entry);
+}
+
+/**
+ * This moves the cursor to the end of the current line.
+ *
+ * @param obj The scrolled entry object
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_cursor_line_end_set(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_cursor_line_end_set(wd->entry);
+}
+
+/**
+ * This begins a selection within the scrolled entry as though
+ * the user were holding down the mouse button to make a selection.
+ *
+ * @param obj The scrolled entry object
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_cursor_selection_begin(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_cursor_selection_begin(wd->entry);
+}
+
+/**
+ * This ends a selection within the scrolled entry as though
+ * the user had just released the mouse button while making a selection.
+ *
+ * @param obj The scrolled entry object
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_cursor_selection_end(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_cursor_selection_end(wd->entry);
+}
+
+/**
+ * TODO: fill this in
+ *
+ * @param obj The scrolled entry object
+ * @return TODO: fill this in
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI Eina_Bool
+elm_scrolled_entry_cursor_is_format_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   return elm_entry_cursor_is_format_get(wd->entry);
+}
+
+/**
+ * This returns whether the cursor is visible.
+ *
+ * @param obj The scrolled entry object
+ * @return If true, the cursor is visible.
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI Eina_Bool
+elm_scrolled_entry_cursor_is_visible_format_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   return elm_entry_cursor_is_visible_format_get(wd->entry);
+}
+
+/**
+ * TODO: fill this in
+ *
+ * @param obj The scrolled entry object
+ * @return TODO: fill this in
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI const char *
+elm_scrolled_entry_cursor_content_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return elm_entry_cursor_content_get(wd->entry);
+}
+
+/**
+ * This executes a "cut" action on the selected text in the scrolled entry.
+ *
+ * @param obj The scrolled entry object
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_selection_cut(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_selection_cut(wd->entry);
+}
+
+/**
+ * This executes a "copy" action on the selected text in the scrolled entry.
+ *
+ * @param obj The scrolled entry object
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_selection_copy(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_selection_copy(wd->entry);
+}
+
+/**
+ * This executes a "paste" action in the scrolled entry.
+ *
+ * @param obj The scrolled entry object
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_selection_paste(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_selection_paste(wd->entry);
+}
+
+/**
+ * This clears and frees the items in a scrolled entry's contextual (right click) menu.
+ *
+ * @param obj The scrolled entry object
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_context_menu_clear(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_context_menu_clear(wd->entry);
+}
+
+/**
+ * This adds an item to the scrolled entry's contextual menu.
+ *
+ * @param obj The scrolled entry object
+ * @param label The item's text label
+ * @param icon_file The item's icon file
+ * @param icon_type The item's icon type
+ * @param func The callback to execute when the item is clicked
+ * @param data The data to associate with the item for related functions
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_context_menu_item_add(Evas_Object *obj, const char *label, const char *icon_file, Elm_Icon_Type icon_type, Evas_Smart_Cb func, const void *data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_context_menu_item_add(wd->entry, label, icon_file, icon_type, func, data);
+}
+
+/**
+ * This disables the scrolled entry's contextual (right click) menu.
+ *
+ * @param obj The scrolled entry object
+ * @param disabled If true, the menu is disabled
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_context_menu_disabled_set(Evas_Object *obj, Eina_Bool disabled)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_entry_context_menu_disabled_set(wd->entry, disabled);
+}
+
+/**
+ * This returns whether the scrolled entry's contextual (right click) menu is disabled.
+ *
+ * @param obj The scrolled entry object
+ * @return If true, the menu is disabled
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI Eina_Bool
+elm_scrolled_entry_context_menu_disabled_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   return elm_entry_context_menu_disabled_get(wd->entry);
+}
+
+/**
+ * This sets the scrolled entry's scrollbar policy (ie. enabling/disabling them).
+ *
+ * @param obj The scrolled entry object
+ * @param h The horizontal scrollbar policy to apply
+ * @param v The vertical scrollbar policy to apply
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_scrollbar_policy_set(Evas_Object *obj, Elm_Scroller_Policy h, Elm_Scroller_Policy v)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->policy_h = h;
+   wd->policy_v = v;
+   elm_scroller_policy_set(wd->scroller, h, v);
+}
+
+/**
+ * This enables/disables bouncing within the entry.
+ *
+ * @param obj The scrolled entry object
+ * @param h The horizontal bounce state
+ * @param v The vertical bounce state
+ *
+ * @ingroup Scrolled_Entry
+ */
+EAPI void
+elm_scrolled_entry_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_scroller_bounce_set(wd->scroller, h_bounce, v_bounce);
+}
diff --git a/src/lib/elm_bg.c b/src/lib/elm_bg.c
new file mode 100644 (file)
index 0000000..6e08c41
--- /dev/null
@@ -0,0 +1,138 @@
+#include <string.h>
+
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Bg Bg
+ *
+ * The bg object is used for setting a solid background to a window or packing
+ * into any container object.
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *img, *custom_img;
+   const char  *file, *group;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _custom_resize(void *data, Evas *a, Evas_Object *obj, void *event_info);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   _elm_theme_object_set(obj, wd->img, "bg", "base", elm_widget_style_get(obj));
+}
+
+static void
+_custom_resize(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   int iw = 0, ih = 0;
+   Evas_Coord x, y, w, h, ow = 0, oh = 0;
+
+   evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
+   evas_object_image_size_get(obj, &iw, &ih);
+
+   if ((iw < 1) || (ih < 1)) return;
+   w = ow;
+   h = (ih * w) / iw;
+   if (h < oh)
+     {
+       h = oh;
+       w = (iw * h) / ih;
+     }
+   x = (ow - w) / 2;
+   y = (oh - h) / 2;
+   evas_object_image_fill_set(obj, x, y, w, h);
+}
+
+/**
+ * Add a new background to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Bg
+ */
+EAPI Evas_Object *
+elm_bg_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "bg");
+   elm_widget_type_set(obj, "bg");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_can_focus_set(obj, 0);
+
+   wd->img = edje_object_add(e);
+   _elm_theme_object_set(obj, wd->img, "bg", "base", "default");
+   elm_widget_resize_object_set(obj, wd->img);
+   return obj;
+}
+
+/**
+ * Set the file (image or edje) used for the background
+ *
+ * @param obj The bg object
+ * @param file The file path
+ * @param group Optional key (group in Edje) within the file
+ *
+ * This sets the image file used in the background object. The image (or edje)
+ * will be stretched (retaining aspect if its an image file) to completely fill
+ * the bg object. This may mean some parts arte not visible.
+ *
+ * @ingroup Bg
+ */
+EAPI void
+elm_bg_file_set(Evas_Object *obj, const char *file, const char *group)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   const char *p;
+
+   if (wd->custom_img)
+     {
+       evas_object_del(wd->custom_img);
+       wd->custom_img = NULL;
+     }
+   if (!file) return;
+   eina_stringshare_replace(&wd->file, file);
+   eina_stringshare_replace(&wd->group, group);
+   if (((p = strrchr(file, '.'))) && (!strcasecmp(p, ".edj")))
+     {
+       wd->custom_img = edje_object_add(evas_object_evas_get(wd->img));
+       edje_object_file_set(wd->custom_img, file, group);
+     }
+   else
+     {
+       wd->custom_img = evas_object_image_add(evas_object_evas_get(wd->img));
+       evas_object_event_callback_add(wd->custom_img, EVAS_CALLBACK_RESIZE, 
+                                       _custom_resize, wd);
+       evas_object_image_file_set(wd->custom_img, file, group);
+     }
+   elm_widget_sub_object_add(obj, wd->custom_img);
+   evas_object_repeat_events_set(wd->custom_img, 1);
+   edje_object_part_swallow(wd->img, "elm.swallow.background", wd->custom_img);
+   evas_object_show(wd->custom_img);
+}
diff --git a/src/lib/elm_box.c b/src/lib/elm_box.c
new file mode 100644 (file)
index 0000000..2eab987
--- /dev/null
@@ -0,0 +1,356 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Box Box
+ *
+ * A box object arranges objects in a single row within a box. Sub objects can
+ * be added at the start, end or before or after any existing object in the
+ * box already. It can have its orientation changed too. How a child object is
+ * sized and otherwise arranged within the box depends on evas hints.
+ * evas_object_size_hint_align_set() will set either the alignment within its
+ * region if the region allocated is bigger than the object size. If you want
+ * the sub object sized up to fill the allocated region, use -1.0 for the
+ * apporpriate horizontal or vertical axes. evas_object_size_hint_weight_set()
+ * will set the packing weight. The weights of all items being packed are added
+ * up and if items are to be sized up to fit, those with the higher weights get
+ * proportionally more space.
+ *
+ * NOTE: Objects should not be added to box objects using _add() calls.
+ */
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *box;
+   Eina_Bool horizontal:1;
+   Eina_Bool homogeneous:1;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+
+static void
+_del_pre_hook(Evas_Object *obj)
+{
+    Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+    evas_object_event_callback_del_full
+        (wd->box, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
+    evas_object_box_remove_all(wd->box, 0);
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   free(wd);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   Evas_Coord w, h;
+   if (!wd) return;
+   evas_object_size_hint_min_get(wd->box, &minw, &minh);
+   evas_object_size_hint_max_get(wd->box, &maxw, &maxh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+   evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+   if (w < minw) w = minw;
+   if (h < minh) h = minh;
+   if ((maxw >= 0) && (w > maxw)) w = maxw;
+   if ((maxh >= 0) && (h > maxh)) h = maxh;
+   evas_object_resize(obj, w, h);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   _sizing_eval(obj);
+}
+
+static void
+_layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data)
+{
+   Widget_Data *wd = data;
+   if (!wd) return;
+   _els_box_layout(o, priv, wd->horizontal, wd->homogeneous);
+}
+
+
+/**
+ * Add a new box to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Box
+ */
+EAPI Evas_Object *
+elm_box_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "box");
+   elm_widget_type_set(obj, "box");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_del_pre_hook_set(obj, _del_pre_hook);
+
+   wd->box = evas_object_box_add(e);
+   /*evas_object_box_layout_set(wd->box, evas_object_box_layout_vertical,
+                             NULL, NULL);*/
+   evas_object_box_layout_set(wd->box, _layout, wd, NULL);
+
+   evas_object_event_callback_add(wd->box, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                 _changed_size_hints, obj);
+   elm_widget_resize_object_set(obj, wd->box);
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+
+   return obj;
+}
+
+/**
+ * Set the horizontal orientation
+ *
+ * By default box object arrange their contents vertically from top to bottom.
+ * By calling this and providing @p orizontal as true, the box will become
+ * horizontal arranging contents left to right.
+ *
+ * @param obj The box object
+ * @param horizontal The horizontal flag (1 = horizontal, 0 = vertical)
+ *
+ * @ingroup Box
+ */
+EAPI void
+elm_box_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->horizontal = !!horizontal;
+   evas_object_smart_calculate(wd->box);
+   /*if (wd->horizontal)
+     {
+       if (wd->homogeneous)
+         evas_object_box_layout_set(wd->box,
+               evas_object_box_layout_homogeneous_horizontal, NULL, NULL);
+       else
+         evas_object_box_layout_set(wd->box, evas_object_box_layout_horizontal,
+                                    NULL, NULL);
+     }
+   else
+     {
+       if (wd->homogeneous)
+         evas_object_box_layout_set(wd->box,
+               evas_object_box_layout_homogeneous_vertical, NULL, NULL);
+       else
+         evas_object_box_layout_set(wd->box, evas_object_box_layout_horizontal,
+                                    NULL, NULL);
+     }*/
+}
+
+/**
+ * Set homogenous layout
+ *
+ * If enabled, homogenous layout makes all items the same size. This size is
+ * of course governed by the size of the largest item in the box.
+ *
+ * @param obj The box object
+ * @param homogenous The homogenous flag (1 = on, 2 = off)
+ *
+ * @ingroup Box
+ */
+EAPI void
+elm_box_homogenous_set(Evas_Object *obj, Eina_Bool homogenous)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->homogeneous = !!homogenous;
+   evas_object_smart_calculate(wd->box);
+   /*if (wd->horizontal)
+     {
+       if (wd->homogeneous)
+         evas_object_box_layout_set(wd->box,
+               evas_object_box_layout_homogeneous_horizontal, NULL, NULL);
+       else
+         evas_object_box_layout_set(wd->box, evas_object_box_layout_horizontal,
+                                    NULL, NULL);
+     }
+   else
+     {
+       if (wd->homogeneous)
+         evas_object_box_layout_set(wd->box,
+               evas_object_box_layout_homogeneous_vertical, NULL, NULL);
+       else
+         evas_object_box_layout_set(wd->box, evas_object_box_layout_horizontal,
+                                    NULL, NULL);
+     }*/
+}
+
+/**
+ * This adds a box at the start of the box (top or left based on orientation)
+ *
+ * This will add the @p subobj to the box object indicated at the beginning
+ * of the box (the left or top end).
+ *
+ * @param obj The box object
+ * @param subobj The object to add to the box
+ *
+ * @ingroup Box
+ */
+EAPI void
+elm_box_pack_start(Evas_Object *obj, Evas_Object *subobj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_widget_sub_object_add(obj, subobj);
+   evas_object_box_prepend(wd->box, subobj);
+}
+
+/**
+ * This adds a box at the end of the box (bottom or right based on orientation)
+ *
+ * This will add the @p subobj to the box object indicated at the end
+ * of the box (the right or bottom end).
+ *
+ * @param obj The box object
+ * @param subobj The object to add to the box
+ *
+ * @ingroup Box
+ */
+EAPI void
+elm_box_pack_end(Evas_Object *obj, Evas_Object *subobj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_widget_sub_object_add(obj, subobj);
+   evas_object_box_append(wd->box, subobj);
+}
+
+/**
+ * This adds adds an object to the box before the indicated object
+ *
+ * This will add the @p subobj to the box indicated before the object
+ * indicated with @p before. If @p before is not already in the box, results
+ * are undefined. Before means either to the left of the indicated object or
+ * above it depending on orientation.
+ *
+ * @param obj The box object
+ * @param subobj The object to add to the box
+ * @param before The object before which to add it
+ *
+ * @ingroup Box
+ */
+EAPI void
+elm_box_pack_before(Evas_Object *obj, Evas_Object *subobj, Evas_Object *before)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_widget_sub_object_add(obj, subobj);
+   evas_object_box_insert_before(wd->box, subobj, before);
+}
+
+/**
+ * This adds adds an object to the box after the indicated object
+ *
+ * This will add the @p subobj to the box indicated after the object
+ * indicated with @p after. If @p after is not already in the box, results
+ * are undefined. After means either to the right of the indicated object or
+ * below it depending on orientation.
+ *
+ * @param obj The box object
+ * @param subobj The object to add to the box
+ * @param after The object after which to add it
+ *
+ * @ingroup Box
+ */
+EAPI void
+elm_box_pack_after(Evas_Object *obj, Evas_Object *subobj, Evas_Object *after)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_widget_sub_object_add(obj, subobj);
+   evas_object_box_insert_after(wd->box, subobj, after);
+}
+
+/**
+ * This clears the box items
+ *
+ * This delete all members of the box object, but not the box itself.
+ *
+ * @param obj The box object
+ *
+ * @ingroup Box
+ */
+EAPI void
+elm_box_clear(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   evas_object_box_remove_all(wd->box, 1);
+}
+
+/**
+ * This unpack a box item
+ *
+ * This unpack the selected member from the box object, but does not delete
+ * the box itself or the packed items.
+ *
+ * @param obj The box object
+ *
+ * @ingroup Box
+ */
+EAPI void
+elm_box_unpack(Evas_Object *obj, Evas_Object *subobj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   evas_object_box_remove(wd->box, subobj);
+}
+
+/**
+ * This unpack the box items
+ *
+ * This unpack all members from the box object, but does not delete
+ * the box itself or the packed items.
+ *
+ * @param obj The box object
+ *
+ * @ingroup Box
+ */
+EAPI void
+elm_box_unpack_all(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   evas_object_box_remove_all(wd->box, 0);
+}
diff --git a/src/lib/elm_bubble.c b/src/lib/elm_bubble.c
new file mode 100644 (file)
index 0000000..264fe87
--- /dev/null
@@ -0,0 +1,309 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Bubble Bubble
+ *
+ * The Bubble is an widget used to show a text in a frame as speech is
+ * represented in comics.
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *bbl;
+   Evas_Object *content, *icon;
+   const char *label, *info;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->label) eina_stringshare_del(wd->label);
+   if (wd->info) eina_stringshare_del(wd->info);
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _elm_theme_object_set(obj, wd->bbl, "bubble", "base", elm_widget_style_get(obj));
+   edje_object_part_text_set(wd->bbl, "elm.text", wd->label);
+   edje_object_part_text_set(wd->bbl, "elm.info", wd->info);
+   edje_object_scale_set(wd->bbl, elm_widget_scale_get(obj) * _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   if (!wd) return;
+   edje_object_size_min_calc(wd->bbl, &minw, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *sub = event_info;
+   if (!wd) return;
+   evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                  _changed_size_hints, obj);
+   if (sub == wd->content) wd->content = NULL;
+   else if (sub == wd->icon) wd->icon = NULL;
+   _sizing_eval(obj);
+}
+
+/**
+ * Add a new bubble to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * This function adds a text bubble to the given parent evas object.
+ *
+ * @ingroup Bubble
+ */
+EAPI Evas_Object *
+elm_bubble_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "bubble");
+   elm_widget_type_set(obj, "bubble");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   wd->bbl = edje_object_add(e);
+   _elm_theme_object_set(obj, wd->bbl, "bubble", "base", "default");
+   elm_widget_resize_object_set(obj, wd->bbl);
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Set the label of the bubble
+ *
+ * @param obj The bubble object
+ * @param label The string to set in the label
+ *
+ * This function sets the title of the bubble that is shown on top of
+ * the bubble.
+ *
+ * @ingroup Bubble
+ */
+EAPI void
+elm_bubble_label_set(Evas_Object *obj, const char *label)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->label, label);
+   edje_object_part_text_set(wd->bbl, "elm.text", label);
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the label of the bubble
+ *
+ * @param obj The bubble object
+ * @return The string of set in the label
+ *
+ * This function gets the title of the bubble that is shown on top of
+ * the bubble.
+ *
+ * @ingroup Bubble
+ */
+EAPI const char*
+elm_bubble_label_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->label;
+}
+
+/**
+ * Set the info of the bubble
+ *
+ * @param obj The bubble object
+ * @param info The given info about the bubble
+ *
+ * This function sets the text shown on the top right of bubble.
+ * In the Anchorblock example of the Elementary tests application it
+ * shows time.
+ *
+ * @ingroup Bubble
+ *
+ */
+EAPI void
+elm_bubble_info_set(Evas_Object *obj, const char *info)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->info, info);
+   edje_object_part_text_set(wd->bbl, "elm.info", info);
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the info of the bubble
+ *
+ * @param obj The bubble object
+ *
+ * @return The "info" string of the bubble
+ *
+ * This function gets the text set to be displayed at the top right of
+ * the bubble.
+ *
+ * @ingroup Bubble
+ *
+ */
+EAPI const char *
+elm_bubble_info_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->info;
+}
+
+/**
+ * Set the text to be showed in the bubble
+ *
+ * @param obj The bubble object
+ * @param content The given info about the bubble
+ *
+ * This function sets the text shown on the top right of bubble. In
+ * the Anchorblock example of the Elementary tests application it
+ * shows time.
+ *
+ * @ingroup Bubble
+ */
+EAPI void
+elm_bubble_content_set(Evas_Object *obj, Evas_Object *content)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if ((wd->content != content) && (wd->content))
+     elm_widget_sub_object_del(obj, wd->content);
+   wd->content = content;
+   if (content)
+     {
+       elm_widget_sub_object_add(obj, content);
+       evas_object_event_callback_add(content,
+                                       EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                      _changed_size_hints, obj);
+       edje_object_part_swallow(wd->bbl, "elm.swallow.content", content);
+     }
+   _sizing_eval(obj);
+}
+
+/**
+ * Set the icon of the bubble
+ *
+ * @param obj The bubble object
+ * @param icon The given icon for the bubble
+ *
+ * This function sets the icon shown on the top left of bubble.
+ *
+ * @ingroup Bubble
+ */
+EAPI void
+elm_bubble_icon_set(Evas_Object *obj, Evas_Object *icon)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if ((wd->icon != icon) && (wd->icon))
+     elm_widget_sub_object_del(obj, wd->icon);
+   wd->icon = icon;
+   if (icon)
+     {
+       elm_widget_sub_object_add(obj, icon);
+       edje_object_part_swallow(wd->bbl, "elm.swallow.icon", icon);
+       evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                      _changed_size_hints, obj);
+     }
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the icon of the bubble
+ *
+ * @param obj The bubble object
+ * @return The icon for the bubble
+ *
+ * This function gets the icon shown on the top left of bubble.
+ *
+ * @ingroup Bubble
+ */
+EAPI Evas_Object *
+elm_bubble_icon_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->icon;
+}
+
+/**
+ * Set the corner of the bubble
+ *
+ * @param obj The bubble object.
+ * @param corner The given corner for the bubble.
+ *
+ * This function sets the corner of the bubble.
+ *
+ * @ingroup Bubble
+ */
+EAPI void
+elm_bubble_corner_set(Evas_Object *obj, const char *corner)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _elm_theme_object_set(obj, wd->bbl, "bubble", corner, elm_widget_style_get(obj));
+   if (wd->icon)
+     edje_object_part_swallow(wd->bbl, "elm.swallow.icon", wd->icon);
+   if (wd->content)
+     edje_object_part_swallow(wd->bbl, "elm.swallow.content", wd->content);
+   // FIXME: fix label etc.
+   _sizing_eval(obj);
+}
diff --git a/src/lib/elm_button.c b/src/lib/elm_button.c
new file mode 100644 (file)
index 0000000..3bccbef
--- /dev/null
@@ -0,0 +1,417 @@
+/*
+ *
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Button Button
+ *
+ * This is a push-button. Press it and run some function. It can contain
+ * a simple label and icon object.
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *btn, *icon;
+   const char *label;
+
+   Eina_Bool autorepeat;
+   Eina_Bool repeating;
+   double ar_threshold;
+   double ar_interval;
+   Ecore_Timer *timer;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _disable_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+static void _signal_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_pressed(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_unpressed(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _on_focus_hook(void *data, Evas_Object *obj);
+
+static const char SIG_CLICKED[] = "clicked";
+static const char SIG_REPEATED[] = "repeated";
+static const char SIG_UNPRESSED[] = "unpressed";
+static const Evas_Smart_Cb_Description _signals[] = {
+  {SIG_CLICKED, ""},
+  {SIG_REPEATED, ""},
+  {SIG_UNPRESSED, ""},
+  {NULL, NULL}
+};
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->label) eina_stringshare_del(wd->label);
+   free(wd);
+}
+
+static void
+_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (elm_widget_focus_get(obj))
+     {
+       edje_object_signal_emit(wd->btn, "elm,action,focus", "elm");
+       evas_object_focus_set(wd->btn, 1);
+     }
+   else
+     {
+       edje_object_signal_emit(wd->btn, "elm,action,unfocus", "elm");
+       evas_object_focus_set(wd->btn, 0);
+     }
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _elm_theme_object_set(obj, wd->btn, "button", "base", elm_widget_style_get(obj));
+   if (wd->icon)
+     edje_object_part_swallow(wd->btn, "elm.swallow.content", wd->icon);
+   if (wd->label)
+     edje_object_signal_emit(wd->btn, "elm,state,text,visible", "elm");
+   else
+     edje_object_signal_emit(wd->btn, "elm,state,text,hidden", "elm");
+   if (wd->icon)
+     edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm");
+   else
+     edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");
+   edje_object_part_text_set(wd->btn, "elm.text", wd->label);
+   edje_object_message_signal_process(wd->btn);
+   edje_object_scale_set(wd->btn, elm_widget_scale_get(obj) * _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+static void
+_disable_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (elm_widget_disabled_get(obj))
+     edje_object_signal_emit(wd->btn, "elm,state,disabled", "elm");
+   else
+     edje_object_signal_emit(wd->btn, "elm,state,enabled", "elm");
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+
+   if (!wd) return;
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   edje_object_size_min_restricted_calc(wd->btn, &minw, &minh, minw, minh);
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (obj != wd->icon) return;
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *sub = event_info;
+   if (!wd) return;
+   if (sub == wd->icon)
+     {
+       edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");
+       evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                       _changed_size_hints, obj);
+       wd->icon = NULL;
+       edje_object_message_signal_process(wd->btn);
+       _sizing_eval(obj);
+     }
+}
+
+static void
+_signal_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (wd->timer)
+     {
+       ecore_timer_del(wd->timer);
+       wd->timer = NULL;
+     }
+   wd->repeating = EINA_FALSE;
+   evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
+   _signal_unpressed(data, obj, emission, source); /* safe guard when the theme does not emit the 'unpress' signal */
+}
+
+static int
+_autorepeat_send(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return ECORE_CALLBACK_CANCEL;
+
+   evas_object_smart_callback_call(data, SIG_REPEATED, NULL);
+   if (!wd->repeating)
+     {
+       wd->timer = NULL;
+       return ECORE_CALLBACK_CANCEL;
+     }
+
+   return ECORE_CALLBACK_RENEW;
+}
+
+static int
+_autorepeat_initial_send(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return ECORE_CALLBACK_CANCEL;
+
+   if (wd->timer) ecore_timer_del(wd->timer);
+   wd->repeating = EINA_TRUE;
+   _autorepeat_send(data);
+   wd->timer = ecore_timer_add(wd->ar_interval, _autorepeat_send, data);
+
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_signal_pressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+
+   if (wd->autorepeat && !wd->repeating)
+     {
+       if (wd->ar_threshold <= 0.0)
+         _autorepeat_initial_send(data); /* call immediately */
+       else
+         wd->timer = ecore_timer_add(wd->ar_threshold, _autorepeat_initial_send, data);
+     }
+}
+
+static void
+_signal_unpressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+
+   if (wd->timer)
+     {
+       ecore_timer_del(wd->timer);
+       wd->timer = NULL;
+     }
+   wd->repeating = EINA_FALSE;
+   evas_object_smart_callback_call(data, SIG_UNPRESSED, NULL);
+}
+
+/**
+ * Add a new button to the parent
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Button
+ */
+EAPI Evas_Object *
+elm_button_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "button");
+   elm_widget_type_set(obj, "button");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_disable_hook_set(obj, _disable_hook);
+   elm_widget_can_focus_set(obj, 1 );                 
+
+   wd->btn = edje_object_add(e);
+   _elm_theme_object_set(obj, wd->btn, "button", "base", "default");
+   edje_object_signal_callback_add(wd->btn, "elm,action,click", "",
+                                   _signal_clicked, obj);
+   edje_object_signal_callback_add(wd->btn, "elm,action,press", "",
+                                   _signal_pressed, obj);
+   edje_object_signal_callback_add(wd->btn, "elm,action,unpress", "",
+                                   _signal_unpressed, obj);
+   elm_widget_resize_object_set(obj, wd->btn);
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+
+   _sizing_eval(obj);
+
+   // TODO: convert Elementary to subclassing of Evas_Smart_Class
+   // TODO: and save some bytes, making descriptions per-class and not instance!
+   evas_object_smart_callbacks_descriptions_set(obj, _signals);
+   return obj;
+}
+
+/**
+ * Set the label used in the button
+ *
+ * @param obj The button object
+ * @param label The text will be written on the button
+ *
+ * @ingroup Button
+ */
+EAPI void
+elm_button_label_set(Evas_Object *obj, const char *label)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->label, label);
+   if (label)
+     edje_object_signal_emit(wd->btn, "elm,state,text,visible", "elm");
+   else
+     edje_object_signal_emit(wd->btn, "elm,state,text,hidden", "elm");
+   edje_object_message_signal_process(wd->btn);
+   edje_object_part_text_set(wd->btn, "elm.text", label);
+   _sizing_eval(obj);
+}
+
+EAPI const char *
+elm_button_label_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->label;
+}
+
+/**
+ * Set the icon used for the button
+ *
+ * @param obj The button object
+ * @param icon  The image for the button
+ *
+ * @ingroup Button
+ */
+EAPI void
+elm_button_icon_set(Evas_Object *obj, Evas_Object *icon)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if ((wd->icon != icon) && (wd->icon))
+     elm_widget_sub_object_del(obj, wd->icon);
+   if ((icon) && (wd->icon != icon))
+     {
+       wd->icon = icon;
+       elm_widget_sub_object_add(obj, icon);
+       evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                      _changed_size_hints, obj);
+       edje_object_part_swallow(wd->btn, "elm.swallow.content", icon);
+       edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm");
+       edje_object_message_signal_process(wd->btn);
+       _sizing_eval(obj);
+     }
+   else
+     wd->icon = icon;
+}
+
+/**
+ * Get the icon used for the button
+ *
+ * @param obj The button object
+ * @return The image for the button
+ *
+ * @ingroup Button
+ */
+EAPI Evas_Object *
+elm_button_icon_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->icon;
+}
+
+/**
+ * Turn on/off the autorepeat event generated when the user keeps pressing on the button
+ *
+ * @param obj The button object
+ * @param on  A bool to turn on/off the event
+ *
+ * @ingroup Button
+ */
+EAPI void
+elm_button_autorepeat_set(Evas_Object *obj, Eina_Bool on)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->timer)
+     {
+        ecore_timer_del(wd->timer);
+        wd->timer = NULL;
+     }
+   wd->autorepeat = on;
+   wd->repeating = EINA_FALSE;
+}
+
+/**
+ * Set the initial timeout before the autorepeat event is generated
+ *
+ * @param obj The button object
+ * @param t   Timeout
+ *
+ * @ingroup Button
+ */
+EAPI void
+elm_button_autorepeat_initial_timeout_set(Evas_Object *obj, double t)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->ar_threshold == t) return;
+   if (wd->timer)
+     {
+       ecore_timer_del(wd->timer);
+       wd->timer = NULL;
+     }
+   wd->ar_threshold = t;
+}
+
+/**
+ * Set the interval between each generated autorepeat event
+ *
+ * @param obj The button object
+ * @param t   Interval
+ *
+ * @ingroup Button
+ */
+EAPI void         
+elm_button_autorepeat_gap_timeout_set(Evas_Object *obj, double t)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->ar_interval == t) return;
+
+   wd->ar_interval = t;
+   if (wd->repeating && wd->timer) ecore_timer_interval_set(wd->timer, t);
+}
diff --git a/src/lib/elm_carousel.c b/src/lib/elm_carousel.c
new file mode 100644 (file)
index 0000000..ad3142b
--- /dev/null
@@ -0,0 +1,256 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+// FIXME: this is NOT the carousel - yet!
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *scr, *bx;
+   Eina_List *items;
+   int icon_size;
+};
+
+struct _Elm_Carousel_Item
+{
+   Evas_Object *obj, *base, *icon;
+   const char *label;
+   Evas_Smart_Cb func;
+   const void *data;
+   Eina_Bool selected : 1;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+
+static void
+_item_show(Elm_Carousel_Item *it)
+{
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+   Evas_Coord x, y, w, h, bx, by;
+   if (!wd) return;
+   evas_object_geometry_get(wd->bx, &bx, &by, NULL, NULL);
+   evas_object_geometry_get(it->base, &x, &y, &w, &h);
+   elm_smart_scroller_child_region_show(wd->scr, x - bx, y - by, w, h);
+}
+
+static void
+_item_select(Elm_Carousel_Item *it)
+{
+   Elm_Carousel_Item *it2;
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+   Evas_Object *obj2;
+   const Eina_List *l;
+   if (!wd) return;
+   if (it->selected) return;
+   EINA_LIST_FOREACH(wd->items, l, it2)
+     {
+       if (it2->selected)
+         {
+            it2->selected = EINA_FALSE;
+            edje_object_signal_emit(it2->base, "elm,state,unselected", "elm");
+            break;
+         }
+     }
+   it->selected = EINA_TRUE;
+   edje_object_signal_emit(it->base, "elm,state,selected", "elm");
+   _item_show(it);
+   obj2 = it->obj;
+   if (it->func) it->func((void *)(it->data), it->obj, it);
+   evas_object_smart_callback_call(obj2, "clicked", it);
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   const Eina_List *l;
+   const Elm_Carousel_Item *it;
+   if (!wd) return;
+   EINA_LIST_FOREACH(wd->items, l, it)
+     {
+        Evas_Coord mw, mh;
+
+       if (it->selected)
+         edje_object_signal_emit(it->base, "elm,state,selected", "elm");
+       _elm_theme_object_set(obj, it->base, "carousel", "item", elm_widget_style_get(obj));
+       edje_object_scale_set(it->base, elm_widget_scale_get(obj) * _elm_config->scale);
+       if (it->icon)
+         {
+            edje_extern_object_min_size_set(it->icon,
+                                            (double)wd->icon_size * _elm_config->scale,
+                                            (double)wd->icon_size * _elm_config->scale);
+            edje_object_part_swallow(it->base, "elm.swallow.icon", it->icon);
+         }
+       edje_object_part_text_set(it->base, "elm.text", it->label);
+       edje_object_size_min_calc(it->base, &mw, &mh);
+       evas_object_size_hint_min_set(it->base, mw, mh);
+       evas_object_size_hint_max_set(it->base, 9999, mh);
+     }
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   Evas_Coord vw = 0, vh = 0;
+   if (!wd) return;
+   edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr), &minw, &minh);
+   evas_object_resize(wd->scr, 500, 500);
+   evas_object_size_hint_min_get(wd->bx, &minw, &minh);
+   evas_object_resize(wd->bx, minw, minh);
+   elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
+   minw = minw + (500 - vw);
+   minh = minh + (500 - vh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Coord mw, mh, vw, vh, w, h;
+   const Eina_List *l;
+   Elm_Carousel_Item *it;
+   if (!wd) return;
+   elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
+   evas_object_size_hint_min_get(wd->bx, &mw, &mh);
+   evas_object_geometry_get(wd->bx, NULL, NULL, &w, &h);
+   if (vw >= mw)
+     {
+       if (w != vw) evas_object_resize(wd->bx, vw, h);
+     }
+   EINA_LIST_FOREACH(wd->items, l, it)
+     {
+       if (it->selected)
+         {
+            _item_show(it);
+            break;
+         }
+     }
+
+}
+
+static void
+_select(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   _item_select(data);
+}
+
+EAPI Evas_Object *
+elm_carousel_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "carousel");
+   elm_widget_type_set(obj, "carousel");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_can_focus_set(obj, 0);
+
+   wd->scr = elm_smart_scroller_add(e);
+   elm_smart_scroller_widget_set(wd->scr, obj);
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "carousel", "base", "default");
+   elm_widget_resize_object_set(obj, wd->scr);
+   elm_smart_scroller_policy_set(wd->scr,
+                                ELM_SMART_SCROLLER_POLICY_AUTO,
+                                ELM_SMART_SCROLLER_POLICY_OFF);
+
+   wd->icon_size = 32;
+
+   wd->bx = evas_object_box_add(e);
+   evas_object_box_layout_set(wd->bx,
+                  evas_object_box_layout_homogeneous_horizontal, NULL, NULL);
+   elm_widget_sub_object_add(obj, wd->bx);
+   elm_smart_scroller_child_set(wd->scr, wd->bx);
+   evas_object_show(wd->bx);
+
+   evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_RESIZE,
+                                 _resize, obj);
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+EAPI Elm_Carousel_Item *
+elm_carousel_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, Evas_Smart_Cb func, const void *data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   Evas_Coord mw, mh;
+   Elm_Carousel_Item *it = calloc(1, sizeof(Elm_Carousel_Item));
+
+   if (!it) return NULL;
+   wd->items = eina_list_append(wd->items, it);
+   it->obj = obj;
+   it->label = eina_stringshare_add(label);
+   it->icon = icon;
+   it->func = func;
+   it->data = data;
+   it->base = edje_object_add(evas_object_evas_get(obj));
+   _elm_theme_object_set(obj, it->base, "carousel", "item", elm_widget_style_get(obj));
+   edje_object_signal_callback_add(it->base, "elm,action,click", "elm",
+                                  _select, it);
+   elm_widget_sub_object_add(obj, it->base);
+   if (it->icon)
+     {
+       edje_extern_object_min_size_set(it->icon,
+                                       (double)wd->icon_size * _elm_config->scale,
+                                       (double)wd->icon_size * _elm_config->scale);
+       edje_object_part_swallow(it->base, "elm.swallow.icon", it->icon);
+       evas_object_show(it->icon);
+       elm_widget_sub_object_add(obj, it->icon);
+     }
+   edje_object_part_text_set(it->base, "elm.text", it->label);
+   edje_object_size_min_calc(it->base, &mw, &mh);
+   evas_object_size_hint_weight_set(it->base, 0.0, 0.0);
+   evas_object_size_hint_align_set(it->base, -1.0, -1.0);
+   evas_object_size_hint_min_set(it->base, mw, mh);
+   evas_object_size_hint_max_set(it->base, 9999, mh);
+   evas_object_box_append(wd->bx, it->base);
+   evas_object_show(it->base);
+   _sizing_eval(obj);
+   return it;
+}
+
+EAPI void
+elm_carousel_item_del(Elm_Carousel_Item *it)
+{
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+   Evas_Object *obj2 = it->obj;
+   if (!wd) return;
+   wd->items = eina_list_remove(wd->items, it);
+   eina_stringshare_del(it->label);
+   if (it->icon) evas_object_del(it->icon);
+   evas_object_del(it->base);
+   free(it);
+   _theme_hook(obj2);
+}
+
+EAPI void
+elm_carousel_item_select(Elm_Carousel_Item *item)
+{
+   _item_select(item);
+}
diff --git a/src/lib/elm_check.c b/src/lib/elm_check.c
new file mode 100644 (file)
index 0000000..c91956a
--- /dev/null
@@ -0,0 +1,386 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Check Check
+ *
+ * The check widget allows for toggling a value between true or false (1 or 0).
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * changed - This is called whenever the user changes the state of one of the
+ * check object.
+ *
+ * Check objects are a lot like radio objects in layout and functionality
+ * except they do not work as a group, but independently and only toggle the
+ * value of a boolean from false to true (0 or 1). elm_check_state_set() sets
+ * the boolean state (1 for true, 0 for false), and elm_check_state_get()
+ * returns the current state. For convenience, like the radio objects, you
+ * can set a pointer to a boolean directly with elm_check_state_pointer_set()
+ * for it to modify.
+ */
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *chk, *icon;
+   Eina_Bool state;
+   Eina_Bool *statep;
+   const char *label;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _disable_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+static void _signal_check_off(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_check_on(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_check_toggle(void *data, Evas_Object *obj, const char *emission, const char *source);
+
+static const char SIG_CHANGED[] = "changed";
+static const Evas_Smart_Cb_Description _signals[] = {
+  {SIG_CHANGED, ""},
+  {NULL, NULL}
+};
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->label) eina_stringshare_del(wd->label);
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _elm_theme_object_set(obj, wd->chk, "check", "base", elm_widget_style_get(obj));
+   if (wd->icon)
+     edje_object_signal_emit(wd->chk, "elm,state,icon,visible", "elm");
+   else
+     edje_object_signal_emit(wd->chk, "elm,state,icon,hidden", "elm");
+   if (wd->state)
+     edje_object_signal_emit(wd->chk, "elm,state,check,on", "elm");
+   else
+     edje_object_signal_emit(wd->chk, "elm,state,check,off", "elm");
+   if (wd->label)
+     edje_object_signal_emit(wd->chk, "elm,state,text,visible", "elm");
+   else
+     edje_object_signal_emit(wd->chk, "elm,state,text,hidden", "elm");
+   edje_object_part_text_set(wd->chk, "elm.text", wd->label);
+   edje_object_message_signal_process(wd->chk);
+   edje_object_scale_set(wd->chk, elm_widget_scale_get(obj) * _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+static void
+_disable_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (elm_widget_disabled_get(obj))
+     edje_object_signal_emit(wd->chk, "elm,state,disabled", "elm");
+   else
+     edje_object_signal_emit(wd->chk, "elm,state,enabled", "elm");
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   if (!wd) return;
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   edje_object_size_min_restricted_calc(wd->chk, &minw, &minh, minw, minh);
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (obj != wd->icon) return;
+   Evas_Coord mw, mh;
+   evas_object_size_hint_min_get(obj, &mw, &mh);
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *sub = event_info;
+   if (!wd) return;
+   if (sub == wd->icon)
+     {
+       edje_object_signal_emit(wd->chk, "elm,state,icon,hidden", "elm");
+       evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                       _changed_size_hints, obj);
+       wd->icon = NULL;
+       _sizing_eval(obj);
+     }
+}
+
+static void
+_signal_check_off(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   wd->state = EINA_FALSE;
+   if (wd->statep) *wd->statep = wd->state;
+   edje_object_signal_emit(wd->chk, "elm,state,check,off", "elm");
+   evas_object_smart_callback_call(data, SIG_CHANGED, NULL);
+}
+
+static void
+_signal_check_on(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   wd->state = EINA_TRUE;
+   if (wd->statep) *wd->statep = wd->state;
+   edje_object_signal_emit(wd->chk, "elm,state,check,on", "elm");
+   evas_object_smart_callback_call(data, SIG_CHANGED, NULL);
+}
+
+static void
+_signal_check_toggle(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   wd->state = !wd->state;
+   if (wd->statep) *wd->statep = wd->state;
+   if (wd->state)
+     edje_object_signal_emit(wd->chk, "elm,state,check,on", "elm");
+   else
+     edje_object_signal_emit(wd->chk, "elm,state,check,off", "elm");
+   evas_object_smart_callback_call(data, SIG_CHANGED, NULL);
+}
+
+/**
+ * Add a new Check object
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Check
+ */
+EAPI Evas_Object *
+elm_check_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "check");
+   elm_widget_type_set(obj, "check");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_disable_hook_set(obj, _disable_hook);
+
+   wd->chk = edje_object_add(e);
+   _elm_theme_object_set(obj, wd->chk, "check", "base", "default");
+   edje_object_signal_callback_add(wd->chk, "elm,action,check,on", "",
+                                   _signal_check_on, obj);
+   edje_object_signal_callback_add(wd->chk, "elm,action,check,off", "",
+                                   _signal_check_off, obj);
+   edje_object_signal_callback_add(wd->chk, "elm,action,check,toggle", "",
+                                   _signal_check_toggle, obj);
+   elm_widget_resize_object_set(obj, wd->chk);
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+
+   _sizing_eval(obj);
+
+   // TODO: convert Elementary to subclassing of Evas_Smart_Class
+   // TODO: and save some bytes, making descriptions per-class and not instance!
+   evas_object_smart_callbacks_descriptions_set(obj, _signals);
+   return obj;
+}
+
+/**
+ * Set the text label of the check object
+ *
+ * @param obj The check object
+ * @param label The text label string in UTF-8
+ *
+ * @ingroup Check
+ */
+EAPI void
+elm_check_label_set(Evas_Object *obj, const char *label)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->label, label);
+   if (label)
+     edje_object_signal_emit(wd->chk, "elm,state,text,visible", "elm");
+   else
+     edje_object_signal_emit(wd->chk, "elm,state,text,hidden", "elm");
+   edje_object_message_signal_process(wd->chk);
+   edje_object_part_text_set(wd->chk, "elm.text", label);
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the text label of the check object
+ *
+ * @param obj The check object
+ * @return The text label string in UTF-8
+ *
+ * @ingroup Check
+ */
+EAPI const char *
+elm_check_label_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->label;
+}
+
+/**
+ * Set the icon object of the check object
+ *
+ * Once the icon object is set, it will become a child of the check object and
+ * be deleted when the check object is deleted. If another icon object is set
+ * then the previous one becomes orophaned and will no longer be deleted along
+ * with the check.
+ *
+ * @param obj The check object
+ * @param icon The icon object
+ *
+ * @ingroup Check
+ */
+EAPI void
+elm_check_icon_set(Evas_Object *obj, Evas_Object *icon)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if ((wd->icon != icon) && (wd->icon))
+     elm_widget_sub_object_del(obj, wd->icon);
+   wd->icon = icon;
+   if (icon)
+     {
+       elm_widget_sub_object_add(obj, icon);
+       evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                      _changed_size_hints, obj);
+       edje_object_part_swallow(wd->chk, "elm.swallow.content", icon);
+       edje_object_signal_emit(wd->chk, "elm,state,icon,visible", "elm");
+       _sizing_eval(obj);
+     }
+}
+
+/**
+ * Get the icon object of the check object
+ *
+ * @param obj The check object
+ * @return The icon object
+ *
+ * @ingroup Check
+ */
+EAPI Evas_Object *
+elm_check_icon_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->icon;
+}
+
+/**
+ * Set the on/off state of the check object
+ *
+ * This sets the state of the check and will also set the value if pointed to
+ * to the state supplied, but will not call any callbacks.
+ *
+ * @param obj The check object
+ * @param state The state to use (1 == on, 0 == off)
+ *
+ * @ingroup Check
+ */
+EAPI void
+elm_check_state_set(Evas_Object *obj, Eina_Bool state)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (state != wd->state)
+     {
+       wd->state = state;
+       if (wd->statep) *wd->statep = wd->state;
+       if (wd->state)
+         edje_object_signal_emit(wd->chk, "elm,state,check,on", "elm");
+       else
+         edje_object_signal_emit(wd->chk, "elm,state,check,off", "elm");
+     }
+}
+
+/**
+ * Get the state of the check object
+ *
+ * @param obj The check object
+ * @return The boolean state
+ *
+ * @ingroup Check
+ */
+EAPI Eina_Bool
+elm_check_state_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->state;
+}
+
+/**
+ * Set a convenience pointer to a boolean to change
+ *
+ * This sets a pointer to a boolean, that, in addition to the check objects
+ * state will also be modified directly. To stop setting the object pointed
+ * to simply use NULL as the statep parameter. If statep is not NULL, then
+ * when this is called, the check objects state will also be modified to
+ * reflect the value of the boolean statep points to, just like calling
+ * elm_check_state_set().
+ *
+ * @param obj The check object
+ * @param statep Pointer to the boolean to modify
+ *
+ * @ingroup Check
+ */
+EAPI void
+elm_check_state_pointer_set(Evas_Object *obj, Eina_Bool *statep)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (statep)
+     {
+       wd->statep = statep;
+       if (*wd->statep != wd->state)
+         {
+            wd->state = *wd->statep;
+            if (wd->state)
+              edje_object_signal_emit(wd->chk, "elm,state,check,on", "elm");
+            else
+              edje_object_signal_emit(wd->chk, "elm,state,check,off", "elm");
+         }
+     }
+   else
+     wd->statep = NULL;
+}
diff --git a/src/lib/elm_clock.c b/src/lib/elm_clock.c
new file mode 100644 (file)
index 0000000..092f1a7
--- /dev/null
@@ -0,0 +1,658 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Clock Clock
+ *
+ * It's a widget to show clock with animation. The update of time is
+ * shown in an animation like the flip of a sheet.
+ *
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *clk;
+   Eina_Bool seconds : 1;
+   Eina_Bool am_pm : 1;
+   Eina_Bool edit : 1;
+   unsigned int digedit;
+   int hrs, min, sec;
+   Evas_Object *digit[6];
+   Evas_Object *ampm;
+   Ecore_Timer *ticker;
+   struct 
+     {
+        int hrs, min, sec;
+        char ampm;
+        Eina_Bool seconds : 1;
+        Eina_Bool am_pm : 1;
+        Eina_Bool edit : 1;
+       unsigned int digedit;
+     } cur;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static int _ticker(void *data);
+static void _signal_clock_val_up(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_clock_val_down(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _time_update(Evas_Object *obj);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   int i;
+   for (i = 0; i < 6; i++)
+     {
+       if (wd->digit[i]) evas_object_del(wd->digit[i]);
+     }
+   if (wd->ampm) evas_object_del(wd->ampm);
+   if (wd->ticker) ecore_timer_del(wd->ticker);
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (elm_widget_focus_get(obj))
+     edje_object_signal_emit(wd->clk, "elm,action,focus", "elm");
+   else
+     edje_object_signal_emit(wd->clk, "elm,action,unfocus", "elm");
+   wd->cur.am_pm = !wd->cur.am_pm; /* hack - force update */
+   _time_update(obj);
+}
+
+static void
+_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (elm_widget_focus_get(obj))
+     edje_object_signal_emit(wd->clk, "elm,action,focus", "elm");
+   else
+     edje_object_signal_emit(wd->clk, "elm,action,unfocus", "elm");
+}
+
+static int
+_ticker(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   double t;
+   struct timeval timev;
+   struct tm *tm;
+   time_t tt;
+   if (!wd) return 0;
+   gettimeofday(&timev, NULL);
+   t = ((double)(1000000 - timev.tv_usec)) / 1000000.0;
+   wd->ticker = ecore_timer_add(t, _ticker, data);
+   if (!wd->edit)
+     {
+       tt = (time_t)(timev.tv_sec);
+       tzset();
+       tm = localtime(&tt);
+       if (tm)
+         {
+            wd->hrs = tm->tm_hour;
+            wd->min = tm->tm_min;
+            wd->sec = tm->tm_sec;
+            _time_update(data);
+         }
+     }
+   return 0;
+}
+
+static void
+_signal_clock_val_up(void *data, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (!wd->edit) return;
+   if (obj == wd->digit[0])
+     {
+       wd->hrs = wd->hrs + 10;
+       if (wd->hrs >= 24) wd->hrs -= 24;
+     }
+   if (obj == wd->digit[1])
+     {
+       wd->hrs = wd->hrs + 1;
+       if (wd->hrs >= 24) wd->hrs -= 24;
+     }
+   if (obj == wd->digit[2])
+     {
+       wd->min = wd->min + 10;
+       if (wd->min >= 60) wd->min -= 60;
+     }
+   if (obj == wd->digit[3])
+     {
+       wd->min = wd->min + 1;
+       if (wd->min >= 60) wd->min -= 60;
+     }
+   if (obj == wd->digit[4])
+     {
+       wd->sec = wd->sec + 10;
+       if (wd->sec >= 60) wd->sec -= 60;
+     }
+   if (obj == wd->digit[5])
+     {
+       wd->sec = wd->sec + 1;
+       if (wd->sec >= 60) wd->sec -= 60;
+     }
+   if (obj == wd->ampm)
+     {
+       wd->hrs = wd->hrs + 12;
+       if (wd->hrs > 23) wd->hrs -= 24;
+     }
+   _time_update(data);
+   evas_object_smart_callback_call(data, "changed", NULL);
+}
+
+static void
+_signal_clock_val_down(void *data, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (!wd->edit) return;
+   if (obj == wd->digit[0])
+     {
+       wd->hrs = wd->hrs - 10;
+       if (wd->hrs < 0) wd->hrs += 24;
+     }
+   if (obj == wd->digit[1])
+     {
+       wd->hrs = wd->hrs - 1;
+       if (wd->hrs < 0) wd->hrs += 24;
+     }
+   if (obj == wd->digit[2])
+     {
+       wd->min = wd->min - 10;
+       if (wd->min < 0) wd->min += 60;
+     }
+   if (obj == wd->digit[3])
+     {
+       wd->min = wd->min - 1;
+       if (wd->min < 0) wd->min += 60;
+     }
+   if (obj == wd->digit[4])
+     {
+       wd->sec = wd->sec - 10;
+       if (wd->sec < 0) wd->sec += 60;
+     }
+   if (obj == wd->digit[5])
+     {
+       wd->sec = wd->sec - 1;
+       if (wd->sec < 0) wd->sec += 60;
+     }
+   if (obj == wd->ampm)
+     {
+       wd->hrs = wd->hrs - 12;
+       if (wd->hrs < 0) wd->hrs += 24;
+     }
+   _time_update(data);
+   evas_object_smart_callback_call(data, "changed", NULL);
+}
+
+static void
+_time_update(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Edje_Message_Int msg;
+   int ampm = 0;
+   const char *style = elm_widget_style_get(obj);
+   if (!wd) return;
+   if ((wd->cur.seconds != wd->seconds) || (wd->cur.am_pm != wd->am_pm) ||
+       (wd->cur.edit != wd->edit) || (wd->cur.digedit != wd->digedit))
+     {
+       int i;
+       Evas_Coord mw, mh;
+
+       for (i = 0; i < 6; i++)
+         {
+            if (wd->digit[i])
+              {
+                 evas_object_del(wd->digit[i]);
+                 wd->digit[i] = NULL;
+              }
+         }
+       if (wd->ampm)
+         {
+            evas_object_del(wd->ampm);
+            wd->ampm = NULL;
+         }
+
+       if ((wd->seconds) && (wd->am_pm))
+         _elm_theme_object_set(obj, wd->clk, "clock", "base-all", style);
+       else if (wd->seconds)
+         _elm_theme_object_set(obj, wd->clk, "clock", "base-seconds", style);
+       else if (wd->am_pm)
+         _elm_theme_object_set(obj, wd->clk, "clock", "base-am_pm", style);
+       else
+         _elm_theme_object_set(obj, wd->clk, "clock", "base", style);
+       edje_object_scale_set(wd->clk, elm_widget_scale_get(obj) * 
+                              _elm_config->scale);
+
+       for (i = 0; i < 6; i++)
+         {
+            char buf[16];
+
+            if ((!wd->seconds) && (i >= 4)) break;
+            wd->digit[i] = edje_object_add(evas_object_evas_get(wd->clk));
+            _elm_theme_object_set(obj, wd->digit[i], "clock", "flipdigit", style);
+            edje_object_scale_set(wd->digit[i], elm_widget_scale_get(obj) * 
+                                   _elm_config->scale);
+            if (wd->edit && (wd->digedit & (1 << i)))
+              edje_object_signal_emit(wd->digit[i], "elm,state,edit,on", "elm");
+            edje_object_signal_callback_add(wd->digit[i], "elm,action,up", "",
+                                            _signal_clock_val_up, obj);
+            edje_object_signal_callback_add(wd->digit[i], "elm,action,down", "",
+                                            _signal_clock_val_down, obj);
+            mw = mh = -1;
+            elm_coords_finger_size_adjust(1, &mw, 2, &mh);
+            edje_object_size_min_restricted_calc(wd->digit[i], &mw, &mh, mw, mh);
+            elm_coords_finger_size_adjust(1, &mw, 2, &mh);
+            edje_extern_object_min_size_set(wd->digit[i], mw, mh);
+            snprintf(buf, sizeof(buf), "d%i", i);
+            edje_object_part_swallow(wd->clk , buf, wd->digit[i]);
+            evas_object_show(wd->digit[i]);
+         }
+       if (wd->am_pm)
+         {
+            wd->ampm = edje_object_add(evas_object_evas_get(wd->clk));
+            _elm_theme_object_set(obj, wd->ampm, "clock", "flipampm", style);
+            edje_object_scale_set(wd->ampm, elm_widget_scale_get(obj) * 
+                                   _elm_config->scale);
+            if (wd->edit)
+              edje_object_signal_emit(wd->ampm, "elm,state,edit,on", "elm");
+            edje_object_signal_callback_add(wd->ampm, "elm,action,up", "",
+                                            _signal_clock_val_up, obj);
+            edje_object_signal_callback_add(wd->ampm, "elm,action,down", "",
+                                            _signal_clock_val_down, obj);
+            mw = mh = -1;
+            elm_coords_finger_size_adjust(1, &mw, 2, &mh);
+            edje_object_size_min_restricted_calc(wd->ampm, &mw, &mh, mw, mh);
+            elm_coords_finger_size_adjust(1, &mw, 2, &mh);
+            edje_extern_object_min_size_set(wd->ampm, mw, mh);
+            edje_object_part_swallow(wd->clk , "ampm", wd->ampm);
+            evas_object_show(wd->ampm);
+         }
+
+       edje_object_size_min_calc(wd->clk, &mw, &mh);
+       evas_object_size_hint_min_set(obj, mw, mh);
+
+       wd->cur.hrs = 0;
+       wd->cur.min = 0;
+       wd->cur.sec = 0;
+       wd->cur.ampm = -1;
+       wd->cur.seconds = wd->seconds;
+       wd->cur.am_pm = wd->am_pm;
+       wd->cur.edit = wd->edit;
+       wd->cur.digedit = wd->digedit;
+     }
+   if (wd->hrs != wd->cur.hrs)
+     {
+       int hrs;
+       int d1, d2, dc1, dc2;
+
+       hrs = wd->hrs;
+       if (wd->am_pm)
+         {
+            if (hrs >= 12)
+              {
+                 if (hrs > 12) hrs -= 12;
+                 ampm = 1;
+              }
+            else if (hrs == 0) hrs = 12;
+         }
+       d1 = hrs / 10;
+       d2 = hrs % 10;
+       dc1 = wd->cur.hrs / 10;
+       dc2 = wd->cur.hrs % 10;
+       if (d1 != dc1)
+         {
+            msg.val = d1;
+            edje_object_message_send(wd->digit[0], EDJE_MESSAGE_INT, 1, &msg);
+         }
+       if (d2 != dc2)
+         {
+            msg.val = d2;
+            edje_object_message_send(wd->digit[1], EDJE_MESSAGE_INT, 1, &msg);
+         }
+       wd->cur.hrs = hrs;
+     }
+   if (wd->min != wd->cur.min)
+     {
+       int d1, d2, dc1, dc2;
+
+       d1 = wd->min / 10;
+       d2 = wd->min % 10;
+       dc1 = wd->cur.min / 10;
+       dc2 = wd->cur.min % 10;
+       if (d1 != dc1)
+         {
+            msg.val = d1;
+            edje_object_message_send(wd->digit[2], EDJE_MESSAGE_INT, 1, &msg);
+         }
+       if (d2 != dc2)
+         {
+            msg.val = d2;
+            edje_object_message_send(wd->digit[3], EDJE_MESSAGE_INT, 1, &msg);
+         }
+       wd->cur.min = wd->min;
+     }
+   if (wd->seconds)
+     {
+       if (wd->sec != wd->cur.sec)
+         {
+            int d1, d2, dc1, dc2;
+
+            d1 = wd->sec / 10;
+            d2 = wd->sec % 10;
+            dc1 = wd->cur.sec / 10;
+            dc2 = wd->cur.sec % 10;
+            if (d1 != dc1)
+              {
+                 msg.val = d1;
+                 edje_object_message_send(wd->digit[4], EDJE_MESSAGE_INT, 1, &msg);
+              }
+            if (d2 != dc2)
+              {
+                 msg.val = d2;
+                 edje_object_message_send(wd->digit[5], EDJE_MESSAGE_INT, 1, &msg);
+              }
+            wd->cur.sec = wd->sec;
+         }
+     }
+   else
+     wd->cur.sec = -1;
+
+   if (wd->am_pm)
+     {
+       if (wd->hrs >= 12) ampm = 1;
+       if (ampm != wd->cur.ampm)
+         {
+            if (wd->cur.ampm != ampm)
+              {
+                 msg.val = ampm;
+                 edje_object_message_send(wd->ampm, EDJE_MESSAGE_INT, 1, &msg);
+              }
+            wd->cur.ampm = ampm;
+         }
+     }
+   else
+     wd->cur.ampm = -1;
+}
+
+/**
+ * Add a new clock to the parent
+ *
+ * @param parent The parent object
+ *
+ * This function inserts a clock widget on a given canvas to show a
+ * animated clock.
+ *
+ * @ingroup Clock
+ */
+EAPI Evas_Object *
+elm_clock_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "clock");
+   elm_widget_type_set(obj, "clock");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
+
+   wd->clk = edje_object_add(e);
+   elm_widget_resize_object_set(obj, wd->clk);
+
+   wd->cur.ampm = -1;
+   wd->cur.seconds = EINA_TRUE;
+   wd->cur.am_pm = EINA_TRUE;
+   wd->cur.edit = EINA_TRUE;
+   wd->cur.digedit = ELM_CLOCK_NONE;
+
+   _time_update(obj);
+   _ticker(obj);
+
+   return obj;
+}
+
+/**
+ * Set the clock time
+ *
+ * @param obj The clock object
+ * @param hrs The hours to set
+ * @param min The minutes to set
+ * @param sec The secondes to set
+ *
+ * This function updates the time that is showed by the clock widget
+ *
+ * @ingroup Clock
+ */
+EAPI void
+elm_clock_time_set(Evas_Object *obj, int hrs, int min, int sec)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->hrs = hrs;
+   wd->min = min;
+   wd->sec = sec;
+   _time_update(obj);
+}
+
+/**
+ * Get clock time
+ *
+ * @param obj The clock object
+ * @param hrs Pointer to the variable to get the hour of this clock
+ * object
+ * @param min Pointer to the variable to get the minute of this clock
+ * object
+ * @param sec Pointer to the variable to get the second of this clock
+ * object
+ *
+ * This function gets the time set of the clock widget and returns it
+ * on the variables passed as the arguments to function
+ *
+ * @ingroup Clock
+ */
+EAPI void
+elm_clock_time_get(const Evas_Object *obj, int *hrs, int *min, int *sec)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (hrs) *hrs = wd->hrs;
+   if (min) *min = wd->min;
+   if (sec) *sec = wd->sec;
+}
+
+/**
+ * Set if the clock settings can be edited
+ *
+ * @param obj The clock object
+ * @param edit Bool option for edited (1 = yes, 0 = no)
+ *
+ * This function sets if the clock settings can be edited or not.
+ * By default or if digit_edit option was previously set to ELM_CLOCK_NONE,
+ * all digits are editable. To choose what digits to make editable
+ * use elm_clock_digit_edit_set().
+ *
+ * @ingroup Clock
+ */
+EAPI void
+elm_clock_edit_set(Evas_Object *obj, Eina_Bool edit)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->edit = edit;
+   if (edit && (wd->digedit == ELM_CLOCK_NONE))
+     elm_clock_digit_edit_set(obj, ELM_CLOCK_ALL);
+   else
+     _time_update(obj);
+}
+
+/**
+ * Get if the clock settings can be edited
+ *
+ * @param obj The clock object
+ * @return Bool option for edited (1 = yes, 0 = no)
+ *
+ * This function gets if the clock settings can be edited or not.
+ *
+ * @ingroup Clock
+ */
+EAPI Eina_Bool
+elm_clock_edit_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->edit;
+}
+
+/**
+ * Set what digits of the clock are editable
+ *
+ * @param obj The clock object
+ * @param digedit Bit mask indicating the digits to edit
+ *
+ * If the digedit param is ELM_CLOCK_NONE, editing will be disabled.
+ *
+ * @ingroup Clock
+ */
+EAPI void
+elm_clock_digit_edit_set(Evas_Object *obj, Elm_Clock_Digedit digedit)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->digedit = digedit;
+   if (digedit == ELM_CLOCK_NONE)
+     elm_clock_edit_set(obj, EINA_FALSE);
+   else
+     _time_update(obj);
+}
+
+/**
+ * Get what digits of the clock are editable
+ *
+ * @param obj The clock object
+ * @return Bit mask indicating the digits.
+ *
+ * @ingroup Clock
+ */
+EAPI unsigned int
+elm_clock_digit_edit_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   return wd->digedit;
+}
+
+/**
+ * Set if the clock shows hours in military or am/pm mode
+ *
+ * @param obj The clock object
+ * @param am_pm Bool option for the hours mode
+ * (1 = am/pm, 0 = military)
+ *
+ * This function sets the clock to show hours in military or am/pm
+ * mode. Some countries like Brazil the military mode (00-24h-format)
+ * is used in opposition to the USA where the am/pm mode is more
+ * common used.
+ *
+ * @ingroup Clock
+ */
+EAPI void
+elm_clock_show_am_pm_set(Evas_Object *obj, Eina_Bool am_pm)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->am_pm = am_pm;
+   _time_update(obj);
+}
+
+/**
+ * Get if the clock shows hours in military or am/pm mode
+ *
+ * @param obj The clock object
+ * @return Bool option for the hours mode
+ * (1 = am/pm, 0 = military)
+ *
+ * This function gets if the clock show hours in military or am/pm
+ * mode. Some countries like Brazil the military mode (00-24h-format)
+ * is used in opposition to the USA where the am/pm mode is more
+ * common used.
+ *
+ * @ingroup Clock
+ */
+EAPI Eina_Bool
+elm_clock_show_am_pm_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->am_pm;
+}
+
+/**
+ * Set if the clock shows hour with the seconds
+ *
+ * @param obj The clock object
+ * @param seconds Bool option for the show seconds
+ * (1 = show seconds, 0 = not show seconds)
+ *
+ * This function sets the clock to show or not to show the elapsed
+ * seconds.
+ *
+ * @ingroup Clock
+ */
+EAPI void
+elm_clock_show_seconds_set(Evas_Object *obj, Eina_Bool seconds)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->seconds = seconds;
+   _time_update(obj);
+}
+
+/**
+ * Get if the clock shows hour with the seconds
+ *
+ * @param obj The clock object
+ * @return Bool option for the show seconds
+ * (1 = show seconds, 0 = not show seconds)
+ *
+ * This function gets if the clock show or not show the elapsed
+ * seconds.
+ *
+ * @ingroup Clock
+ */
+EAPI Eina_Bool
+elm_clock_show_seconds_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->seconds;
+}
diff --git a/src/lib/elm_config.c b/src/lib/elm_config.c
new file mode 100644 (file)
index 0000000..97a265d
--- /dev/null
@@ -0,0 +1,633 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include <Elementary.h>
+#include "elm_priv.h"
+
+Elm_Config *_elm_config = NULL;
+char *_elm_profile = NULL;
+static Eet_Data_Descriptor *_config_edd = NULL;
+
+static void _desc_init(void);
+static void _desc_shutdown(void);
+static void _profile_get(void);
+static void _config_free(void);
+static void _config_apply(void);
+static void _config_load(void);
+static void _env_get(void);
+
+#ifdef HAVE_ELEMENTARY_X
+static Ecore_Event_Handler *_prop_change_handler = NULL;
+static Ecore_X_Window _root_1st = 0;
+#define ATOM_COUNT 5
+static Ecore_X_Atom _atom[ATOM_COUNT];
+static Ecore_X_Atom _atom_config = 0;
+static Ecore_X_Atom _atom_config_specific = 0;
+static const char *_atom_names[ATOM_COUNT] =
+{
+     "ENLIGHTENMENT_SCALE",
+     "ENLIGHTENMENT_FINGER_SIZE",
+     "ENLIGHTENMENT_THEME",
+     "ENLIGHTENMENT_PROFILE",
+     "ENLIGHTENMENT_CONFIG"
+};
+#define ATOM_E_SCALE 0
+#define ATOM_E_FINGER_SIZE 1
+#define ATOM_E_THEME 2
+#define ATOM_E_PROFILE 3
+#define ATOM_E_CONFIG 4
+
+static Eina_Bool _prop_config_get(void);
+static int _prop_change(void *data __UNUSED__, int ev_type __UNUSED__, void *ev);
+
+static Eina_Bool
+_prop_config_get(void)
+{
+   int size = 0;
+   Ecore_X_Atom atom;
+   char buf[512];
+   unsigned char *data = NULL, *config_data;
+   
+   snprintf(buf, sizeof(buf), "ENLIGHTENMENT_CONFIG_%s", _elm_profile);
+   atom = ecore_x_atom_get(buf);
+   _atom_config = atom;
+   if (!ecore_x_window_prop_property_get(_root_1st,
+                                         atom, _atom[ATOM_E_CONFIG], 
+                                         8, &data, &size))
+     {
+        if (!ecore_x_window_prop_property_get(_root_1st, 
+                                              _atom[ATOM_E_CONFIG], 
+                                              _atom[ATOM_E_CONFIG], 
+                                              8, &data, &size))
+          return 0;
+        else
+          _atom_config = _atom[ATOM_E_CONFIG];
+     }
+   else
+     _atom_config = atom;
+   if (size < 1)
+     {
+        free(data);
+        return 0;
+     }
+   config_data = eet_data_descriptor_decode(_config_edd, data, size);
+   free(data);
+   if (!config_data) return 0;
+   _config_free();
+   _elm_config = config_data;
+   _config_apply();
+   _elm_rescale();
+   return 1;
+}
+
+static int
+_prop_change(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
+{
+   Ecore_X_Event_Window_Property *event = ev;
+
+   if (event->win == _root_1st)
+     {
+       if (event->atom == _atom[ATOM_E_SCALE])
+         {
+            unsigned int val = 1000;
+
+            if (ecore_x_window_prop_card32_get(event->win,
+                                               event->atom,
+                                               &val, 1) > 0)
+              {
+                 double pscale;
+
+                 pscale = _elm_config->scale;
+                 if (val > 0) _elm_config->scale = (double)val / 1000.0;
+                 if (pscale != _elm_config->scale) _elm_rescale();
+              }
+         }
+       else if (event->atom == _atom[ATOM_E_FINGER_SIZE])
+         {
+            unsigned int val = 1000;
+
+            if (ecore_x_window_prop_card32_get(event->win,
+                                               event->atom,
+                                               &val, 1) > 0)
+              {
+                 int pfinger_size;
+
+                 pfinger_size = _elm_config->finger_size;
+                 _elm_config->finger_size = val;
+                 if (pfinger_size != _elm_config->finger_size) _elm_rescale();
+              }
+         }
+       else if (event->atom == _atom[ATOM_E_THEME])
+         {
+             char *val = NULL;
+             
+             val = ecore_x_window_prop_string_get(event->win,
+                                                  event->atom);
+            eina_stringshare_replace(&_elm_config->theme, val);
+            if (val)
+              {
+                 _elm_theme_parse(NULL, val);
+                 free(val);
+                 _elm_rescale();
+              }
+         }
+       else if (event->atom == _atom[ATOM_E_PROFILE])
+          {
+             char *val = NULL;
+             
+             val = ecore_x_window_prop_string_get(event->win,
+                                                  event->atom);
+            eina_stringshare_replace(&_elm_config->theme, val);
+            if (val)
+              {
+                  int changed = 0;
+                  
+                  if (_elm_profile)
+                    {
+                       if (strcmp(_elm_profile, val)) changed = 1;
+                       free(_elm_profile);
+                    }
+                  _elm_profile = val;
+                  if (changed)
+                    {
+                       if (!_prop_config_get())
+                         {
+                            _config_free();
+                            _config_load();
+                            _config_apply();
+                            _elm_rescale();
+                         }
+                    }
+              }
+          }
+       else if (((_atom_config > 0) && (event->atom == _atom_config)) ||
+                 (event->atom == _atom[ATOM_E_CONFIG]))
+          {
+             _prop_config_get();
+          }
+     }
+   return 1;
+}
+#endif
+
+static void
+_desc_init(void)
+{
+   Eet_Data_Descriptor_Class eddc;
+   
+   EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Config);
+   eddc.func.str_direct_alloc = NULL;
+   eddc.func.str_direct_free = NULL;
+   
+   _config_edd = eet_data_descriptor_file_new(&eddc);
+   if (!_config_edd)
+     {
+        printf("EEEK! eet_data_descriptor_file_new() failed\n");
+        return;
+     }
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "engine", engine, EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "thumbscroll_enable", thumbscroll_enable, EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "thumbscroll_threshhold", thumbscroll_threshhold, EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "thumbscroll_momentum_threshhold", thumbscroll_momentum_threshhold, EET_T_DOUBLE);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "thumbscroll_friction", thumbscroll_friction, EET_T_DOUBLE);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "thumbscroll_bounce_friction", thumbscroll_bounce_friction, EET_T_DOUBLE);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "page_scroll_friction", page_scroll_friction, EET_T_DOUBLE);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "bring_in_scroll_friction", bring_in_scroll_friction, EET_T_DOUBLE);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "zoom_friction", zoom_friction, EET_T_DOUBLE);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "thumbscroll_bounce_enable", thumbscroll_bounce_enable, EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "scale", scale, EET_T_DOUBLE);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "bgpixmap", bgpixmap, EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "compositing", compositing, EET_T_INT);
+   // EET_DATA_DESCRIPTOR_ADD_LIST(_config_edd, Elm_Config, "font_dirs", font_dirs, sub_edd);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "font_hinting", font_hinting, EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "image_cache", image_cache, EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "font_cache", font_cache, EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "finger_size", finger_size, EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "fps", fps, EET_T_DOUBLE);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "theme", theme, EET_T_STRING);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "modules", modules, EET_T_STRING);
+}
+
+static void
+_desc_shutdown(void)
+{
+   if (!_config_edd) return;
+   eet_data_descriptor_free(_config_edd);
+   _config_edd = NULL;
+}
+
+static void
+_profile_get(void)
+{
+   Eet_File *ef = NULL;
+   const char *home = NULL;
+   char buf[PATH_MAX], *p, *s;
+   int len = 0;
+
+   _elm_profile = strdup("default");
+   
+   // if env var - use profile without question
+   s = getenv("ELM_PROFILE");
+   if (s)
+     {
+        free(_elm_profile);
+        _elm_profile = strdup(s);
+        return;
+     }
+   
+   home = getenv("HOME");
+   if (!home) home = "/";
+   
+   // usser profile
+   snprintf(buf, sizeof(buf), "%s/.elementary/config/profile.cfg", home);
+   ef = eet_open(buf, EET_FILE_MODE_READ);
+   if (ef)
+     {
+        p = eet_read(ef, "config", &len);
+        if (p)
+          {
+             free(_elm_profile);
+             _elm_profile = malloc(len + 1);
+             memcpy(_elm_profile, p, len);
+             _elm_profile[len] = 0;
+             free(p);
+          }
+        eet_close(ef);
+        if (!p) ef = NULL;
+     }
+   if (ef) return;
+   
+   // system profile
+   snprintf(buf, sizeof(buf), "%s/config/profile.cfg", _elm_data_dir);
+   ef = eet_open(buf, EET_FILE_MODE_READ);
+   if (ef)
+     {
+        p = eet_read(ef, "config", &len);
+        if (p)
+          {
+             free(_elm_profile);
+             _elm_profile = malloc(len + 1);
+             memcpy(_elm_profile, p, len);
+             _elm_profile[len] = 0;
+             free(p);
+          }
+        eet_close(ef);
+     }
+}
+
+static void
+_config_free(void)
+{
+   const char *fontdir;
+   
+   if (!_elm_config) return;
+   EINA_LIST_FREE(_elm_config->font_dirs, fontdir)
+     {
+        eina_stringshare_del(fontdir);
+     }
+   if (_elm_config->theme) eina_stringshare_del(_elm_config->theme);
+   if (_elm_config->modules) eina_stringshare_del(_elm_config->modules);
+   free(_elm_config);
+   _elm_config = NULL;
+}
+
+static void
+_config_apply(void)
+{
+   _elm_theme_parse(NULL, _elm_config->theme);
+   if (_elm_config->modules) _elm_module_parse(_elm_config->modules);
+   ecore_animator_frametime_set(1.0 / _elm_config->fps);
+   edje_frametime_set(1.0 / _elm_config->fps);
+   edje_scale_set(_elm_config->scale);
+}
+
+static void
+_config_load(void)
+{
+   Eet_File *ef = NULL;
+   char buf[PATH_MAX];
+   const char *home = NULL;
+   
+   home = getenv("HOME");
+   if (!home) home = "/";
+   
+   // user config
+   snprintf(buf, sizeof(buf), "%s/.elementary/config/%s/base.cfg", home, _elm_profile);
+   ef = eet_open(buf, EET_FILE_MODE_READ);
+   if (ef)
+     {
+        _elm_config = eet_data_read(ef, _config_edd, "config");
+        eet_close(ef);
+     }
+   if (_elm_config) return;
+   
+   // system config
+   snprintf(buf, sizeof(buf), "%s/config/%s/base.cfg", _elm_data_dir, _elm_profile);
+   ef = eet_open(buf, EET_FILE_MODE_READ);
+   if (ef)
+     {
+        _elm_config = eet_data_read(ef, _config_edd, "config");
+        eet_close(ef);
+     }
+   if (_elm_config) return;
+
+   // config load fail - defaults
+   _elm_config = ELM_NEW(Elm_Config);
+   _elm_config->engine = ELM_SOFTWARE_X11;
+   _elm_config->thumbscroll_enable = 1;
+   _elm_config->thumbscroll_threshhold = 24;
+   _elm_config->thumbscroll_momentum_threshhold = 100.0;
+   _elm_config->thumbscroll_friction = 1.0;
+   _elm_config->thumbscroll_bounce_friction = 0.5;
+   _elm_config->page_scroll_friction = 0.5;
+   _elm_config->bring_in_scroll_friction = 0.5;
+   _elm_config->zoom_friction = 0.5;
+   _elm_config->thumbscroll_bounce_enable = 1;
+   _elm_config->scale = 1.0;
+   _elm_config->bgpixmap = 0;
+   _elm_config->font_hinting = 2;
+   _elm_config->font_dirs = NULL;
+   _elm_config->image_cache = 4096;
+   _elm_config->font_cache = 512;
+   _elm_config->finger_size = 40;
+   _elm_config->compositing = 1;
+   _elm_config->fps = 60.0;
+   _elm_config->theme = eina_stringshare_add("default");
+   _elm_config->modules = NULL;
+}
+
+static void
+_env_get(void)
+{
+   char buf[PATH_MAX], *p, *s;
+   
+   s = getenv("ELM_ENGINE");
+   if (s)
+     {
+        if ((!strcasecmp(s, "x11")) ||
+            (!strcasecmp(s, "x")) ||
+            (!strcasecmp(s, "software-x11")) ||
+            (!strcasecmp(s, "software_x11")))
+          _elm_config->engine = ELM_SOFTWARE_X11;
+        else if ((!strcasecmp(s, "x11-16")) ||
+                 (!strcasecmp(s, "x16")) ||
+                 (!strcasecmp(s, "software-16-x11")) ||
+                 (!strcasecmp(s, "software_16_x11")))
+          _elm_config->engine = ELM_SOFTWARE_16_X11;
+        else if ((!strcasecmp(s, "xrender")) ||
+                 (!strcasecmp(s, "xr")) ||
+                 (!strcasecmp(s, "xrender-x11")) ||
+                 (!strcasecmp(s, "xrender_x11")))
+          _elm_config->engine = ELM_XRENDER_X11;
+        else if ((!strcasecmp(s, "fb")) ||
+                 (!strcasecmp(s, "software-fb")) ||
+                 (!strcasecmp(s, "software_fb")))
+          _elm_config->engine = ELM_SOFTWARE_FB;
+        else if ((!strcasecmp(s, "directfb")) ||
+                 (!strcasecmp(s, "dfb")))
+          _elm_config->engine = ELM_SOFTWARE_DIRECTFB;
+        else if ((!strcasecmp(s, "sdl")) ||
+                 (!strcasecmp(s, "software-sdl")) ||
+                 (!strcasecmp(s, "software_sdl")))
+          _elm_config->engine = ELM_SOFTWARE_SDL;
+        else if ((!strcasecmp(s, "sdl-16")) ||
+                 (!strcasecmp(s, "software-16-sdl")) ||
+                 (!strcasecmp(s, "software_16_sdl")))
+          _elm_config->engine = ELM_SOFTWARE_16_SDL;
+        else if ((!strcasecmp(s, "opengl")) ||
+                 (!strcasecmp(s, "gl")) ||
+                 (!strcasecmp(s, "opengl-x11")) ||
+                 (!strcasecmp(s, "opengl_x11")))
+          _elm_config->engine = ELM_OPENGL_X11;
+        else if ((!strcasecmp(s, "opengl-sdl")) ||
+                 (!strcasecmp(s, "opengl_sdl")) ||
+                 (!strcasecmp(s, "gl-sdl")) ||
+                 (!strcasecmp(s, "gl_sdl")))
+          _elm_config->engine = ELM_OPENGL_SDL;
+        else if ((!strcasecmp(s, "gdi")) ||
+                 (!strcasecmp(s, "software-gdi")) ||
+                 (!strcasecmp(s, "software_gdi")))
+          _elm_config->engine = ELM_SOFTWARE_WIN32;
+        else if ((!strcasecmp(s, "wince-gdi")) ||
+                 (!strcasecmp(s, "software-16-wince-gdi")) ||
+                 (!strcasecmp(s, "software_16_wince_gdi")))
+          _elm_config->engine = ELM_SOFTWARE_16_WINCE;
+     }
+
+   s = getenv("ELM_THUMBSCROLL_ENABLE");
+   if (s) _elm_config->thumbscroll_enable = atoi(s);
+   s = getenv("ELM_THUMBSCROLL_THRESHOLD");
+   if (s) _elm_config->thumbscroll_threshhold = atoi(s);
+   // FIXME: floatformat locale issues here 1.0 vs 1,0 - should just be 1.0
+   s = getenv("ELM_THUMBSCROLL_MOMENTUM_THRESHOLD");
+   if (s) _elm_config->thumbscroll_momentum_threshhold = atof(s);
+   s = getenv("ELM_THUMBSCROLL_FRICTION");
+   if (s) _elm_config->thumbscroll_friction = atof(s);
+   s = getenv("ELM_PAGE_SCROLL_FRICTION");
+   if (s) _elm_config->page_scroll_friction = atof(s);
+   s = getenv("ELM_BRING_IN_SCROLL_FRICTION");
+   if (s) _elm_config->bring_in_scroll_friction = atof(s);
+   s = getenv("ELM_ZOOM_FRICTION");
+   if (s) _elm_config->zoom_friction = atof(s);
+
+   s = getenv("ELM_THEME");
+   if (s) eina_stringshare_replace(&_elm_config->theme, s);
+
+   s = getenv("ELM_FONT_HINTING");
+   if (s)
+     {
+       if      (!strcasecmp(s, "none"))     _elm_config->font_hinting = 0;
+       else if (!strcasecmp(s, "auto"))     _elm_config->font_hinting = 1;
+       else if (!strcasecmp(s, "bytecode")) _elm_config->font_hinting = 2;
+     }
+
+   s = getenv("ELM_FONT_PATH");
+   if (s)
+     {
+       const char *p, *pp;
+       char *buf2;
+
+        EINA_LIST_FREE(_elm_config->font_dirs, p)
+          {
+             eina_stringshare_del(p);
+          }
+        
+       buf2 = alloca(strlen(s) + 1);
+       p = s;
+       pp = p;
+       for (;;)
+         {
+            if ((*p == ':') || (*p == 0))
+              {
+                 int len;
+
+                 len = p - pp;
+                 strncpy(buf2, pp, len);
+                 buf2[len] = 0;
+                 _elm_config->font_dirs = 
+                    eina_list_append(_elm_config->font_dirs, 
+                                     eina_stringshare_add(buf2));
+                 if (*p == 0) break;
+                 p++;
+                 pp = p;
+              }
+            else
+              {
+                 if (*p == 0) break;
+                 p++;
+              }
+         }
+     }
+
+   s = getenv("ELM_IMAGE_CACHE");
+   if (s) _elm_config->image_cache = atoi(s);
+
+   s = getenv("ELM_FONT_CACHE");
+   if (s) _elm_config->font_cache = atoi(s);
+
+   s = getenv("ELM_SCALE");
+   if (s) _elm_config->scale = atof(s);
+   
+   _elm_config->finger_size = (double)_elm_config->finger_size * _elm_config->scale;
+   s = getenv("ELM_FINGER_SIZE");
+   if (s) _elm_config->finger_size = atoi(s);
+
+   s = getenv("ELM_FPS");
+   if (s) _elm_config->fps = atof(s);
+   if (_elm_config->fps < 1.0) _elm_config->fps = 1.0;
+
+   s = getenv("ELM_MODULES");
+   if (s) eina_stringshare_replace(&_elm_config->modules, s);
+}
+
+void
+_elm_config_init(void)
+{
+   _desc_init();
+   _profile_get();
+   _config_load();
+   _env_get();
+   _config_apply();
+}
+
+void
+_elm_config_sub_init(void)
+{
+   if ((_elm_config->engine == ELM_SOFTWARE_X11) ||
+       (_elm_config->engine == ELM_SOFTWARE_16_X11) ||
+       (_elm_config->engine == ELM_XRENDER_X11) ||
+       (_elm_config->engine == ELM_OPENGL_X11))
+     {
+#ifdef HAVE_ELEMENTARY_X
+       unsigned int val = 1000;
+
+       if (!ecore_x_init(NULL))
+         {
+            ERR("Cannot connect to X11 display. check $DISPLAY variable");
+            exit(1);
+         }
+        _root_1st = ecore_x_window_root_first_get();
+        
+       if (!ecore_x_screen_is_composited(0))
+         _elm_config->compositing = 0;
+
+        ecore_x_atoms_get(_atom_names, ATOM_COUNT, _atom);
+       ecore_x_event_mask_set(_root_1st,
+                              ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
+       _prop_change_handler = ecore_event_handler_add
+         (ECORE_X_EVENT_WINDOW_PROPERTY, _prop_change, NULL);
+       if (!getenv("ELM_SCALE"))
+         {
+            if (ecore_x_window_prop_card32_get(_root_1st,
+                                               _atom[ATOM_E_SCALE],
+                                               &val, 1) > 0)
+              {
+                 if (val > 0)
+                   {
+                      _elm_config->scale = (double)val / 1000.0;
+                      // FIXME: hack until e export finger size too
+                      if (getenv("ELM_FINGER_SIZE"))
+                        _elm_config->finger_size = 40.0 * _elm_config->scale;
+                       edje_scale_set(_elm_config->scale);
+                   }
+              }
+         }
+       if (!getenv("ELM_FINGER_SIZE"))
+         {
+            if (ecore_x_window_prop_card32_get(_root_1st,
+                                               _atom[ATOM_E_FINGER_SIZE],
+                                               &val, 1) > 0)
+              {
+                 if (val > 0)
+                   {
+                      _elm_config->finger_size = val;
+                   }
+              }
+         }
+       if (!getenv("ELM_THEME"))
+         {
+             char *s;
+             
+             s = ecore_x_window_prop_string_get(_root_1st,
+                                               _atom[ATOM_E_THEME]);
+             if (s)
+              {
+                 eina_stringshare_replace(&_elm_config->theme, s);
+                  _elm_theme_parse(NULL, s);
+                  free(s);
+              }
+         }
+       if (!getenv("ELM_PROFILE"))
+         {
+             char *s;
+             
+             s = ecore_x_window_prop_string_get(_root_1st,
+                                               _atom[ATOM_E_PROFILE]);
+             if (s)
+              {
+                  int changed = 0;
+                  
+                  if (_elm_profile)
+                    {
+                       if (strcmp(_elm_profile, s)) changed = 1;
+                       free(_elm_profile);
+                    }
+                  _elm_profile = s;
+                  if (changed) _prop_config_get();
+              }
+         }
+#endif
+      }
+}
+
+void
+_elm_config_shutdown(void)
+{
+   if ((_elm_config->engine == ELM_SOFTWARE_X11) ||
+       (_elm_config->engine == ELM_SOFTWARE_16_X11) ||
+       (_elm_config->engine == ELM_XRENDER_X11) ||
+       (_elm_config->engine == ELM_OPENGL_X11) ||
+       (_elm_config->engine == ELM_SOFTWARE_SDL) ||
+       (_elm_config->engine == ELM_SOFTWARE_16_SDL) ||
+       (_elm_config->engine == ELM_OPENGL_SDL) ||
+       (_elm_config->engine == ELM_SOFTWARE_WIN32) ||
+       (_elm_config->engine == ELM_SOFTWARE_16_WINCE))
+     {
+#ifdef HAVE_ELEMENTARY_X
+       ecore_event_handler_del(_prop_change_handler);
+       _prop_change_handler = NULL;
+#endif
+     }
+   _config_free();
+   if (_elm_profile)
+     {
+        free(_elm_profile);
+        _elm_profile = NULL;
+     }
+   _desc_shutdown();
+}
diff --git a/src/lib/elm_conform.c b/src/lib/elm_conform.c
new file mode 100644 (file)
index 0000000..85bceb9
--- /dev/null
@@ -0,0 +1,295 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Conformant Conformant
+ * 
+ * The aim is to provide a widget that can be used in elementary apps to 
+ * account for space taken up by the indicator & softkey windows when running 
+ * the illume2 module of E17.
+ */
+
+typedef struct _Widget_Data Widget_Data;
+struct _Widget_Data 
+{
+   Evas_Object *base;
+   Evas_Object *shelf, *panel;
+   Evas_Object *content;
+   Ecore_Event_Handler *prop_hdl;
+   struct {
+      Ecore_Animator *animator; // animaton timer
+      double start; // time started
+      Evas_Coord auto_x, auto_y; // desired delta
+      Evas_Coord x, y; // current delta
+   } delta;
+};
+
+/* local function prototypes */
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static int _prop_change(void *data, int type, void *event);
+
+/* local functions */
+static void 
+_del_hook(Evas_Object *obj) 
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->prop_hdl) ecore_event_handler_del(wd->prop_hdl);
+   free(wd);
+}
+
+static void 
+_theme_hook(Evas_Object *obj) 
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _elm_theme_object_set(obj, wd->base, "conformant", "base", elm_widget_style_get(obj));
+   if (wd->content)
+     edje_object_part_swallow(wd->base, "elm.swallow.content", wd->content);
+   edje_object_scale_set(wd->base, elm_widget_scale_get(obj) * _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+static void 
+_sizing_eval(Evas_Object *obj) 
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord mw = -1, mh = -1;
+   if (!wd) return;
+   edje_object_size_min_calc(wd->base, &mw, &mh);
+   evas_object_size_hint_min_set(obj, mw, mh);
+   evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *sub = event_info;
+   if (!wd) return;
+   if (sub == wd->content)
+     {
+        evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                            _changed_size_hints, obj);
+        wd->content = NULL;
+        _sizing_eval(obj);
+     }
+}
+
+/* unused now - but meant to be for making sure the focused widget is always
+ * visible when the vkbd comes and goes by moving the conformant obj (and thus
+ * its children) to  show the focused widget (and if focus changes follow)
+
+static Evas_Object *
+_focus_object_get(const Evas_Object *obj)
+{
+   Evas_Object *win, *foc;
+   
+   win = elm_widget_top_get(obj);
+   if (!win) return NULL;
+   foc = elm_widget_top_get(win);
+}
+
+static void
+_focus_object_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
+{
+   evas_object_geometry_get(obj, x, y, w, h);
+}
+
+static void
+_focus_change_del(void *data, Evas_Object *obj, void *event_info)
+{
+   // called from toplevel when the focused window shanges
+}
+
+static void
+_autoscroll_move(Evas_Object *obj)
+{
+   // move conformant edje by delta to show focused widget
+}
+
+static void
+_autoscroll_mode_enable(Evas_Object *obj)
+{
+   // called when autoscroll mode should be on - content area smaller than
+   // its min size
+   // 1. get focused object
+   // 2. if not in visible conformant area calculate delta needed to
+   //    get it in
+   // 3. store delta and call _autoscroll_move() which either asanimates
+   //    or jumps right there
+}
+
+static void
+_autoscroll_mode_disable(Evas_Object *obj)
+{
+   // called when autoscroll mode should be off - set delta to 0 and
+   // call _autoscroll_move()
+}
+*/
+
+static int 
+_prop_change(void *data, int type __UNUSED__, void *event) 
+{
+#ifdef HAVE_ELEMENTARY_X
+   Ecore_X_Event_Window_Property *ev;
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return 1;
+   ev = event;
+   if (ev->atom == ECORE_X_ATOM_E_ILLUME_ZONE) 
+     {
+        Ecore_X_Window zone;
+        int sh = -1;
+
+        zone = ecore_x_e_illume_zone_get(ev->win);
+        ecore_x_e_illume_indicator_geometry_get(zone, NULL, NULL, NULL, &sh);
+        if (sh < 0) sh = 0;
+        evas_object_size_hint_min_set(wd->shelf, -1, sh);
+        evas_object_size_hint_max_set(wd->shelf, -1, sh);
+        sh = -1;
+        ecore_x_e_illume_softkey_geometry_get(zone, NULL, NULL, NULL, &sh);
+        if (sh < 0) sh = 0;
+        evas_object_size_hint_min_set(wd->panel, -1, sh);
+        evas_object_size_hint_max_set(wd->panel, -1, sh);
+     }
+   else if (ev->atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY) 
+     {
+        Ecore_X_Window zone;
+        int sh = -1;
+
+        zone = ecore_x_e_illume_zone_get(ev->win);
+        ecore_x_e_illume_indicator_geometry_get(zone, NULL, NULL, NULL, &sh);
+        if (sh < 0) sh = 0;
+        evas_object_size_hint_min_set(wd->shelf, -1, sh);
+        evas_object_size_hint_max_set(wd->shelf, -1, sh);
+     }
+   else if (ev->atom == ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY) 
+     {
+        Ecore_X_Window zone;
+        int sh = -1;
+
+        zone = ecore_x_e_illume_zone_get(ev->win);
+        ecore_x_e_illume_softkey_geometry_get(zone, NULL, NULL, NULL, &sh);
+        if (sh < 0) sh = 0;
+        evas_object_size_hint_min_set(wd->panel, -1, sh);
+        evas_object_size_hint_max_set(wd->panel, -1, sh);
+     }
+   else if (ev->atom == ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY) 
+     {
+        Ecore_X_Window zone;
+        int ky = -1;
+
+        printf("Keyboard Geometry Changed\n");
+        zone = ecore_x_e_illume_zone_get(ev->win);
+        ecore_x_e_illume_keyboard_geometry_get(zone, NULL, &ky, NULL, NULL);
+        printf("\tGeom: %d\n", ky);
+     }
+#endif
+
+   return 1;
+}
+
+/**
+ * Add a new Conformant object
+ * 
+ * @param parent The parent object
+ * @return The new conformant object or NULL if it cannot be created
+ * 
+ * @ingroup Conformant
+ */
+EAPI Evas_Object *
+elm_conformant_add(Evas_Object *parent) 
+{
+   Evas_Object *obj;
+   Evas *evas;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+
+   evas = evas_object_evas_get(parent);
+
+   obj = elm_widget_add(evas);
+   ELM_SET_WIDTYPE(widtype, "conformant");
+   elm_widget_type_set(obj, "conformant");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   wd->base = edje_object_add(evas);
+   _elm_theme_object_set(obj, wd->base, "conformant", "base", "default");
+   elm_widget_resize_object_set(obj, wd->base);
+
+#ifdef HAVE_ELEMENTARY_X
+   Ecore_X_Window zone, xwin;
+   int sh = -1;
+
+   xwin = elm_win_xwindow_get(parent);
+   zone = ecore_x_e_illume_zone_get(xwin);
+
+   ecore_x_e_illume_indicator_geometry_get(zone, NULL, NULL, NULL, &sh);
+   if (sh < 0) sh = 0;
+   wd->shelf = evas_object_rectangle_add(evas);
+   evas_object_color_set(wd->shelf, 0, 0, 0, 0);
+   evas_object_size_hint_min_set(wd->shelf, -1, sh);
+   evas_object_size_hint_max_set(wd->shelf, -1, sh);
+   edje_object_part_swallow(wd->base, "elm.swallow.shelf", wd->shelf);
+
+   sh = -1;
+   ecore_x_e_illume_softkey_geometry_get(zone, NULL, NULL, NULL, &sh);
+   if (sh < 0) sh = 0;
+   wd->panel = evas_object_rectangle_add(evas);
+   evas_object_color_set(wd->panel, 0, 0, 0, 0);
+   evas_object_size_hint_min_set(wd->panel, -1, sh);
+   evas_object_size_hint_max_set(wd->panel, -1, sh);
+   edje_object_part_swallow(wd->base, "elm.swallow.panel", wd->panel);
+
+   wd->prop_hdl = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, 
+                                          _prop_change, obj);
+   // FIXME: get kbd region prop
+#endif
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Set the content of the conformant widget
+ * 
+ * @param obj The conformant object
+ * @param content The content that will be used inside this conformant object
+ * 
+ * @ingroup Conformant
+ */
+EAPI void 
+elm_conformant_content_set(Evas_Object *obj, Evas_Object *content) 
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if ((wd->content != content) && (wd->content))
+     elm_widget_sub_object_del(obj, wd->content);
+   wd->content = content;
+   if (content) 
+     {
+        elm_widget_sub_object_add(obj, content);
+        evas_object_event_callback_add(content,
+                                       EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                       _changed_size_hints, obj);
+        edje_object_part_swallow(wd->base, "elm.swallow.content", content);
+        _sizing_eval(obj);
+     }
+}
diff --git a/src/lib/elm_entry.c b/src/lib/elm_entry.c
new file mode 100644 (file)
index 0000000..fba911b
--- /dev/null
@@ -0,0 +1,2163 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Entry Entry
+ *
+ * An entry is a convenience widget which shows
+ * a box that the user can enter text into.  Unlike a
+ * @ref Scrolled_Entry widget, entries DO NOT scroll with user
+ * input.  Entry widgets are capable of expanding past the
+ * boundaries of the window, thus resizing the window to its
+ * own length.
+ * 
+ * You can also insert "items" in the entry with:
+ * 
+ * \<item size=16x16 vsize=full href=emoticon/haha\>\</item\>
+ * 
+ * for example. sizing can be set bu size=WxH, relsize=WxH or absize=WxH with
+ * vsize=ascent or vsize=full. the href=NAME sets the item name. Entry
+ * supports a list of emoticon names by default. These are:
+ * 
+ * emoticon/angry
+ * emoticon/angry-shout
+ * emoticon/crazy-laugh
+ * emoticon/evil-laugh
+ * emoticon/evil
+ * emoticon/goggle-smile
+ * emoticon/grumpy
+ * emoticon/grumpy-smile
+ * emoticon/guilty
+ * emoticon/guilty-smile
+ * emoticon/haha
+ * emoticon/half-smile
+ * emoticon/happy-panting
+ * emoticon/happy
+ * emoticon/indifferent
+ * emoticon/kiss
+ * emoticon/knowing-grin
+ * emoticon/laugh
+ * emoticon/little-bit-sorry
+ * emoticon/love-lots
+ * emoticon/love
+ * emoticon/minimal-smile
+ * emoticon/not-happy
+ * emoticon/not-impressed
+ * emoticon/omg
+ * emoticon/opensmile
+ * emoticon/smile
+ * emoticon/sorry
+ * emoticon/squint-laugh
+ * emoticon/surprised
+ * emoticon/suspicious
+ * emoticon/tongue-dangling
+ * emoticon/tongue-poke
+ * emoticon/uh
+ * emoticon/unhappy
+ * emoticon/very-sorry
+ * emoticon/what
+ * emoticon/wink
+ * emoticon/worried
+ * emoticon/wtf
+ *
+ * These are built-in currently, but you can add your own item provieer that
+ * can create inlined objects in the text and fill the space allocated to the
+ * item with a custom object of your own.
+ * 
+ * See the entry test for some more examples of use of this.
+ * 
+ * Signals that you can add callbacks for are:
+ * "changed" - The text within the entry was changed
+ * "activated" - The entry has received focus and the cursor
+ * "press" - The entry has been clicked
+ * "longpressed" - The entry has been clicked for a couple seconds
+ * "clicked" - The entry has been clicked
+ * "clicked,double" - The entry has been double clicked
+ * "focused" - The entry has received focus
+ * "unfocused" - The entry has lost focus
+ * "selection,paste" - A paste action has occurred
+ * "selection,copy" - A copy action has occurred
+ * "selection,cut" - A cut action has occurred
+ * "selection,start" - A selection has begun
+ * "selection,changed" - The selection has changed
+ * "selection,cleared" - The selection has been cleared
+ * "cursor,changed" - The cursor has changed
+ * "anchor,clicked" - The anchor has been clicked
+ */
+
+typedef struct _Mod_Api Mod_Api;
+
+typedef struct _Widget_Data Widget_Data;
+typedef struct _Elm_Entry_Context_Menu_Item Elm_Entry_Context_Menu_Item;
+typedef struct _Elm_Entry_Item_Provider Elm_Entry_Item_Provider;
+
+struct _Widget_Data
+{
+   Evas_Object *ent;
+   Evas_Object *hoversel;
+   Ecore_Job *deferred_recalc_job;
+   Ecore_Event_Handler *sel_notify_handler;
+   Ecore_Event_Handler *sel_clear_handler;
+   Ecore_Timer *longpress_timer;
+   const char *cut_sel;
+   const char *text;
+   Evas_Coord lastw;
+   Evas_Coord downx, downy;
+   Evas_Coord cx, cy, cw, ch;
+   Eina_List *items;
+   Eina_List *item_providers;
+   Mod_Api *api; // module api if supplied
+   Eina_Bool changed : 1;
+   Eina_Bool linewrap : 1;
+   Eina_Bool char_linewrap : 1;
+   Eina_Bool single_line : 1;
+   Eina_Bool password : 1;
+   Eina_Bool editable : 1;
+   Eina_Bool selection_asked : 1;
+   Eina_Bool have_selection : 1;
+   Eina_Bool selmode : 1;
+   Eina_Bool deferred_cur : 1;
+   Eina_Bool disabled : 1;
+   Eina_Bool context_menu : 1;
+};
+
+struct _Elm_Entry_Context_Menu_Item
+{
+   Evas_Object *obj;
+   const char *label;
+   const char *icon_file;
+   const char *icon_group;
+   Elm_Icon_Type icon_type;
+   Evas_Smart_Cb func;
+   void *data;
+};
+
+struct _Elm_Entry_Item_Provider
+{
+   Evas_Object *(*func) (void *data, Evas_Object *entry, const char *item);
+   void *data;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _disable_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _on_focus_hook(void *data, Evas_Object *obj);
+static void _resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static const char *_getbase(Evas_Object *obj);
+static void _signal_entry_changed(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_selection_start(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_selection_changed(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_selection_cleared(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_entry_paste_request(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_entry_copy_notify(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_entry_cut_notify(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_cursor_changed(void *data, Evas_Object *obj, const char *emission, const char *source);
+
+static const char SIG_CHANGED[] = "changed";
+static const char SIG_ACTIVATED[] = "activated";
+static const char SIG_PRESS[] = "press";
+static const char SIG_LONGPRESSED[] = "longpressed";
+static const char SIG_CLICKED[] = "clicked";
+static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
+static const char SIG_FOCUSED[] = "focused";
+static const char SIG_UNFOCUSED[] = "unfocused";
+static const char SIG_SELECTION_PASTE[] = "selection,paste";
+static const char SIG_SELECTION_COPY[] = "selection,copy";
+static const char SIG_SELECTION_CUT[] = "selection,cut";
+static const char SIG_SELECTION_START[] = "selection,start";
+static const char SIG_SELECTION_CHANGED[] = "selection,changed";
+static const char SIG_SELECTION_CLEARED[] = "selection,cleared";
+static const char SIG_CURSOR_CHANGED[] = "cursor,changed";
+static const char SIG_ANCHOR_CLICKED[] = "anchor,clicked";
+static const Evas_Smart_Cb_Description _signals[] = {
+  {SIG_CHANGED, ""},
+  {SIG_ACTIVATED, ""},
+  {SIG_PRESS, ""},
+  {SIG_LONGPRESSED, ""},
+  {SIG_CLICKED, ""},
+  {SIG_CLICKED_DOUBLE, ""},
+  {SIG_FOCUSED, ""},
+  {SIG_UNFOCUSED, ""},
+  {SIG_SELECTION_PASTE, ""},
+  {SIG_SELECTION_COPY, ""},
+  {SIG_SELECTION_CUT, ""},
+  {SIG_SELECTION_START, ""},
+  {SIG_SELECTION_CHANGED, ""},
+  {SIG_SELECTION_CLEARED, ""},
+  {SIG_CURSOR_CHANGED, ""},
+  {SIG_ANCHOR_CLICKED, ""},
+  {NULL, NULL}
+};
+
+static Eina_List *entries = NULL;
+
+struct _Mod_Api
+{
+   void (*obj_hook) (Evas_Object *obj);
+   void (*obj_unhook) (Evas_Object *obj);
+   void (*obj_longpress) (Evas_Object *obj);
+};
+
+static Mod_Api *
+_module(Evas_Object *obj __UNUSED__)
+{
+   static Elm_Module *m = NULL;
+   if (m) goto ok; // already found - just use
+   if (!(m = _elm_module_find_as("entry/api"))) return NULL;
+   // get module api
+   m->api = malloc(sizeof(Mod_Api));
+   if (!m->api) return NULL;
+   ((Mod_Api *)(m->api)      )->obj_hook = // called on creation
+     _elm_module_symbol_get(m, "obj_hook");
+   ((Mod_Api *)(m->api)      )->obj_unhook = // called on deletion
+     _elm_module_symbol_get(m, "obj_unhook");
+   ((Mod_Api *)(m->api)      )->obj_longpress = // called on long press menu
+     _elm_module_symbol_get(m, "obj_longpress");
+   ok: // ok - return api
+   return m->api;
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_Entry_Context_Menu_Item *it;
+   Elm_Entry_Item_Provider *ip;
+
+   if ((wd->api) && (wd->api->obj_unhook)) wd->api->obj_unhook(obj); // module - unhook
+
+   entries = eina_list_remove(entries, obj);
+#ifdef HAVE_ELEMENTARY_X
+   ecore_event_handler_del(wd->sel_notify_handler);
+   ecore_event_handler_del(wd->sel_clear_handler);
+#endif
+   if (wd->cut_sel) eina_stringshare_del(wd->cut_sel);
+   if (wd->text) eina_stringshare_del(wd->text);
+   if (wd->deferred_recalc_job) ecore_job_del(wd->deferred_recalc_job);
+   if (wd->longpress_timer) ecore_timer_del(wd->longpress_timer);
+   EINA_LIST_FREE(wd->items, it)
+     {
+        eina_stringshare_del(it->label);
+        eina_stringshare_del(it->icon_file);
+        eina_stringshare_del(it->icon_group);
+        free(it);
+     }
+   EINA_LIST_FREE(wd->item_providers, ip)
+     {
+        free(ip);
+     }
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   const char *t;
+
+   t = eina_stringshare_add(elm_entry_entry_get(obj));
+   _elm_theme_object_set(obj, wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
+   elm_entry_entry_set(obj, t);
+   eina_stringshare_del(t);
+   edje_object_scale_set(wd->ent, elm_widget_scale_get(obj) * _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+static void
+_disable_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (elm_widget_disabled_get(obj))
+     {
+       edje_object_signal_emit(wd->ent, "elm,state,disabled", "elm");
+       wd->disabled = EINA_TRUE;
+     }
+   else
+     {
+       edje_object_signal_emit(wd->ent, "elm,state,enabled", "elm");
+       wd->disabled = EINA_FALSE;
+     }
+}
+
+static void
+_elm_win_recalc_job(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Coord minw = -1, minh = -1, maxh = -1;
+   Evas_Coord resw, resh, minminw;
+   if (!wd) return;
+   wd->deferred_recalc_job = NULL;
+   evas_object_geometry_get(wd->ent, NULL, NULL, &resw, &resh);
+   resh = 0;
+   minminw = 0;
+   edje_object_size_min_restricted_calc(wd->ent, &minw, &minh, 0, 0);
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   minminw = minw;
+   edje_object_size_min_restricted_calc(wd->ent, &minw, &minh, resw, 0);
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   evas_object_size_hint_min_set(data, minminw, minh);
+   if (wd->single_line) maxh = minh;
+   evas_object_size_hint_max_set(data, -1, maxh);
+   if (wd->deferred_cur)
+     elm_widget_show_region_set(data, wd->cx, wd->cy, wd->cw, wd->ch);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   Evas_Coord resw, resh;
+   if (!wd) return;
+   if (wd->linewrap || wd->char_linewrap)
+     {
+       evas_object_geometry_get(wd->ent, NULL, NULL, &resw, &resh);
+       if ((resw == wd->lastw) && (!wd->changed)) return;
+       wd->changed = EINA_FALSE;
+       wd->lastw = resw;
+       if (wd->deferred_recalc_job) ecore_job_del(wd->deferred_recalc_job);
+       wd->deferred_recalc_job = ecore_job_add(_elm_win_recalc_job, obj);
+     }
+   else
+     {
+       evas_object_geometry_get(wd->ent, NULL, NULL, &resw, &resh);
+       edje_object_size_min_calc(wd->ent, &minw, &minh);
+        elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+       evas_object_size_hint_min_set(obj, minw, minh);
+        if (wd->single_line) maxh = minh;
+       evas_object_size_hint_max_set(obj, maxw, maxh);
+     }
+}
+
+static void
+_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *top = elm_widget_top_get(obj);
+   if (!wd) return;
+   if (!wd->editable) return;
+   if (elm_widget_focus_get(obj))
+     {
+       evas_object_focus_set(wd->ent, 1);
+       edje_object_signal_emit(wd->ent, "elm,action,focus", "elm");
+       if (top) elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_ON);
+       evas_object_smart_callback_call(obj, SIG_FOCUSED, NULL);
+     }
+   else
+     {
+       edje_object_signal_emit(wd->ent, "elm,action,unfocus", "elm");
+       evas_object_focus_set(wd->ent, 0);
+       if (top) elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_OFF);
+       evas_object_smart_callback_call(obj, SIG_UNFOCUSED, NULL);
+     }
+}
+
+static void
+_hoversel_position(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord cx, cy, cw, ch, x, y, mw, mh;
+   if (!wd) return;
+   evas_object_geometry_get(wd->ent, &x, &y, NULL, NULL);
+   edje_object_part_text_cursor_geometry_get(wd->ent, "elm.text",
+                                            &cx, &cy, &cw, &ch);
+   evas_object_size_hint_min_get(wd->hoversel, &mw, &mh);
+   if (cw < mw)
+     {
+       cx += (cw - mw) / 2;
+       cw = mw;
+     }
+   if (ch < mh)
+     {
+       cy += (ch - mh) / 2;
+       ch = mh;
+     }
+   evas_object_move(wd->hoversel, x + cx, y + cy);
+   evas_object_resize(wd->hoversel, cw, ch);
+}
+
+static void
+_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+
+   if (wd->hoversel) _hoversel_position(data);
+}
+
+static void
+_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (wd->linewrap || wd->char_linewrap)
+     {
+        _sizing_eval(data);
+     }
+   if (wd->hoversel) _hoversel_position(data);
+//   Evas_Coord ww, hh;
+//   evas_object_geometry_get(wd->ent, NULL, NULL, &ww, &hh);
+}
+
+static void
+_dismissed(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (wd->hoversel) evas_object_hide(wd->hoversel);
+   if (wd->selmode)
+     {
+        if (!wd->password)
+          edje_object_part_text_select_allow_set(wd->ent, "elm.text", 1);
+     }
+   elm_widget_scroll_freeze_pop(data);
+}
+
+static void
+_select(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   wd->selmode = EINA_TRUE;
+   edje_object_part_text_select_none(wd->ent, "elm.text");
+   if (!wd->password)
+     edje_object_part_text_select_allow_set(wd->ent, "elm.text", 1);
+   edje_object_signal_emit(wd->ent, "elm,state,select,on", "elm");
+   elm_widget_scroll_hold_push(data);
+}
+
+static void
+_paste(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   evas_object_smart_callback_call(data, SIG_SELECTION_PASTE, NULL);
+   if (wd->sel_notify_handler)
+     {
+#ifdef HAVE_ELEMENTARY_X
+       Evas_Object *top;
+
+       top = elm_widget_top_get(data);
+       if ((top) && (elm_win_xwindow_get(top)))
+         {
+            ecore_x_selection_primary_request
+              (elm_win_xwindow_get(top),
+               ECORE_X_SELECTION_TARGET_UTF8_STRING);
+            wd->selection_asked = EINA_TRUE;
+         }
+#endif
+     }
+}
+
+static void
+_store_selection(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   const char *sel = edje_object_part_text_selection_get(wd->ent, "elm.text");
+   if (!wd) return;
+   eina_stringshare_replace(&wd->cut_sel, sel);
+}
+
+static void
+_cut(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+
+   wd->selmode = EINA_FALSE;
+   edje_object_part_text_select_allow_set(wd->ent, "elm.text", 0);
+   edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
+   elm_widget_scroll_hold_pop(data);
+   _store_selection(data);
+   edje_object_part_text_insert(wd->ent, "elm.text", "");
+   edje_object_part_text_select_none(wd->ent, "elm.text");
+}
+
+static void
+_copy(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   wd->selmode = EINA_FALSE;
+   edje_object_part_text_select_allow_set(wd->ent, "elm.text", 0);
+   edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
+   elm_widget_scroll_hold_pop(data);
+   _store_selection(data);
+   edje_object_part_text_select_none(wd->ent, "elm.text");
+}
+
+static void
+_cancel(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   wd->selmode = EINA_FALSE;
+   edje_object_part_text_select_allow_set(wd->ent, "elm.text", 0);
+   edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
+   elm_widget_scroll_hold_pop(data);
+   edje_object_part_text_select_none(wd->ent, "elm.text");
+}
+
+static void
+_item_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Elm_Entry_Context_Menu_Item *it = data;
+   Evas_Object *obj2 = it->obj;
+   if (it->func) it->func(it->data, obj2, NULL);
+}
+
+static int
+_long_press(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Object *top;
+   const Eina_List *l;
+   const Elm_Entry_Context_Menu_Item *it;
+   if (!wd) return 0;
+   if ((wd->api) && (wd->api->obj_longpress))
+     {
+        wd->api->obj_longpress(data);
+     }
+   else if (wd->context_menu)
+     {
+        const char *context_menu_orientation;
+
+        if (wd->hoversel) evas_object_del(wd->hoversel);
+        else elm_widget_scroll_freeze_push(data);
+        wd->hoversel = elm_hoversel_add(data);
+        context_menu_orientation = edje_object_data_get
+          (wd->ent, "context_menu_orientation");
+        if ((context_menu_orientation) &&
+            (!strcmp(context_menu_orientation, "horizontal")))
+          elm_hoversel_horizontal_set(wd->hoversel, 1);
+        elm_object_style_set(wd->hoversel, "entry");
+        elm_widget_sub_object_add(data, wd->hoversel);
+        elm_hoversel_label_set(wd->hoversel, "Text");
+        top = elm_widget_top_get(data);
+        if (top) elm_hoversel_hover_parent_set(wd->hoversel, top);
+        evas_object_smart_callback_add(wd->hoversel, "dismissed", _dismissed, data);
+        if (!wd->selmode)
+          {
+             if (!wd->password)
+               elm_hoversel_item_add(wd->hoversel, "Select", NULL, ELM_ICON_NONE,
+                                     _select, data);
+             if (1) // need way to detect if someone has a selection
+               {
+                  if (wd->editable)
+                    elm_hoversel_item_add(wd->hoversel, "Paste", NULL, ELM_ICON_NONE,
+                                          _paste, data);
+               }
+          }
+        else
+          {
+             if (!wd->password)
+               {
+                  if (wd->have_selection)
+                    {
+                       elm_hoversel_item_add(wd->hoversel, "Copy", NULL, ELM_ICON_NONE,
+                                             _copy, data);
+                       if (wd->editable)
+                         elm_hoversel_item_add(wd->hoversel, "Cut", NULL, ELM_ICON_NONE,
+                                               _cut, data);
+                    }
+                  elm_hoversel_item_add(wd->hoversel, "Cancel", NULL, ELM_ICON_NONE,
+                                        _cancel, data);
+               }
+          }
+        EINA_LIST_FOREACH(wd->items, l, it)
+          {
+             elm_hoversel_item_add(wd->hoversel, it->label, it->icon_file,
+                                   it->icon_type, _item_clicked, it);
+          }
+        if (wd->hoversel)
+          {
+             _hoversel_position(data);
+             evas_object_show(wd->hoversel);
+             elm_hoversel_hover_begin(wd->hoversel);
+          }
+        edje_object_part_text_select_allow_set(wd->ent, "elm.text", 0);
+        edje_object_part_text_select_abort(wd->ent, "elm.text");
+     }
+   wd->longpress_timer = NULL;
+   evas_object_smart_callback_call(data, SIG_LONGPRESSED, NULL);
+   return 0;
+}
+
+static void
+_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Event_Mouse_Down *ev = event_info;
+   if (!wd) return;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
+   if (ev->button != 1) return;
+   //   if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
+   if (wd->longpress_timer) ecore_timer_del(wd->longpress_timer);
+   wd->longpress_timer = ecore_timer_add(1.0, _long_press, data);
+   wd->downx = ev->canvas.x;
+   wd->downy = ev->canvas.y;
+}
+
+static void
+_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Event_Mouse_Up *ev = event_info;
+   if (!wd) return;
+   if (ev->button != 1) return;
+   if (wd->longpress_timer)
+     {
+       ecore_timer_del(wd->longpress_timer);
+       wd->longpress_timer = NULL;
+     }
+}
+
+static void
+_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Event_Mouse_Move *ev = event_info;
+   if (!wd) return;
+   if (!wd->selmode)
+     {
+       if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
+         {
+            if (wd->longpress_timer)
+              {
+                 ecore_timer_del(wd->longpress_timer);
+                 wd->longpress_timer = NULL;
+              }
+         }
+       else if (wd->longpress_timer)
+         {
+            Evas_Coord dx, dy;
+
+            dx = wd->downx - ev->cur.canvas.x;
+            dx *= dx;
+            dy = wd->downy - ev->cur.canvas.y;
+            dy *= dy;
+            if ((dx + dy) >
+                ((_elm_config->finger_size / 2) *
+                 (_elm_config->finger_size / 2)))
+              {
+                 ecore_timer_del(wd->longpress_timer);
+                 wd->longpress_timer = NULL;
+              }
+         }
+     }
+   else if (wd->longpress_timer)
+     {
+       Evas_Coord dx, dy;
+
+       dx = wd->downx - ev->cur.canvas.x;
+       dx *= dx;
+       dy = wd->downy - ev->cur.canvas.y;
+       dy *= dy;
+       if ((dx + dy) >
+           ((_elm_config->finger_size / 2) *
+            (_elm_config->finger_size / 2)))
+         {
+            ecore_timer_del(wd->longpress_timer);
+            wd->longpress_timer = NULL;
+         }
+     }
+}
+
+static const char *
+_getbase(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return "base";
+   if (wd->editable)
+     {
+       if (wd->password) return "base-password";
+       else
+         {
+            if (wd->single_line) return "base-single";
+            else
+              {
+                 if (wd->linewrap) return "base";
+                  else if (wd->char_linewrap) return "base-charwrap";
+                 else  return "base-nowrap";
+              }
+         }
+     }
+   else
+     {
+       if (wd->password) return "base-password";
+       else
+         {
+            if (wd->single_line) return "base-single-noedit";
+            else
+              {
+                 if (wd->linewrap) return "base-noedit";
+                  else if (wd->char_linewrap) return "base-noedit-charwrap";
+                 else  return "base-nowrap-noedit";
+              }
+         }
+     }
+   return "base";
+}
+
+static char *
+_str_append(char *str, const char *txt, int *len, int *alloc)
+{
+   int txt_len = strlen(txt);
+
+   if (txt_len <= 0) return str;
+   if ((*len + txt_len) >= *alloc)
+     {
+       char *str2;
+       int alloc2;
+
+       alloc2 = *alloc + txt_len + 128;
+       str2 = realloc(str, alloc2);
+       if (!str2) return str;
+       *alloc = alloc2;
+       str = str2;
+     }
+   strcpy(str + *len, txt);
+   *len += txt_len;
+   return str;
+}
+
+static char *
+_mkup_to_text(const char *mkup)
+{
+   char *str = NULL;
+   int str_len = 0, str_alloc = 0;
+   char *s, *p;
+   char *tag_start, *tag_end, *esc_start, *esc_end, *ts;
+
+   if (!mkup) return NULL;
+   tag_start = tag_end = esc_start = esc_end = NULL;
+   p = (char *)mkup;
+   s = p;
+   for (;;)
+     {
+       if ((*p == 0) ||
+           (tag_end) || (esc_end) ||
+           (tag_start) || (esc_start))
+         {
+            if (tag_end)
+              {
+                 char *ttag;
+
+                 ttag = malloc(tag_end - tag_start);
+                 if (ttag)
+                   {
+                      strncpy(ttag, tag_start + 1, tag_end - tag_start - 1);
+                      ttag[tag_end - tag_start - 1] = 0;
+                      if (!strcmp(ttag, "br"))
+                        str = _str_append(str, "\n", &str_len, &str_alloc);
+                      else if (!strcmp(ttag, "\n"))
+                        str = _str_append(str, "\n", &str_len, &str_alloc);
+                      else if (!strcmp(ttag, "\\n"))
+                        str = _str_append(str, "\n", &str_len, &str_alloc);
+                      else if (!strcmp(ttag, "\t"))
+                        str = _str_append(str, "\t", &str_len, &str_alloc);
+                      else if (!strcmp(ttag, "\\t"))
+                        str = _str_append(str, "\t", &str_len, &str_alloc);
+                      free(ttag);
+                   }
+                 tag_start = tag_end = NULL;
+              }
+            else if (esc_end)
+              {
+                 ts = malloc(esc_end - esc_start + 1);
+                 if (ts)
+                   {
+                      const char *esc;
+                      strncpy(ts, esc_start, esc_end - esc_start);
+                      ts[esc_end - esc_start] = 0;
+                      esc = evas_textblock_escape_string_get(ts);
+                      if (esc)
+                        str = _str_append(str, esc, &str_len, &str_alloc);
+                      free(ts);
+                   }
+                 esc_start = esc_end = NULL;
+              }
+            else if (*p == 0)
+              {
+                 ts = malloc(p - s + 1);
+                 if (ts)
+                   {
+                      strncpy(ts, s, p - s);
+                      ts[p - s] = 0;
+                      str = _str_append(str, ts, &str_len, &str_alloc);
+                      free(ts);
+                   }
+                  break;
+              }
+         }
+       if (*p == '<')
+         {
+            if (!esc_start)
+              {
+                 tag_start = p;
+                 tag_end = NULL;
+                 ts = malloc(p - s + 1);
+                 if (ts)
+                   {
+                      strncpy(ts, s, p - s);
+                      ts[p - s] = 0;
+                      str = _str_append(str, ts, &str_len, &str_alloc);
+                      free(ts);
+                   }
+                 s = NULL;
+              }
+         }
+       else if (*p == '>')
+         {
+            if (tag_start)
+              {
+                 tag_end = p;
+                 s = p + 1;
+              }
+         }
+       else if (*p == '&')
+         {
+            if (!tag_start)
+              {
+                 esc_start = p;
+                 esc_end = NULL;
+                 ts = malloc(p - s + 1);
+                 if (ts)
+                   {
+                      strncpy(ts, s, p - s);
+                      ts[p - s] = 0;
+                      str = _str_append(str, ts, &str_len, &str_alloc);
+                      free(ts);
+                   }
+                 s = NULL;
+              }
+         }
+       else if (*p == ';')
+         {
+            if (esc_start)
+              {
+                 esc_end = p;
+                 s = p + 1;
+              }
+         }
+       p++;
+     }
+   return str;
+}
+
+static char *
+_text_to_mkup(const char *text)
+{
+   char *str = NULL;
+   int str_len = 0, str_alloc = 0;
+   int ch, pos = 0, pos2 = 0;
+
+   if (!text) return NULL;
+   for (;;)
+     {
+       pos = pos2;
+        pos2 = evas_string_char_next_get((char *)(text), pos2, &ch);
+        if ((ch <= 0) || (pos2 <= 0)) break;
+       if (ch == '\n')
+          str = _str_append(str, "<br>", &str_len, &str_alloc);
+       else if (ch == '\t')
+          str = _str_append(str, "<\t>", &str_len, &str_alloc);
+       else if (ch == '<')
+          str = _str_append(str, "&lt;", &str_len, &str_alloc);
+       else if (ch == '>')
+          str = _str_append(str, "&gt;", &str_len, &str_alloc);
+       else if (ch == '&')
+          str = _str_append(str, "&amp;", &str_len, &str_alloc);
+       else
+         {
+            char tstr[16];
+
+            strncpy(tstr, text + pos, pos2 - pos);
+            tstr[pos2 - pos] = 0;
+            str = _str_append(str, tstr, &str_len, &str_alloc);
+         }
+     }
+   return str;
+}
+
+static void
+_signal_entry_changed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   wd->changed = EINA_TRUE;
+   _sizing_eval(data);
+   if (wd->text) eina_stringshare_del(wd->text);
+   wd->text = NULL;
+   evas_object_smart_callback_call(data, SIG_CHANGED, NULL);
+}
+
+static void
+_signal_selection_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   const Eina_List *l;
+   Evas_Object *entry;
+   if (!wd) return;
+   EINA_LIST_FOREACH(entries, l, entry)
+     {
+       if (entry != data) elm_entry_select_none(entry);
+     }
+   wd->have_selection = EINA_TRUE;
+   evas_object_smart_callback_call(data, SIG_SELECTION_START, NULL);
+   if (wd->sel_notify_handler)
+     {
+       char *txt = _mkup_to_text(elm_entry_selection_get(data));
+
+       if (txt)
+         {
+#ifdef HAVE_ELEMENTARY_X
+            Evas_Object *top;
+
+            top = elm_widget_top_get(data);
+            if ((top) && (elm_win_xwindow_get(top)))
+              ecore_x_selection_primary_set(elm_win_xwindow_get(top), txt,
+                                             strlen(txt));
+#endif
+            free(txt);
+         }
+     }
+}
+
+static void
+_signal_selection_changed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   wd->have_selection = EINA_TRUE;
+   evas_object_smart_callback_call(data, SIG_SELECTION_CHANGED, NULL);
+   if (wd->sel_notify_handler)
+     {
+       char *txt = _mkup_to_text(elm_entry_selection_get(data));
+
+       if (txt)
+         {
+#ifdef HAVE_ELEMENTARY_X
+            Evas_Object *top;
+
+            top = elm_widget_top_get(data);
+            if ((top) && (elm_win_xwindow_get(top)))
+              ecore_x_selection_primary_set(elm_win_xwindow_get(top), txt,
+                                             strlen(txt));
+#endif
+            free(txt);
+         }
+     }
+}
+
+static void
+_signal_selection_cleared(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (!wd->have_selection) return;
+   wd->have_selection = EINA_FALSE;
+   evas_object_smart_callback_call(data, SIG_SELECTION_CLEARED, NULL);
+   if (wd->sel_notify_handler)
+     {
+       if (wd->cut_sel)
+         {
+#ifdef HAVE_ELEMENTARY_X
+            Evas_Object *top;
+
+            top = elm_widget_top_get(data);
+            if ((top) && (elm_win_xwindow_get(top)))
+              {
+                 char *t;
+
+                 t = _mkup_to_text(wd->cut_sel);
+                 if (t)
+                   {
+                      ecore_x_selection_primary_set(elm_win_xwindow_get(top),
+                                                     t, strlen(t));
+                      free(t);
+                   }
+              }
+#endif
+            eina_stringshare_del(wd->cut_sel);
+            wd->cut_sel = NULL;
+         }
+       else
+         {
+#ifdef HAVE_ELEMENTARY_X
+            Evas_Object *top;
+
+            top = elm_widget_top_get(data);
+            if ((top) && (elm_win_xwindow_get(top)))
+              ecore_x_selection_primary_clear();
+#endif
+         }
+     }
+}
+
+static void
+_signal_entry_paste_request(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   evas_object_smart_callback_call(data, SIG_SELECTION_PASTE, NULL);
+   if (wd->sel_notify_handler)
+     {
+#ifdef HAVE_ELEMENTARY_X
+       Evas_Object *top;
+
+       top = elm_widget_top_get(data);
+       if ((top) && (elm_win_xwindow_get(top)))
+         {
+            ecore_x_selection_primary_request(elm_win_xwindow_get(top),
+                                               ECORE_X_SELECTION_TARGET_UTF8_STRING);
+            wd->selection_asked = EINA_TRUE;
+         }
+#endif
+     }
+}
+
+static void
+_signal_entry_copy_notify(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   evas_object_smart_callback_call(data, SIG_SELECTION_COPY, NULL);
+}
+
+static void
+_signal_entry_cut_notify(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   char *txt;
+   if (!wd) return;
+   evas_object_smart_callback_call(data, SIG_SELECTION_CUT, NULL);
+   txt = _mkup_to_text(elm_entry_selection_get(data));
+   eina_stringshare_replace(&wd->cut_sel, txt);
+   if (txt) free(txt);
+   edje_object_part_text_insert(wd->ent, "elm.text", "");
+   wd->changed = EINA_TRUE;
+   _sizing_eval(data);
+}
+
+static void
+_signal_cursor_changed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Coord cx, cy, cw, ch;
+   if (!wd) return;
+   evas_object_smart_callback_call(data, SIG_CURSOR_CHANGED, NULL);
+   edje_object_part_text_cursor_geometry_get(wd->ent, "elm.text",
+                                             &cx, &cy, &cw, &ch);
+   if (!wd->deferred_recalc_job)
+     elm_widget_show_region_set(data, cx, cy, cw, ch);
+   else
+     {
+       wd->deferred_cur = EINA_TRUE;
+       wd->cx = cx;
+       wd->cy = cy;
+       wd->cw = cw;
+       wd->ch = ch;
+     }
+}
+
+static void
+_signal_anchor_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+}
+
+static void
+_signal_anchor_up(void *data, Evas_Object *obj __UNUSED__, const char *emission, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Elm_Entry_Anchor_Info ei;
+   char *buf2, *p, *p2, *n;
+   if (!wd) return;
+   p = strrchr(emission, ',');
+   if (p)
+     {
+       const Eina_List *geoms;
+
+       n = p + 1;
+       p2 = p -1;
+       while (p2 >= emission)
+         {
+            if (*p2 == ',') break;
+            p2--;
+         }
+       p2++;
+       buf2 = alloca(5 + p - p2);
+       strncpy(buf2, p2, p - p2);
+       buf2[p - p2] = 0;
+       ei.name = n;
+       ei.button = atoi(buf2);
+       ei.x = ei.y = ei.w = ei.h = 0;
+       geoms =
+          edje_object_part_text_anchor_geometry_get(wd->ent, "elm.text", ei.name);
+       if (geoms)
+         {
+            Evas_Textblock_Rectangle *r;
+            const Eina_List *l;
+            Evas_Coord px, py, x, y;
+
+            evas_object_geometry_get(wd->ent, &x, &y, NULL, NULL);
+            evas_pointer_output_xy_get(evas_object_evas_get(wd->ent), &px, &py);
+            EINA_LIST_FOREACH(geoms, l, r)
+              {
+                 if (((r->x + x) <= px) && ((r->y + y) <= py) &&
+                     ((r->x + x + r->w) > px) && ((r->y + y + r->h) > py))
+                   {
+                      ei.x = r->x + x;
+                      ei.y = r->y + y;
+                      ei.w = r->w;
+                      ei.h = r->h;
+                      break;
+                   }
+              }
+         }
+       if (!wd->disabled)
+         evas_object_smart_callback_call(data, SIG_ANCHOR_CLICKED, &ei);
+     }
+}
+
+static void
+_signal_anchor_move(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+}
+
+static void
+_signal_anchor_in(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+}
+
+static void
+_signal_anchor_out(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+}
+
+static void
+_signal_key_enter(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   evas_object_smart_callback_call(data, SIG_ACTIVATED, NULL);
+}
+
+static void
+_signal_mouse_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   evas_object_smart_callback_call(data, SIG_PRESS, NULL);
+}
+
+static void
+_signal_mouse_up(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
+}
+
+static void
+_signal_mouse_double(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   evas_object_smart_callback_call(data, SIG_CLICKED_DOUBLE, NULL);
+}
+
+#ifdef HAVE_ELEMENTARY_X
+static int
+_event_selection_notify(void *data, int type __UNUSED__, void *event)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Ecore_X_Event_Selection_Notify *ev = event;
+   if (!wd) return 1;
+   if (!wd->selection_asked) return 1;
+   if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) ||
+       (ev->selection == ECORE_X_SELECTION_PRIMARY))
+     {
+       Ecore_X_Selection_Data_Text *text_data;
+
+       text_data = ev->data;
+       if (text_data->data.content == ECORE_X_SELECTION_CONTENT_TEXT)
+         {
+            if (text_data->text)
+              {
+                 char *txt = _text_to_mkup(text_data->text);
+
+                 if (txt)
+                   {
+                      elm_entry_entry_insert(data, txt);
+                      free(txt);
+                   }
+              }
+         }
+       wd->selection_asked = EINA_FALSE;
+     }
+   return 1;
+}
+
+static int
+_event_selection_clear(void *data, int type __UNUSED__, void *event)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Ecore_X_Event_Selection_Clear *ev = event;
+   if (!wd) return 1;
+   if (!wd->have_selection) return 1;
+   if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) ||
+       (ev->selection == ECORE_X_SELECTION_PRIMARY))
+     {
+       elm_entry_select_none(data);
+     }
+   return 1;
+}
+#endif
+
+static Evas_Object *
+_get_item(void *data, Evas_Object *edje, const char *part, const char *item)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Object *o;
+   Eina_List *l;
+   Elm_Entry_Item_Provider *ip;
+   int ok = 0;
+
+   EINA_LIST_FOREACH(wd->item_providers, l, ip)
+     {
+        o = ip->func(ip->data, data, item);
+        if (o) return o;
+     }
+   o = edje_object_add(evas_object_evas_get(data));
+   if (!strncmp(item, "emoticon/", 9))
+     ok = _elm_theme_object_set(data, o, "entry", item, elm_widget_style_get(data));
+   if (!ok)
+     _elm_theme_object_set(data, o, "entry/emoticon", "wtf", elm_widget_style_get(data));
+   return o;
+}
+
+/**
+ * This adds an entry to @p parent object.
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Entry
+ */
+EAPI Evas_Object *
+elm_entry_add(Evas_Object *parent)
+{
+   Evas_Object *obj, *top;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "entry");
+   elm_widget_type_set(obj, "entry");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_disable_hook_set(obj, _disable_hook);
+   elm_widget_can_focus_set(obj, 1);
+
+   wd->linewrap     = EINA_TRUE;
+   wd->char_linewrap= EINA_FALSE;
+   wd->editable     = EINA_TRUE;
+   wd->disabled     = EINA_FALSE;
+   wd->context_menu = EINA_TRUE;
+
+   wd->ent = edje_object_add(e);
+   edje_object_item_provider_set(wd->ent, _get_item, obj);
+   evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOVE, _move, obj);
+   evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_RESIZE, _resize, obj);
+   evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOUSE_DOWN,
+                                  _mouse_down, obj);
+   evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOUSE_UP,
+                                  _mouse_up, obj);
+   evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOUSE_MOVE,
+                                  _mouse_move, obj);
+
+   _elm_theme_object_set(obj, wd->ent, "entry", "base", "default");
+   edje_object_signal_callback_add(wd->ent, "entry,changed", "elm.text",
+                                   _signal_entry_changed, obj);
+   edje_object_signal_callback_add(wd->ent, "selection,start", "elm.text",
+                                   _signal_selection_start, obj);
+   edje_object_signal_callback_add(wd->ent, "selection,changed", "elm.text",
+                                   _signal_selection_changed, obj);
+   edje_object_signal_callback_add(wd->ent, "selection,cleared", "elm.text",
+                                   _signal_selection_cleared, obj);
+   edje_object_signal_callback_add(wd->ent, "entry,paste,request", "elm.text",
+                                   _signal_entry_paste_request, obj);
+   edje_object_signal_callback_add(wd->ent, "entry,copy,notify", "elm.text",
+                                   _signal_entry_copy_notify, obj);
+   edje_object_signal_callback_add(wd->ent, "entry,cut,notify", "elm.text",
+                                   _signal_entry_cut_notify, obj);
+   edje_object_signal_callback_add(wd->ent, "cursor,changed", "elm.text",
+                                   _signal_cursor_changed, obj);
+   edje_object_signal_callback_add(wd->ent, "anchor,mouse,down,*", "elm.text",
+                                   _signal_anchor_down, obj);
+   edje_object_signal_callback_add(wd->ent, "anchor,mouse,up,*", "elm.text",
+                                   _signal_anchor_up, obj);
+   edje_object_signal_callback_add(wd->ent, "anchor,mouse,move,*", "elm.text",
+                                   _signal_anchor_move, obj);
+   edje_object_signal_callback_add(wd->ent, "anchor,mouse,in,*", "elm.text",
+                                   _signal_anchor_in, obj);
+   edje_object_signal_callback_add(wd->ent, "anchor,mouse,out,*", "elm.text",
+                                   _signal_anchor_out, obj);
+   edje_object_signal_callback_add(wd->ent, "entry,key,enter", "elm.text",
+                                   _signal_key_enter, obj);
+   edje_object_signal_callback_add(wd->ent, "mouse,down,1", "elm.text",
+                                   _signal_mouse_down, obj);
+   edje_object_signal_callback_add(wd->ent, "mouse,up,1", "elm.text",
+                                   _signal_mouse_up, obj);
+   edje_object_signal_callback_add(wd->ent, "mouse,down,1,double", "elm.text",
+                                   _signal_mouse_double, obj);
+   edje_object_part_text_set(wd->ent, "elm.text", "");
+   elm_widget_resize_object_set(obj, wd->ent);
+   _sizing_eval(obj);
+
+#ifdef HAVE_ELEMENTARY_X
+   top = elm_widget_top_get(obj);
+   if ((top) && (elm_win_xwindow_get(top)))
+     {
+       wd->sel_notify_handler =
+         ecore_event_handler_add(ECORE_X_EVENT_SELECTION_NOTIFY,
+                                 _event_selection_notify, obj);
+       wd->sel_clear_handler =
+         ecore_event_handler_add(ECORE_X_EVENT_SELECTION_CLEAR,
+                                 _event_selection_clear, obj);
+     }
+#endif
+
+   entries = eina_list_prepend(entries, obj);
+
+   // module - find module for entry
+   wd->api = _module(obj);
+   // if found - hook in
+   if ((wd->api) && (wd->api->obj_hook)) wd->api->obj_hook(obj);
+
+   // TODO: convert Elementary to subclassing of Evas_Smart_Class
+   // TODO: and save some bytes, making descriptions per-class and not instance!
+   evas_object_smart_callbacks_descriptions_set(obj, _signals);
+   return obj;
+}
+
+
+/**
+ * This sets the entry object not to line wrap.  All input will
+ * be on a single line, and the entry box will extend with user input.
+ *
+ * @param obj The entry object
+ * @param single_line If true, the text in the entry
+ * will be on a single line.
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_single_line_set(Evas_Object *obj, Eina_Bool single_line)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   const char *t;
+   if (!wd) return;
+   if (wd->single_line == single_line) return;
+   wd->single_line = single_line;
+   wd->linewrap = EINA_FALSE;
+   wd->char_linewrap = EINA_FALSE;
+   t = eina_stringshare_add(elm_entry_entry_get(obj));
+   _elm_theme_object_set(obj, wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
+   elm_entry_entry_set(obj, t);
+   eina_stringshare_del(t);
+   _sizing_eval(obj);
+}
+
+/**
+ * This returns true if the entry has been set to single line mode.
+ * See also elm_entry_single_line_set().
+ *
+ * @param obj The entry object
+ * @return single_line If true, the text in the entry is set to display
+ * on a single line.
+ *
+ * @ingroup Entry
+ */
+EAPI Eina_Bool
+elm_entry_single_line_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->single_line;
+}
+
+/**
+ * This sets the entry object to password mode.  All text entered
+ * and/or displayed within the widget will be replaced with asterisks (*).
+ *
+ * @param obj The entry object
+ * @param password If true, password mode is enabled.
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_password_set(Evas_Object *obj, Eina_Bool password)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   const char *t;
+   if (!wd) return;
+   if (wd->password == password) return;
+   wd->password = password;
+   wd->single_line = EINA_TRUE;
+   wd->linewrap = EINA_FALSE;
+   wd->char_linewrap = EINA_FALSE;
+   t = eina_stringshare_add(elm_entry_entry_get(obj));
+   _elm_theme_object_set(obj, wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
+   elm_entry_entry_set(obj, t);
+   eina_stringshare_del(t);
+   _sizing_eval(obj);
+}
+
+
+/**
+ * This returns whether password mode is enabled.
+ * See also elm_entry_password_set().
+ *
+ * @param obj The entry object
+ * @return If true, the entry is set to display all characters
+ * as asterisks (*).
+ *
+ * @ingroup Entry
+ */
+EAPI Eina_Bool
+elm_entry_password_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->password;
+}
+
+/**
+ * This sets the text displayed within the entry to @p entry.
+ *
+ * @param obj The entry object
+ * @param entry The text to be displayed
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_entry_set(Evas_Object *obj, const char *entry)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (!entry) entry = "";
+   edje_object_part_text_set(wd->ent, "elm.text", entry);
+   if (wd->text) eina_stringshare_del(wd->text);
+   wd->text = NULL;
+   wd->changed = EINA_TRUE;
+   _sizing_eval(obj);
+}
+
+/**
+ * This returns the text currently shown in object @p entry.
+ * See also elm_entry_entry_set().
+ *
+ * @param obj The entry object
+ * @return The currently displayed text or NULL on failure
+ *
+ * @ingroup Entry
+ */
+EAPI const char *
+elm_entry_entry_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   const char *text;
+   if (!wd) return NULL;
+   if (wd->text) return wd->text;
+   text = edje_object_part_text_get(wd->ent, "elm.text");
+   if (!text)
+     {
+       ERR("text=NULL for edje %p, part 'elm.text'", wd->ent);
+       return NULL;
+     }
+   eina_stringshare_replace(&wd->text, text);
+   return wd->text;
+}
+
+/**
+ * This returns all selected text within the entry.
+ *
+ * @param obj The entry object
+ * @return The selected text within the entry or NULL on failure
+ *
+ * @ingroup Entry
+ */
+EAPI const char *
+elm_entry_selection_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return edje_object_part_text_selection_get(wd->ent, "elm.text");
+}
+
+/**
+ * This inserts text in @p entry at the beginning of the entry
+ * object.
+ *
+ * @param obj The entry object
+ * @param entry The text to insert
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_entry_insert(Evas_Object *obj, const char *entry)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   edje_object_part_text_insert(wd->ent, "elm.text", entry);
+   wd->changed = EINA_TRUE;
+   _sizing_eval(obj);
+}
+
+/**
+ * This enables word line wrapping in the entry object.  It is the opposite
+ * of elm_entry_single_line_set().  Additionally, setting this disables
+ * character line wrapping.
+ * See also elm_entry_line_char_wrap_set().
+ *
+ * @param obj The entry object
+ * @param wrap If true, the entry will be wrapped once it reaches the end
+ * of the object. Wrapping will occur at the end of the word before the end of the
+ * object.
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_line_wrap_set(Evas_Object *obj, Eina_Bool wrap)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   const char *t;
+   if (!wd) return;
+   if (wd->linewrap == wrap) return;
+   wd->linewrap = wrap;
+   if(wd->linewrap)
+       wd->char_linewrap = EINA_FALSE;
+   t = eina_stringshare_add(elm_entry_entry_get(obj));
+   _elm_theme_object_set(obj, wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
+   elm_entry_entry_set(obj, t);
+   eina_stringshare_del(t);
+   _sizing_eval(obj);
+}
+
+/**
+ * This enables character line wrapping in the entry object.  It is the opposite
+ * of elm_entry_single_line_set().  Additionally, setting this disables
+ * word line wrapping.
+ * See also elm_entry_line_wrap_set().
+ *
+ * @param obj The entry object
+ * @param wrap If true, the entry will be wrapped once it reaches the end
+ * of the object. Wrapping will occur immediately upon reaching the end of the object.
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_line_char_wrap_set(Evas_Object *obj, Eina_Bool wrap)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   const char *t;
+   if (!wd) return;
+   if (wd->char_linewrap == wrap) return;
+   wd->char_linewrap = wrap;
+   if(wd->char_linewrap)
+       wd->linewrap = EINA_FALSE;
+   t = eina_stringshare_add(elm_entry_entry_get(obj));
+   _elm_theme_object_set(obj, wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
+   elm_entry_entry_set(obj, t);
+   eina_stringshare_del(t);
+   _sizing_eval(obj);
+}
+
+/**
+ * This sets the editable attribute of the entry.
+ *
+ * @param obj The entry object
+ * @param editable If true, the entry will be editable by the user.
+ * If false, it will be set to the disabled state.
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_editable_set(Evas_Object *obj, Eina_Bool editable)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   const char *t;
+   if (!wd) return;
+   if (wd->editable == editable) return;
+   wd->editable = editable;
+   t = eina_stringshare_add(elm_entry_entry_get(obj));
+   _elm_theme_object_set(obj, wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
+   elm_entry_entry_set(obj, t);
+   eina_stringshare_del(t);
+   _sizing_eval(obj);
+}
+
+/**
+ * This gets the editable attribute of the entry.
+ * See also elm_entry_editable_set().
+ *
+ * @param obj The entry object
+ * @return If true, the entry is editable by the user.
+ * If false, it is not editable by the user
+ *
+ * @ingroup Entry
+ */
+EAPI Eina_Bool
+elm_entry_editable_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->editable;
+}
+
+/**
+ * This drops any existing text selection within the entry.
+ *
+ * @param obj The entry object
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_select_none(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->selmode)
+     {
+       wd->selmode = EINA_FALSE;
+       edje_object_part_text_select_allow_set(wd->ent, "elm.text", 0);
+       edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
+     }
+   wd->have_selection = EINA_FALSE;
+   edje_object_part_text_select_none(wd->ent, "elm.text");
+}
+
+/**
+ * This selects all text within the entry.
+ *
+ * @param obj The entry object
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_select_all(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->selmode)
+     {
+       wd->selmode = EINA_FALSE;
+       edje_object_part_text_select_allow_set(wd->ent, "elm.text", 0);
+       edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
+     }
+   wd->have_selection = EINA_TRUE;
+   edje_object_part_text_select_all(wd->ent, "elm.text");
+}
+
+/**
+ * This moves the cursor one place to the right within the entry.
+ *
+ * @param obj The entry object
+ * @return EINA_TRUE upon success, EINA_FALSE upon failure
+ *
+ * @ingroup Entry
+ */
+EAPI Eina_Bool
+elm_entry_cursor_next(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return edje_object_part_text_cursor_next(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
+}
+
+/**
+ * This moves the cursor one place to the left within the entry.
+ *
+ * @param obj The entry object
+ * @return EINA_TRUE upon success, EINA_FALSE upon failure
+ *
+ * @ingroup Entry
+ */
+EAPI Eina_Bool
+elm_entry_cursor_prev(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return edje_object_part_text_cursor_prev(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
+}
+
+/**
+ * This moves the cursor one line up within the entry.
+ *
+ * @param obj The entry object
+ * @return EINA_TRUE upon success, EINA_FALSE upon failure
+ *
+ * @ingroup Entry
+ */
+EAPI Eina_Bool
+elm_entry_cursor_up(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return edje_object_part_text_cursor_up(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
+}
+
+/**
+ * This moves the cursor one line down within the entry.
+ *
+ * @param obj The entry object
+ * @return EINA_TRUE upon success, EINA_FALSE upon failure
+ *
+ * @ingroup Entry
+ */
+EAPI Eina_Bool
+elm_entry_cursor_down(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return edje_object_part_text_cursor_down(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
+}
+
+/**
+ * This moves the cursor to the beginning of the entry.
+ *
+ * @param obj The entry object
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_cursor_begin_set(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   edje_object_part_text_cursor_begin_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
+}
+
+/**
+ * This moves the cursor to the end of the entry.
+ *
+ * @param obj The entry object
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_cursor_end_set(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   edje_object_part_text_cursor_end_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
+}
+
+/**
+ * This moves the cursor to the beginning of the current line.
+ *
+ * @param obj The entry object
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_cursor_line_begin_set(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   edje_object_part_text_cursor_line_begin_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
+}
+
+/**
+ * This moves the cursor to the end of the current line.
+ *
+ * @param obj The entry object
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_cursor_line_end_set(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   edje_object_part_text_cursor_line_end_set(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
+}
+
+/**
+ * This begins a selection within the entry as though
+ * the user were holding down the mouse button to make a selection.
+ *
+ * @param obj The entry object
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_cursor_selection_begin(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   edje_object_part_text_select_begin(wd->ent, "elm.text");
+}
+
+/**
+ * This ends a selection within the entry as though
+ * the user had just released the mouse button while making a selection.
+ *
+ * @param obj The entry object
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_cursor_selection_end(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   edje_object_part_text_select_extend(wd->ent, "elm.text");
+}
+
+/**
+ * TODO: fill this in
+ *
+ * @param obj The entry object
+ * @return TODO: fill this in
+ *
+ * @ingroup Entry
+ */
+EAPI Eina_Bool
+elm_entry_cursor_is_format_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return edje_object_part_text_cursor_is_format_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
+}
+
+/**
+ * This returns whether the cursor is visible.
+ *
+ * @param obj The entry object
+ * @return If true, the cursor is visible.
+ *
+ * @ingroup Entry
+ */
+EAPI Eina_Bool
+elm_entry_cursor_is_visible_format_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return edje_object_part_text_cursor_is_visible_format_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
+}
+
+/**
+ * TODO: fill this in
+ *
+ * @param obj The entry object
+ * @return TODO: fill this in
+ *
+ * @ingroup Entry
+ */
+EAPI const char *
+elm_entry_cursor_content_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return edje_object_part_text_cursor_content_get(wd->ent, "elm.text", EDJE_CURSOR_MAIN);
+}
+
+/**
+ * This executes a "cut" action on the selected text in the entry.
+ *
+ * @param obj The entry object
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_selection_cut(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _cut(obj, NULL, NULL);
+}
+
+/**
+ * This executes a "copy" action on the selected text in the entry.
+ *
+ * @param obj The entry object
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_selection_copy(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _copy(obj, NULL, NULL);
+}
+
+/**
+ * This executes a "paste" action in the entry.
+ *
+ * @param obj The entry object
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_selection_paste(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _paste(obj, NULL, NULL);
+}
+
+/**
+ * This clears and frees the items in a entry's contextual (right click) menu.
+ *
+ * @param obj The entry object
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_context_menu_clear(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_Entry_Context_Menu_Item *it;
+   if (!wd) return;
+   EINA_LIST_FREE(wd->items, it)
+     {
+        eina_stringshare_del(it->label);
+        eina_stringshare_del(it->icon_file);
+        eina_stringshare_del(it->icon_group);
+        free(it);
+     }
+}
+
+/**
+ * This adds an item to the entry's contextual menu.
+ *
+ * @param obj The entry object
+ * @param label The item's text label
+ * @param icon_file The item's icon file
+ * @param icon_type The item's icon type
+ * @param func The callback to execute when the item is clicked
+ * @param data The data to associate with the item for related functions
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_context_menu_item_add(Evas_Object *obj, const char *label, const char *icon_file, Elm_Icon_Type icon_type, Evas_Smart_Cb func, const void *data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_Entry_Context_Menu_Item *it;
+   if (!wd) return;
+   it = calloc(1, sizeof(Elm_Entry_Context_Menu_Item));
+   if (!it) return;
+   wd->items = eina_list_append(wd->items, it);
+   it->obj = obj;
+   it->label = eina_stringshare_add(label);
+   it->icon_file = eina_stringshare_add(icon_file);
+   it->icon_type = icon_type;
+   it->func = func;
+   it->data = (void *)data;
+}
+
+/**
+ * This disables the entry's contextual (right click) menu.
+ *
+ * @param obj The entry object
+ * @param disabled If true, the menu is disabled
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_context_menu_disabled_set(Evas_Object *obj, Eina_Bool disabled)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->context_menu == !disabled) return;
+   wd->context_menu = !disabled;
+}
+
+/**
+ * This returns whether the entry's contextual (right click) menu is disabled.
+ *
+ * @param obj The entry object
+ * @return If true, the menu is disabled
+ *
+ * @ingroup Entry
+ */
+EAPI Eina_Bool
+elm_entry_context_menu_disabled_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return !wd->context_menu;
+}
+
+/**
+ * This appends a custom item provider to the list for that entry
+ *
+ * This appends the given callback. The list is walked from beginning to end
+ * with each function called given the item href string in the text. If the
+ * function returns an object handle other than NULL (it should create an
+ * and object to do this), then this object is used to replace that item. If
+ * not the next provider is called until one provides an item object, or the
+ * default provider in entry does.
+ * 
+ * @param obj The entry object
+ * @param func The function called to provide the item object
+ * @param data The data passed to @p func
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_item_provider_append(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *entry, const char *item), void *data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (!func) return;
+   Elm_Entry_Item_Provider *ip = calloc(1, sizeof(Elm_Entry_Item_Provider));
+   if (!ip) return;
+   ip->func = func;
+   ip->data = data;
+   wd->item_providers = eina_list_append(wd->item_providers, ip);
+}
+
+/**
+ * This prepends a custom item provider to the list for that entry
+ *
+ * This prepends the given callback. See elm_entry_item_provider_append() for
+ * more information
+ * 
+ * @param obj The entry object
+ * @param func The function called to provide the item object
+ * @param data The data passed to @p func
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_item_provider_prepend(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *entry, const char *item), void *data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (!func) return;
+   Elm_Entry_Item_Provider *ip = calloc(1, sizeof(Elm_Entry_Item_Provider));
+   if (!ip) return;
+   ip->func = func;
+   ip->data = data;
+   wd->item_providers = eina_list_prepend(wd->item_providers, ip);
+}
+
+/**
+ * This removes a custom item provider to the list for that entry
+ *
+ * This removes the given callback. See elm_entry_item_provider_append() for
+ * more information
+ * 
+ * @param obj The entry object
+ * @param func The function called to provide the item object
+ * @param data The data passed to @p func
+ *
+ * @ingroup Entry
+ */
+EAPI void
+elm_entry_item_provider_remove(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *entry, const char *item), void *data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Eina_List *l;
+   Elm_Entry_Item_Provider *ip;
+   if (!wd) return;
+   if (!func) return;
+   EINA_LIST_FOREACH(wd->item_providers, l, ip)
+     {
+        if ((ip->func == func) && (ip->data == data))
+          {
+             wd->item_providers = eina_list_remove_list(wd->item_providers, l);
+             free(ip);
+             return;
+          }
+     }
+}
+
+/**
+ * This converts a markup (HTML-like) string into UTF-8.
+ *
+ * @param s The string (in markup) to be converted
+ * @return The converted string (in UTF-8)
+ *
+ * @ingroup Entry
+ */
+EAPI char *
+elm_entry_markup_to_utf8(const char *s)
+{
+   char *ss = _mkup_to_text(s);
+   if (!ss) ss = strdup("");
+   return ss;
+}
+
+/**
+ * This converts a UTF-8 string into markup (HTML-like).
+ *
+ * @param s The string (in UTF-8) to be converted
+ * @return The converted string (in markup)
+ *
+ * @ingroup Entry
+ */
+EAPI char *
+elm_entry_utf8_to_markup(const char *s)
+{
+   char *ss = _text_to_mkup(s);
+   if (!ss) ss = strdup("");
+   return ss;
+}
diff --git a/src/lib/elm_flip.c b/src/lib/elm_flip.c
new file mode 100644 (file)
index 0000000..9daf720
--- /dev/null
@@ -0,0 +1,495 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Flip Flip
+ *
+ * This holds 2 content objects: one on the front and one on the back. It
+ * allows you to flip from front to back and vice-versa using various effects.
+ *
+ * Supported flip types:
+ * ELM_FLIP_ROTATE_Y_CENTER_AXIS
+ * ELM_FLIP_ROTATE_X_CENTER_AXIS
+ * ELM_FLIP_ROTATE_XZ_CENTER_AXIS
+ * ELM_FLIP_ROTATE_YZ_CENTER_AXIS
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * "animate,done" - when a flip animation is finished
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Ecore_Animator *animator;
+   double start, len;
+   Elm_Flip_Mode mode;
+   struct {
+      Evas_Object *content, *clip;
+   } front, back;
+   Eina_Bool state : 1;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+
+static void _configure(Evas_Object *obj);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->animator) ecore_animator_del(wd->animator);
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, minw2 = -1, minh2 = -1;
+   Evas_Coord maxw = -1, maxh = -1, maxw2 = -1, maxh2 = -1;
+   if (!wd) return;
+   if (wd->front.content)
+     evas_object_size_hint_min_get(wd->front.content, &minw, &minh);
+   if (wd->back.content)
+     evas_object_size_hint_min_get(wd->back.content, &minw2, &minh2);
+   if (wd->front.content)
+     evas_object_size_hint_max_get(wd->front.content, &maxw, &maxh);
+   if (wd->back.content)
+     evas_object_size_hint_max_get(wd->back.content, &maxw2, &maxh2);
+   
+   if (minw2 > minw) minw = minw2;
+   if (minh2 > minh) minh = minh2;
+   if ((maxw2 >= 0) && (maxw2 < maxw)) maxw = maxw2;
+   if ((maxh2 >= 0) && (maxh2 < maxh)) maxh = maxh2;
+   
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *sub = event_info;
+   if (!wd) return;
+   if (sub == wd->front.content)
+     {
+       evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                            _changed_size_hints, obj);
+       wd->front.content = NULL;
+        evas_object_hide(wd->front.clip);
+       _sizing_eval(obj);
+     }
+   else if (sub == wd->back.content)
+     {
+       evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                            _changed_size_hints, obj);
+       wd->back.content = NULL;
+        evas_object_hide(wd->back.clip);
+       _sizing_eval(obj);
+     }
+}
+
+static int
+_flip(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   double t = ecore_loop_time_get() - wd->start;
+   Evas_Coord x, y, w, h;
+   double p, deg;
+   Evas_Map *mf, *mb;
+   Evas_Coord cx, cy, px, py, foc;
+   int lx, ly, lz, lr, lg, lb, lar, lag, lab;
+   if (!wd->animator) return 0;
+   t = t / wd->len;
+   if (t > 1.0) t = 1.0;
+
+   if (!wd) return 0;
+   evas_object_geometry_get(obj, &x, &y, &w, &h);
+
+   mf = evas_map_new(4);
+   evas_map_smooth_set(mf, 0);
+   mb = evas_map_new(4);
+   evas_map_smooth_set(mb, 0);
+
+   if (wd->front.content)
+     evas_map_util_points_populate_from_object_full(mf, wd->front.content, 0);
+   if (wd->back.content)
+     evas_map_util_points_populate_from_object_full(mb, wd->back.content, 0);
+   
+   cx = x + (w / 2);
+   cy = y + (h / 2);
+
+   px = x + (w / 2);
+   py = y + (h / 2);
+   foc = 2048;
+   
+   lx = cx;
+   ly = cy;
+   lz = -10000;
+   lr = 255;
+   lg = 255;
+   lb = 255;
+   lar = 0;
+   lag = 0;
+   lab = 0;
+   
+   switch (wd->mode)
+     {
+     case ELM_FLIP_ROTATE_Y_CENTER_AXIS:
+        p = 1.0 - t;
+        p = 1.0 - (p * p);
+        if (wd->state) deg = 180.0 * p;
+        else deg = 180 + (180.0 * p);
+        evas_map_util_3d_rotate(mf, 0.0, deg, 0.0, cx, cy, 0);
+        evas_map_util_3d_rotate(mb, 0.0, deg + 180.0, 0.0, cx, cy, 0);
+        break;
+     case ELM_FLIP_ROTATE_X_CENTER_AXIS:
+        p = 1.0 - t;
+        p = 1.0 - (p * p);
+        if (wd->state) deg = 180.0 * p;
+        else deg = 180 + (180.0 * p);
+        evas_map_util_3d_rotate(mf, deg, 0.0, 0.0, cx, cy, 0);
+        evas_map_util_3d_rotate(mb, deg + 180.0, 0.0, 0.0, cx, cy, 0);
+        break;
+     case ELM_FLIP_ROTATE_XZ_CENTER_AXIS:
+        p = 1.0 - t;
+        p = 1.0 - (p * p);
+        if (wd->state) deg = 180.0 * p;
+        else deg = 180 + (180.0 * p);
+        evas_map_util_3d_rotate(mf, deg, 0.0, deg, cx, cy, 0);
+        evas_map_util_3d_rotate(mb, deg + 180.0, 0.0, deg + 180.0, cx, cy, 0);
+        break;
+     case ELM_FLIP_ROTATE_YZ_CENTER_AXIS:
+        p = 1.0 - t;
+        p = 1.0 - (p * p);
+        if (wd->state) deg = 180.0 * p;
+        else deg = 180 + (180.0 * p);
+        evas_map_util_3d_rotate(mf, 0.0, deg, deg, cx, cy, 0);
+        evas_map_util_3d_rotate(mb, 0.0, deg + 180.0, deg + 180.0, cx, cy, 0);
+        break;
+     default:
+        break;
+     }
+
+   
+   if (wd->front.content)
+     {
+        evas_map_util_3d_lighting(mf, lx, ly, lz, lr, lg, lb, lar, lag, lab);
+        evas_map_util_3d_perspective(mf, px, py, 0, foc);
+        evas_object_map_set(wd->front.content, mf);
+        evas_object_map_enable_set(wd->front.content, 1);
+        if (evas_map_util_clockwise_get(mf)) evas_object_show(wd->front.clip);
+        else evas_object_hide(wd->front.clip);
+     }
+      
+   if (wd->back.content)
+     {
+        evas_map_util_3d_lighting(mb, lx, ly, lz, lr, lg, lb, lar, lag, lab);
+        evas_map_util_3d_perspective(mb, px, py, 0, foc);
+        evas_object_map_set(wd->back.content, mb);
+        evas_object_map_enable_set(wd->back.content, 1);
+        if (evas_map_util_clockwise_get(mb)) evas_object_show(wd->back.clip);
+        else evas_object_hide(wd->back.clip);
+     }
+   
+   evas_map_free(mf);
+   evas_map_free(mb);
+   
+   if (t >= 1.0)
+     {
+        evas_object_map_enable_set(wd->front.content, 0);
+        evas_object_map_enable_set(wd->back.content, 0);
+        wd->animator = NULL;
+        wd->state = !wd->state;
+        _configure(obj);
+        evas_object_smart_callback_call(obj, "animate,done", NULL);
+        return 0;
+     }
+   return 1;
+}
+
+static void
+_configure(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord x, y, w, h;
+   if (!wd) return;
+   evas_object_geometry_get(obj, &x, &y, &w, &h);
+   if (wd->front.content)
+     {
+        if (!wd->animator)
+          evas_object_move(wd->front.content, x, y);
+        evas_object_resize(wd->front.content, w, h);
+     }
+   if (wd->back.content)
+     {
+        if (!wd->animator)
+          evas_object_move(wd->back.content, x, y);
+        evas_object_resize(wd->back.content, w, h);
+     }
+   _flip(obj);
+}
+
+static void
+_move(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   _configure(obj);
+}
+
+static void
+_resize(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{    
+   _configure(obj);
+}
+
+static int
+_animate(void *data)
+{
+   return _flip(data);
+}
+
+/**
+ * Add a new flip to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Flip
+ */
+EAPI Evas_Object *
+elm_flip_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "flip");
+   elm_widget_type_set(obj, "flip");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   wd->front.clip = evas_object_rectangle_add(e);
+   evas_object_color_set(wd->front.clip, 255, 255, 255, 255);
+   evas_object_move(wd->front.clip, -49999, -49999);
+   evas_object_resize(wd->front.clip, 99999, 99999);
+   elm_widget_sub_object_add(wd->front.clip, obj);
+   evas_object_smart_member_add(wd->front.clip, obj);
+   
+   wd->back.clip = evas_object_rectangle_add(e);
+   evas_object_color_set(wd->back.clip, 255, 255, 255, 255);
+   evas_object_move(wd->back.clip, -49999, -49999);
+   evas_object_resize(wd->back.clip, 99999, 99999);
+   elm_widget_sub_object_add(wd->back.clip, obj);
+   evas_object_smart_member_add(wd->back.clip, obj);
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, NULL);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, NULL);
+   
+   wd->state = 1;
+     
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Set the flip front content
+ *
+ * @param obj The flip object
+ * @param content The content to be used in this flip object
+ *
+ * @ingroup Flip
+ */
+EAPI void
+elm_flip_content_front_set(Evas_Object *obj, Evas_Object *content)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->front.content == content) return;
+   if ((wd->front.content != content) && (wd->front.content))
+     {
+        evas_object_clip_set(wd->front.content, NULL);
+        elm_widget_sub_object_del(obj, wd->front.content);
+        evas_object_smart_member_del(wd->front.content);
+     }
+   wd->front.content = content;
+   if (content)
+     {
+       elm_widget_sub_object_add(content, obj);
+        evas_object_smart_member_add(content, obj);
+        evas_object_clip_set(content, wd->front.clip);
+       evas_object_event_callback_add(content,
+                                       EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                      _changed_size_hints, obj);
+       _sizing_eval(obj);
+        if (!elm_flip_front_get(obj)) evas_object_hide(wd->front.clip);
+        else evas_object_show(wd->front.clip);
+     }
+   else
+     evas_object_hide(wd->front.clip);     
+   _configure(obj);
+}
+
+/**
+ * Set the flip back content
+ *
+ * @param obj The flip object
+ * @param content The content to be used in this flip object
+ *
+ * @ingroup Flip
+ */
+EAPI void
+elm_flip_content_back_set(Evas_Object *obj, Evas_Object *content)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->back.content == content) return;
+   if ((wd->back.content != content) && (wd->back.content))
+     {
+        evas_object_clip_set(wd->back.content, NULL);
+        elm_widget_sub_object_del(obj, wd->back.content);
+        evas_object_smart_member_del(wd->back.content);
+     }
+   wd->back.content = content;
+   if (content)
+     {
+       elm_widget_sub_object_add(content, obj);
+        evas_object_smart_member_add(content, obj);
+        evas_object_clip_set(content, wd->back.clip);
+       evas_object_event_callback_add(content,
+                                       EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                      _changed_size_hints, obj);
+       _sizing_eval(obj);
+        if (elm_flip_front_get(obj)) evas_object_hide(wd->back.clip);
+        else evas_object_show(wd->back.clip);
+     }
+   else
+     evas_object_hide(wd->back.clip);
+   _configure(obj);
+}
+
+/**
+ * Get the flip front content
+ *
+ * @param obj The flip object
+ * @return The content to be used in this flip object front
+ *
+ * @ingroup Flip
+ */
+EAPI Evas_Object *
+elm_flip_content_front_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   return wd->front.content;
+}
+
+/**
+ * Get the flip back content
+ *
+ * @param obj The flip object
+ * @return The content to be used in this flip object back
+ *
+ * @ingroup Flip
+ */
+EAPI Evas_Object *
+elm_flip_content_back_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   return wd->back.content;
+}
+
+/**
+ * Get flip front visibility state
+ *
+ * @param obj The flip object
+ * @return If front front is showing or not currently
+ *
+ * @ingroup Flip
+ */
+EAPI Eina_Bool
+elm_flip_front_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->state;
+}
+
+/**
+ * Set flip perspective
+ *
+ * @param obj The flip object
+ * @param foc The coordinate to set the focus on
+ * @param x The X coordinate
+ * @param y The Y coordinate
+ *
+ * NOTE: This function currently does nothing.
+ *
+ * @ingroup Flip
+ */
+EAPI void
+elm_flip_perspective_set(Evas_Object *obj, Evas_Coord foc __UNUSED__, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+}
+
+/**
+ * Runs the flip animation
+ *
+ * @param obj The flip object
+ * @param mode The mode type.  Currently accepted modes are:
+ *
+ * ELM_FLIP_ROTATE_Y_CENTER_AXIS
+ * ELM_FLIP_ROTATE_X_CENTER_AXIS
+ * ELM_FLIP_ROTATE_XZ_CENTER_AXIS
+ * ELM_FLIP_ROTATE_YZ_CENTER_AXIS
+ *
+ * @ingroup Flip
+ */
+EAPI void
+elm_flip_go(Evas_Object *obj, Elm_Flip_Mode mode)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (!wd->animator) wd->animator = ecore_animator_add(_animate, obj);
+   wd->mode = mode;
+   wd->start = ecore_loop_time_get();
+   wd->len = 0.5;
+}
diff --git a/src/lib/elm_frame.c b/src/lib/elm_frame.c
new file mode 100644 (file)
index 0000000..3acd071
--- /dev/null
@@ -0,0 +1,180 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Frame Frame
+ *
+ * This holds some content and has a title. Looks like a frame, but
+ * supports styles so multple frames are avaible
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *frm;
+   Evas_Object *content;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _elm_theme_object_set(obj, wd->frm, "frame", "base", elm_widget_style_get(obj));
+   if (wd->content)
+     edje_object_part_swallow(wd->frm, "elm.swallow.content", wd->content);
+   edje_object_scale_set(wd->frm, elm_widget_scale_get(obj) * _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1;
+   if (!wd) return;
+   edje_object_size_min_calc(wd->frm, &minw, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   // FIXME: why is this needed? how does edje get this unswallowed or
+   // lose its callbacks to edje
+   if (!wd) return;
+   edje_object_part_swallow(wd->frm, "elm.swallow.content", wd->content);
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *sub = event_info;
+   if (!wd) return;
+   if (sub == wd->content)
+     {
+       evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                            _changed_size_hints, obj);
+       wd->content = NULL;
+       _sizing_eval(obj);
+     }
+}
+
+/**
+ * Add a new frame to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Frame
+ */
+EAPI Evas_Object *
+elm_frame_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "frame");
+   elm_widget_type_set(obj, "frame");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   wd->frm = edje_object_add(e);
+   _elm_theme_object_set(obj, wd->frm, "frame", "base", "default");
+   elm_widget_resize_object_set(obj, wd->frm);
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Set the frame label
+ *
+ * @param obj The frame object
+ * @param label The label of this frame object
+ *
+ * @ingroup Frame
+ */
+EAPI void
+elm_frame_label_set(Evas_Object *obj, const char *label)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   edje_object_part_text_set(wd->frm, "elm.text", label);
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the frame label
+ *
+ * @param obj The frame object
+ *
+ * @return The label of this frame objet or NULL if unable to get frame
+ *
+ * @ingroup Frame
+ */
+EAPI const char *
+elm_frame_label_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if ((!wd) || (!wd->frm)) return NULL;
+   return edje_object_part_text_get(wd->frm, "elm.text");
+}
+
+/**
+ * Set the frame content
+ *
+ * @param obj The frame object
+ * @param content The content will be filled in this frame object
+ *
+ * @ingroup Frame
+ */
+EAPI void
+elm_frame_content_set(Evas_Object *obj, Evas_Object *content)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if ((wd->content != content) && (wd->content))
+     elm_widget_sub_object_del(obj, wd->content);
+   wd->content = content;
+   if (content)
+     {
+       elm_widget_sub_object_add(obj, content);
+       evas_object_event_callback_add(content,
+                                       EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                      _changed_size_hints, obj);
+       edje_object_part_swallow(wd->frm, "elm.swallow.content", content);
+       _sizing_eval(obj);
+     }
+}
diff --git a/src/lib/elm_genlist.c b/src/lib/elm_genlist.c
new file mode 100644 (file)
index 0000000..436c42b
--- /dev/null
@@ -0,0 +1,3147 @@
+/*
+ *
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Genlist Genlist
+ *
+ * The aim was to have  more expansive list that the simple list in
+ * Elementary that could have more flexible items and allow many more entries
+ * while still being fast and low on memory usage. At the same time it was
+ * also made to be able to do tree structures. But the price to pay is more
+ * complexity when it comes to usage. If all you want is a simple list with
+ * icons and a single label, use the normal List object.
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * clicked - This is called when a user has double-clicked an item. The
+ * event_info parameter is the genlist item that was double-clicked.
+ *
+ * selected - This is called when a user has made an item selected. The
+ * event_info parameter is the genlist item that was selected.
+ *
+ * unselected - This is called when a user has made an item unselected. The
+ * event_info parameter is the genlist item that was unselected.
+ *
+ * expanded -  This is called when elm_genlist_item_expanded_set() is called
+ * and the item is now meant to be expanded. The event_info parameter is the
+ * genlist item that was indicated to expand. It is the job of this callback
+ * to then fill in the child items.
+ *
+ * contracted - This is called when elm_genlist_item_expanded_set() is called
+ * and the item is now meant to be contracted. The event_info parameter is
+ * the genlist item that was indicated to contract. It is the job of this
+ * callback to then delete the child items
+ *
+ * expand,request - This is called when a user has indicated they want to
+ * expand a tree branch item. The callback should decide if the item can
+ * expand (has any children) and then call elm_genlist_item_expanded_set()
+ * appropriately to set the state. The event_info parameter is the genlist
+ * item that was indicated to expand.
+ *
+ * contract,request - This is called when a user has indicated they want to
+ * contract a tree branch item. The callback should decide if the item can
+ * contract (has any children) and then call elm_genlist_item_expanded_set()
+ * appropriately to set the state. The event_info parameter is the genlist
+ * item that was indicated to contract.
+ *
+ * realized - This is called when the item in the list is created as a real
+ * evas object. event_info parameter is the genlist item that was created.
+ * The object may be deleted at any time, so it is up to the caller to
+ * not use the object pointer from elm_genlist_item_object_get() in a way
+ * where it may point to freed objects.
+ *
+ * drag,start,up - This is called when the item in the list has been dragged
+ * (not scrolled) up.
+ *
+ * drag,start,down - This is called when the item in the list has been dragged
+ * (not scrolled) down.
+ *
+ * drag,start,left - This is called when the item in the list has been dragged
+ * (not scrolled) left.
+ *
+ * drag,start,right - This is called when the item in the list has been dragged
+ * (not scrolled) right.
+ *
+ * drag,stop - This is called when the item in the list has stopped being
+ * dragged.
+ *
+ * drag - This is called when the item in the list is being dragged.
+ *
+ * Genlist has a fairly large API, mostly because it's relatively complex,
+ * trying to be both expansive, powerful and efficient. First we will begin
+ * an overview o the theory behind genlist.
+ *
+ * Evas tracks every object you create. Every time it processes an event
+ * (mouse move, down, up etc.) it needs to walk through objects and find out
+ * what event that affects. Even worse every time it renders display updates,
+ * in order to just calculate what to re-draw, it needs to walk through many
+ * many many objects. Thus, the more objects you keep active, the more
+ * overhead Evas has in just doing its work. It is advisable to keep your
+ * active objects to the minimum working set you need. Also remember that
+ * object creation and deletion carries an overhead, so there is a
+ * middle-ground, which is not easily determined. But don't keep massive lists
+ * of objects you can't see or use. Genlist does this with list objects. It
+ * creates and destroys them dynamically as you scroll around. It groups them
+ * into blocks so it can determine the visibility etc. of a whole block at
+ * once as opposed to having to walk the whole list. This 2-level list allows
+ * for very large numbers of items to be in the list (tests have used up to
+ * 2,000,000 items). Also genlist employs a queue for adding items. As items
+ * may be different sizes, every item added needs to be calculated as to its
+ * size and thus this presents a lot of overhead on populating the list, this
+ * genlist employs a queue. Any item added is queued and spooled off over
+ * time, actually appearing some time later, so if your list has many members
+ * you may find it takes a while for them to all appear, with your process
+ * consuming a lot of CPU while it is busy spooling.
+ *
+ * Genlist also implements a tree structure, but it does so with callbacks to
+ * the application, with the application filling in tree structures when
+ * requested (allowing for efficient building of a very deep tree that could
+ * even be used for file-management). See the above smart signal callbacks for
+ * details.
+ *
+ * An item in the genlist world can have 0 or more text labels (they can be
+ * regular text or textblock – that's up to the style to determine), 0 or
+ * more icons (which are simply objects swallowed into the genlist item) and
+ * 0 or more boolean states that can be used for check, radio or other
+ * indicators by the edje theme style. An item may be one of several styles
+ * (Elementary provides 2 by default - “default” and “double_label”, but this
+ * can be extended by system or application custom themes/overlays/extensions).
+ *
+ * In order to implement the ability to add and delete items on the fly,
+ * Genlist implements a class/callback system where the application provides
+ * a structure with information about that type of item (genlist may contain
+ * multiple different items with different classes, states and styles).
+ * Genlist will call the functions in this struct (methods) when an item is
+ * “realized” (that is created dynamically while scrolling). All objects will
+ * simply be deleted  when no longer needed with evas_object_del(). The
+ * Elm_Genlist_Item_Class structure contains the following members:
+ *
+ * item_style - This is a constant string and simply defines the name of the
+ * item style. It must be specified and the default should be “default”.
+ *
+ * func.label_get - This function is called when an actual item object is
+ * created. The data parameter is the data parameter passed to
+ * elm_genlist_item_append() and related item creation functions. The obj
+ * parameter is the genlist object and the part parameter is the string name
+ * of the text part in the edje design that is listed as one of the possible
+ * labels that can be set. This function must return a strudup()'ed string as
+ * the caller will free() it when done.
+ *
+ * func.icon_get - This function is called when an actual item object is
+ * created. The data parameter is the data parameter passed to
+ * elm_genlist_item_append() and related item creation functions. The obj
+ * parameter is the genlist object and the part parameter is the string name
+ * of the icon part in the edje design that is listed as one of the possible
+ * icons that can be set. This must return NULL for no object or a valid
+ * object. The object will be deleted by genlist on shutdown or when the item
+ * its unrealized.
+ *
+ * func.state_get - This function is called when an actual item object is
+ * created. The data parameter is the data parameter passed to
+ * elm_genlist_item_append() and related item creation functions. The obj
+ * parameter is the genlist object and the part parameter is the string name
+ * of the state part in the edje design that is listed as one of the possible
+ * states that can be set. Return 0 for false or 1 for true. Genlist will
+ * emit a signal to the edje object with “elm,state,XXX,active” “elm” when
+ * true (the default is false), where XXX is the name of the part.
+ *
+ * func.del - This is called when elm_genlist_item_del() is called on an
+ * item, elm_genlist_clear() is called on the genlist, or
+ * elm_genlist_item_subitems_clear() is called to clear sub-items. This is
+ * intended for use when actual genlist items are deleted, so any backing
+ * data attached to the item (e.g. its data parameter on creation) can be
+ * deleted.
+ *
+ * Items can be added by several calls. All of them return a Elm_Genlist_Item
+ * handle that is an internal member inside the genlist. They all take a data
+ * parameter that is meant to be used for a handle to the applications
+ * internal data (eg the struct with the original item data). The parent
+ * parameter is the parent genlist item this belongs to if it is a tree, and
+ * NULL if there is no parent. The flags can be a bitmask of
+ * ELM_GENLIST_ITEM_NONE and ELM_GENLIST_ITEM_SUBITEMS. If
+ * ELM_GENLIST_ITEM_SUBITEMS is set then this item is displayed as a item
+ * that is able to expand and have child items. The func parameter is a
+ * convenience callback that is called when the item is selected and the data
+ * parameter will be the func_data parameter, obj be the genlist object and
+ * vent_info will be the genlist item.
+ *
+ * elm_genlist_item_append() appends an item to the end of the list, or if
+ * there is a parent, to the end of all the child items of the parent.
+ * elm_genlist_item_prepend() is the same but prepends to the beginning of
+ * the list or children list. elm_genlist_item_insert_before() inserts at
+ * item before another item and elm_genlist_item_insert_after() inserts after
+ * the indicated item.
+ *
+ * The application can clear the list with elm_genlist_clear() which deletes
+ * all the items in the list and elm_genlist_item_del() will delete a specific
+ * item. elm_genlist_item_subitems_clear() will clear all items that are
+ * children of the indicated parent item.
+ *
+ * If the application wants multiple items to be able to be selected,
+ * elm_genlist_multi_select_set() can enable this. If the list is
+ * single-selection only (the default), then elm_genlist_selected_item_get()
+ * will return the selected item, if any, or NULL I none is selected. If the
+ * list is multi-select then elm_genlist_selected_items_get() will return a
+ * list (that is only valid as long as no items are modified (added, deleted,
+ * selected or unselected).
+ *
+ * To help inspect list items you can jump to the item at the top of the list
+ * with elm_genlist_first_item_get() which will return the item pointer, and
+ * similarly elm_genlist_last_item_get() gets the item at the end of the list.
+ * elm_genlist_item_next_get() and elm_genlist_item_prev_get() get the next
+ * and previous items respectively relative to the indicated item. Using
+ * these calls you can walk the entire item list/tree. Note that as a tree
+ * the items are flattened in the list, so elm_genlist_item_parent_get() will
+ * let you know which item is the parent (and thus know how to skip them if
+ * wanted).
+ *
+ * There are also convenience functions. elm_genlist_item_genlist_get() will
+ * return the genlist object the item belongs to.  elm_genlist_item_show()
+ * will make the scroller scroll to show that specific item so its visible.
+ * elm_genlist_item_data_get() returns the data pointer set by the item
+ * creation functions.
+ *
+ * If an item changes (state of boolean changes, label or icons change),
+ * then use elm_genlist_item_update() to have genlist update the item with
+ * the new state. Genlist will re-realize the item thus call the functions
+ * in the _Elm_Genlist_Item_Class for that item.
+ *
+ * To programmatically (un)select an item use elm_genlist_item_selected_set().
+ * To get its selected state use elm_genlist_item_selected_get(). Similarly
+ * to expand/contract and item and get its expanded state, use
+ * elm_genlist_item_expanded_set() and elm_genlist_item_expanded_get(). And
+ * again to make an item disabled (unable to be selected and appear
+ * differently) use elm_genlist_item_disabled_set() to set this and
+ * elm_genlist_item_disabled_get() to get the disabled state.
+ *
+ * In general to indicate how the genlist should expand items horizontally to
+ * fill the list area, use elm_genlist_horizontal_mode_set(). Valid modes are
+ * ELM_LIST_LIMIT and ELM_LIST_SCROLL . The default is ELM_LIST_SCROLL. This
+ * mode means that if items are too wide to fit, the scroller will scroll
+ * horizontally. Otherwise items are expanded to fill the width of the
+ * viewport of the scroller. If it is ELM_LIST_LIMIT, Items will be expanded
+ * to the viewport width and limited to that size. This can be combined with
+ * a different style that uses edjes' ellipsis feature (cutting text off like
+ * this: “tex...”).
+ *
+ * Items will only call their selection func and callback when first becoming
+ * selected. Any further clicks will do nothing, unless you enable always
+ * select with elm_genlist_always_select_mode_set(). This means even if
+ * selected, every click will make the selected callbacks be called.
+ * elm_genlist_no_select_mode_set() will turn off the ability to select
+ * items entirely and they will neither appear selected nor call selected
+ * callback functions.
+ *
+ * Remember that you can create new styles and add you own theme augmentation
+ * per application with elm_theme_extension_add(). If you absolutely must
+ * have a specific style that overrides any theme the user or system sets up
+ * you can use elm_theme_overlay_add() to add such a file.
+ */
+
+typedef struct _Widget_Data Widget_Data;
+typedef struct _Item_Block Item_Block;
+typedef struct _Pan Pan;
+
+struct _Widget_Data
+{
+   Evas_Object *obj, *scr, *pan_smart;
+   Eina_Inlist *items, *blocks;
+   Pan *pan;
+   Evas_Coord pan_x, pan_y, minw, minh;
+   Ecore_Job *calc_job, *update_job;
+   Ecore_Idler *queue_idler;
+   Eina_List *queue, *selected;
+   Elm_Genlist_Item *show_item;
+   Elm_List_Mode mode;
+   Eina_Bool on_hold : 1;
+   Eina_Bool multi : 1;
+   Eina_Bool always_select : 1;
+   Eina_Bool longpressed : 1;
+   Eina_Bool wasselected : 1;
+   Eina_Bool no_select : 1;
+   Eina_Bool bring_in : 1;
+   Eina_Bool compress : 1;
+   Eina_Bool homogeneous : 1;
+   int item_width;
+   int item_height;
+   int max_items_per_block;
+};
+
+struct _Item_Block
+{
+   EINA_INLIST;
+   int count;
+   int num;
+   Widget_Data *wd;
+   Eina_List *items;
+   Evas_Coord x, y, w, h, minw, minh;
+   Eina_Bool want_unrealize : 1;
+   Eina_Bool realized : 1;
+   Eina_Bool changed : 1;
+   Eina_Bool updateme : 1;
+   Eina_Bool showme : 1;
+};
+
+struct _Elm_Genlist_Item
+{
+   EINA_INLIST;
+   Widget_Data *wd;
+   Item_Block *block;
+   Eina_List *items;
+   Evas_Coord x, y, w, h, minw, minh;
+   const Elm_Genlist_Item_Class *itc;
+   const void *data;
+   Elm_Genlist_Item *parent;
+   Elm_Genlist_Item_Flags flags;
+   struct 
+     {
+        Evas_Smart_Cb func;
+        const void *data;
+     } func;
+
+   Evas_Object *base, *spacer;
+   Eina_List *labels, *icons, *states, *icon_objs;
+   Ecore_Timer *long_timer;
+   Evas_Coord dx, dy;
+
+   Elm_Genlist_Item *rel;
+   int relcount;
+   int walking;
+   Eina_Bool before : 1;
+
+   Eina_Bool want_unrealize : 1;
+   Eina_Bool realized : 1;
+   Eina_Bool selected : 1;
+   Eina_Bool hilighted : 1;
+   Eina_Bool expanded : 1;
+   Eina_Bool disabled : 1;
+   Eina_Bool display_only : 1;
+   Eina_Bool mincalcd : 1;
+   Eina_Bool queued : 1;
+   Eina_Bool showme : 1;
+   Eina_Bool delete_me : 1;
+   Eina_Bool down : 1;
+   Eina_Bool dragging : 1;
+   Eina_Bool updateme : 1;
+};
+
+struct _Pan
+{
+   Evas_Object_Smart_Clipped_Data __clipped_data;
+   Widget_Data *wd;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+//static void _show_region_hook(void *data, Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _item_unrealize(Elm_Genlist_Item *it);
+static void _item_block_unrealize(Item_Block *itb);
+static void _calc_job(void *data);
+
+static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->calc_job) ecore_job_del(wd->calc_job);
+   if (wd->update_job) ecore_job_del(wd->update_job);
+   free(wd);
+}
+
+static void
+_del_pre_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   evas_object_del(wd->pan_smart);
+   wd->pan_smart = NULL;
+   elm_genlist_clear(obj);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Item_Block *itb;
+   if (!wd) return;
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base", elm_widget_style_get(obj));
+//   edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
+   EINA_INLIST_FOREACH(wd->blocks, itb)
+     {
+       Eina_List *l;
+       Elm_Genlist_Item *it;
+        
+       if (itb->realized) _item_block_unrealize(itb);
+       EINA_LIST_FOREACH(itb->items, l, it)
+          it->mincalcd = EINA_FALSE;
+
+       itb->changed = EINA_TRUE;
+     }
+   if (wd->calc_job) ecore_job_del(wd->calc_job);
+   wd->calc_job = ecore_job_add(_calc_job, wd);
+   _sizing_eval(obj);
+}
+
+/*
+static void
+_show_region_hook(void *data, Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Coord x, y, w, h;
+   if (!wd) return;
+   elm_widget_show_region_get(obj, &x, &y, &w, &h);
+   elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
+}
+*/
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   if (!wd) return;
+   evas_object_size_hint_min_get(wd->scr, &minw, &minh);
+   evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
+   minh = -1;
+   if (wd->mode != ELM_LIST_LIMIT) minw = -1;
+   else
+     {
+        Evas_Coord  vmw, vmh, vw, vh;
+        
+        minw = wd->minw;
+        maxw = -1;
+        elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
+        if ((minw > 0) && (vw < minw)) vw = minw;
+        else if ((maxw > 0) && (vw > maxw)) vw = maxw;
+        minw = -1;
+        edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
+        minw = vmw + minw;
+     }
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_item_hilight(Elm_Genlist_Item *it)
+{
+   const char *selectraise;
+   if ((it->wd->no_select) || (it->delete_me) || (it->hilighted)) return;
+   edje_object_signal_emit(it->base, "elm,state,selected", "elm");
+   selectraise = edje_object_data_get(it->base, "selectraise");
+   if ((selectraise) && (!strcmp(selectraise, "on")))
+     evas_object_raise(it->base);
+   it->hilighted = EINA_TRUE;
+}
+
+static void
+_item_block_del(Elm_Genlist_Item *it)
+{
+   Eina_Inlist *il;
+   Item_Block *itb = it->block;
+
+   itb->items = eina_list_remove(itb->items, it);
+   itb->count--;
+   itb->changed = EINA_TRUE;
+   if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
+   it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
+   if (itb->count < 1)
+     {
+       il = EINA_INLIST_GET(itb);
+       Item_Block *itbn = (Item_Block *)(il->next);
+       if (it->parent)
+         it->parent->items = eina_list_remove(it->parent->items, it);
+       else
+         it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
+       free(itb);
+       if (itbn) itbn->changed = EINA_TRUE;
+     }
+   else
+     {
+       if (itb->count < 16)
+         {
+            il = EINA_INLIST_GET(itb);
+            Item_Block *itbp = (Item_Block *)(il->prev);
+            Item_Block *itbn = (Item_Block *)(il->next);
+            if ((itbp) && ((itbp->count + itb->count) < 48))
+              {
+                 Elm_Genlist_Item *it2;
+
+                 EINA_LIST_FREE(itb->items, it2)
+                   {
+                      it2->block = itbp;
+                      itbp->items = eina_list_append(itbp->items, it2);
+                      itbp->count++;
+                      itbp->changed = EINA_TRUE;
+                   }
+                 it->wd->blocks = eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
+                 free(itb);
+              }
+            else if ((itbn) && ((itbn->count + itb->count) < 48))
+              {
+                 while (itb->items)
+                   {
+                      Eina_List *last = eina_list_last(itb->items);
+                      Elm_Genlist_Item *it2 = last->data;
+
+                      it2->block = itbn;
+                      itb->items = eina_list_remove_list(itb->items, last);
+                      itbn->items = eina_list_prepend(itbn->items, it2);
+                      itbn->count++;
+                      itbn->changed = EINA_TRUE;
+                   }
+                 it->wd->blocks = 
+                    eina_inlist_remove(it->wd->blocks, EINA_INLIST_GET(itb));
+                 free(itb);
+              }
+         }
+     }
+}
+
+static void
+_item_del(Elm_Genlist_Item *it)
+{
+   elm_genlist_item_subitems_clear(it);
+   if (it->wd->show_item == it) it->wd->show_item = NULL;
+   if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
+   if (it->realized) _item_unrealize(it);
+   if (it->block) _item_block_del(it);
+   if ((!it->delete_me) && (it->itc->func.del)) 
+     it->itc->func.del(it->data, it->wd->obj);
+   it->delete_me = EINA_TRUE;
+   if (it->queued)
+     it->wd->queue = eina_list_remove(it->wd->queue, it);
+   it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
+   if (it->parent)
+     it->parent->items = eina_list_remove(it->parent->items, it);
+   if (it->long_timer) ecore_timer_del(it->long_timer);
+   free(it);
+}
+
+static void
+_item_select(Elm_Genlist_Item *it)
+{
+   if ((it->wd->no_select) || (it->delete_me)) return;
+   if (it->selected)
+     {
+       if (it->wd->always_select) goto call;
+       return;
+     }
+   it->selected = EINA_TRUE;
+   it->wd->selected = eina_list_append(it->wd->selected, it);
+   call:
+   it->walking++;
+   if (it->func.func) it->func.func((void *)it->func.data, it->wd->obj, it);
+   if (!it->delete_me)
+     evas_object_smart_callback_call(it->wd->obj, "selected", it);
+   it->walking--;
+   if ((it->walking == 0) && (it->delete_me))
+     {
+        if (it->relcount == 0) _item_del(it);
+     }
+}
+
+static void
+_item_unselect(Elm_Genlist_Item *it)
+{
+   const char *stacking, *selectraise;
+
+   if ((it->delete_me) || (!it->hilighted)) return;
+   edje_object_signal_emit(it->base, "elm,state,unselected", "elm");
+   stacking = edje_object_data_get(it->base, "stacking");
+   selectraise = edje_object_data_get(it->base, "selectraise");
+   if ((selectraise) && (!strcmp(selectraise, "on")))
+     {
+       if ((stacking) && (!strcmp(stacking, "below")))
+         evas_object_lower(it->base);
+     }
+   it->hilighted = EINA_FALSE;
+   if (it->selected)
+     {
+       it->selected = EINA_FALSE;
+       it->wd->selected = eina_list_remove(it->wd->selected, it);
+       evas_object_smart_callback_call(it->wd->obj, "unselected", it);
+     }
+}
+
+static void
+_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Elm_Genlist_Item *it = data;
+   Evas_Event_Mouse_Move *ev = event_info;
+   Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
+
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
+     {
+       if (!it->wd->on_hold)
+         {
+            it->wd->on_hold = EINA_TRUE;
+            _item_unselect(it);
+         }
+     }
+   if ((it->dragging) && (it->down))
+     {
+        if (it->long_timer)
+          {
+             ecore_timer_del(it->long_timer);
+             it->long_timer = NULL;
+          }
+        evas_object_smart_callback_call(it->wd->obj, "drag", it);
+        return;
+     }
+   if ((!it->down)/* || (it->wd->on_hold)*/ || (it->wd->longpressed))
+     {
+        if (it->long_timer)
+          {
+             ecore_timer_del(it->long_timer);
+             it->long_timer = NULL;
+          }
+        return;
+     }
+   if (!it->display_only)
+     elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   evas_object_geometry_get(obj, &x, &y, NULL, NULL);
+   x = ev->cur.canvas.x - x;
+   y = ev->cur.canvas.y - y;
+   dx = x - it->dx;
+   adx = dx;
+   if (adx < 0) adx = -dx;
+   dy = y - it->dy;
+   ady = dy;
+   if (ady < 0) ady = -dy;
+   minw /= 2;
+   minh /= 2;
+   if ((adx > minw) || (ady > minh))
+     {
+        it->dragging = 1;
+        if (it->long_timer)
+          {
+             ecore_timer_del(it->long_timer);
+             it->long_timer = NULL;
+          }
+        if (!it->wd->wasselected)
+          _item_unselect(it);
+        it->wd->wasselected = 0;
+        if (dy < 0)
+          {
+             if (ady > adx)
+               evas_object_smart_callback_call(it->wd->obj, "drag,start,up", it);
+             else
+               {
+                  if (dx < 0)
+                    evas_object_smart_callback_call(it->wd->obj, 
+                                                    "drag,start,left", it);
+                  else
+                    evas_object_smart_callback_call(it->wd->obj, 
+                                                    "drag,start,right", it);
+               }
+          }
+        else
+          {
+             if (ady > adx)
+               evas_object_smart_callback_call(it->wd->obj, 
+                                               "drag,start,down", it);
+             else
+               {
+                  if (dx < 0)
+                    evas_object_smart_callback_call(it->wd->obj, 
+                                                    "drag,start,left", it);
+                  else
+                    evas_object_smart_callback_call(it->wd->obj, 
+                                                    "drag,start,right", it);
+               }
+          }
+     }
+}
+
+static int
+_long_press(void *data)
+{
+   Elm_Genlist_Item *it = data;
+
+   it->long_timer = NULL;
+   if ((it->disabled) || (it->dragging)) return 0;
+   it->wd->longpressed = EINA_TRUE;
+   evas_object_smart_callback_call(it->wd->obj, "longpressed", it);
+   return 0;
+}
+
+static void
+_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Elm_Genlist_Item *it = data;
+   Evas_Event_Mouse_Down *ev = event_info;
+   Evas_Coord x, y;
+
+   if (ev->button != 1) return;
+   it->down = 1;
+   it->dragging  = 0;
+   evas_object_geometry_get(obj, &x, &y, NULL, NULL);
+   it->dx = ev->canvas.x - x;
+   it->dy = ev->canvas.y - y;
+   it->wd->longpressed = EINA_FALSE;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
+   else it->wd->on_hold = EINA_FALSE;
+   it->wd->wasselected = it->selected;
+   _item_hilight(it);
+   if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
+     evas_object_smart_callback_call(it->wd->obj, "clicked", it);
+   if (it->long_timer) ecore_timer_del(it->long_timer);
+   if (it->realized)
+     it->long_timer = ecore_timer_add(1.0, _long_press, it);
+   else
+     it->long_timer = NULL;
+}
+
+static void
+_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Elm_Genlist_Item *it = data;
+   Evas_Event_Mouse_Up *ev = event_info;
+   Eina_Bool dragged = 0;
+
+   if (ev->button != 1) return;
+   it->down = 0;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
+   else it->wd->on_hold = EINA_FALSE;
+   if (it->long_timer)
+     {
+        ecore_timer_del(it->long_timer);
+        it->long_timer = NULL;
+     }
+   if (it->dragging)
+     {
+        it->dragging = 0;
+        evas_object_smart_callback_call(it->wd->obj, "drag,stop", it);
+        dragged = 1;
+     }
+   if (it->wd->on_hold)
+     {
+        it->wd->longpressed = EINA_FALSE;
+       it->wd->on_hold = EINA_FALSE;
+       return;
+     }
+   if (it->wd->longpressed)
+     {
+        it->wd->longpressed = EINA_FALSE;
+        if (!it->wd->wasselected)
+          _item_unselect(it);
+        it->wd->wasselected = 0;
+        return;
+     }
+   if (dragged)
+     {
+        if (it->want_unrealize)
+          {
+             _item_unrealize(it);
+             if (it->block->want_unrealize)
+               _item_block_unrealize(it->block);
+          }
+     }
+   if ((it->disabled) || (dragged)) return;
+   if (it->wd->multi)
+     {
+       if (!it->selected)
+         {
+            _item_hilight(it);
+            _item_select(it);
+         }
+       else _item_unselect(it);
+     }
+   else
+     {
+       if (!it->selected)
+         {
+            Widget_Data *wd = it->wd;
+             if (wd)
+               {
+                  while (wd->selected) _item_unselect(wd->selected->data);
+               }
+         }
+       else
+         {
+            const Eina_List *l, *l_next;
+            Elm_Genlist_Item *it2;
+
+            EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
+              if (it2 != it) _item_unselect(it2);
+//          _item_hilight(it);
+//          _item_select(it);
+         }
+        _item_hilight(it);
+        _item_select(it);
+     }
+}
+
+static void
+_signal_expand_toggle(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Elm_Genlist_Item *it = data;
+
+   if (it->expanded)
+     evas_object_smart_callback_call(it->wd->obj, "contract,request", it);
+   else
+     evas_object_smart_callback_call(it->wd->obj, "expand,request", it);
+}
+
+static void
+_signal_expand(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Elm_Genlist_Item *it = data;
+
+   if (!it->expanded)
+     evas_object_smart_callback_call(it->wd->obj, "expand,request", it);
+}
+
+static void
+_signal_contract(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Elm_Genlist_Item *it = data;
+
+   if (it->expanded)
+     evas_object_smart_callback_call(it->wd->obj, "contract,request", it);
+}
+
+static void
+_item_realize(Elm_Genlist_Item *it, int in, int calc)
+{
+   Elm_Genlist_Item *it2;
+   const char *stacking;
+   const char *treesize;
+   char buf[1024];
+   int depth, tsize = 20;
+
+   if ((it->realized) || (it->delete_me)) return;
+   it->base = edje_object_add(evas_object_evas_get(it->wd->obj));
+   edje_object_scale_set(it->base, elm_widget_scale_get(it->wd->obj) * 
+                         _elm_config->scale);
+   evas_object_smart_member_add(it->base, it->wd->pan_smart);
+   elm_widget_sub_object_add(it->wd->obj, it->base);
+
+   if (it->flags & ELM_GENLIST_ITEM_SUBITEMS) strncpy(buf, "tree", sizeof(buf));
+   else strncpy(buf, "item", sizeof(buf));
+   if (it->wd->compress) strncat(buf, "_compress", sizeof(buf) - strlen(buf));
+
+   if (in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
+   strncat(buf, "/", sizeof(buf) - strlen(buf));
+   strncat(buf, it->itc->item_style, sizeof(buf) - strlen(buf));
+   
+   _elm_theme_object_set(it->wd->obj, it->base, "genlist", buf, elm_widget_style_get(it->wd->obj));
+   it->spacer = evas_object_rectangle_add(evas_object_evas_get(it->wd->obj));
+   evas_object_color_set(it->spacer, 0, 0, 0, 0);
+   elm_widget_sub_object_add(it->wd->obj, it->spacer);
+   for (it2 = it, depth = 0; it2->parent; it2 = it2->parent) depth += 1;
+   treesize = edje_object_data_get(it->base, "treesize");
+   if (treesize) tsize = atoi(treesize);
+   evas_object_size_hint_min_set(it->spacer,
+                                 (depth * tsize) * _elm_config->scale, 1);
+   edje_object_part_swallow(it->base, "elm.swallow.pad", it->spacer);
+   if (!calc)
+     {
+       edje_object_signal_callback_add(it->base, "elm,action,expand,toggle",
+                                        "elm", _signal_expand_toggle, it);
+       edje_object_signal_callback_add(it->base, "elm,action,expand", "elm",
+                                        _signal_expand, it);
+       edje_object_signal_callback_add(it->base, "elm,action,contract",
+                                        "elm", _signal_contract, it);
+       stacking = edje_object_data_get(it->base, "stacking");
+       if (stacking)
+         {
+            if (!strcmp(stacking, "below")) evas_object_lower(it->base);
+            else if (!strcmp(stacking, "above")) evas_object_raise(it->base);
+         }
+       evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_DOWN,
+                                      _mouse_down, it);
+       evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_UP,
+                                      _mouse_up, it);
+       evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_MOVE,
+                                      _mouse_move, it);
+       if (it->selected)
+         edje_object_signal_emit(it->base, "elm,state,selected", "elm");
+       if (it->disabled)
+         edje_object_signal_emit(it->base, "elm,state,disabled", "elm");
+       if (it->expanded)
+         edje_object_signal_emit(it->base, "elm,state,expanded", "elm");
+     }
+
+   if (calc && it->wd->homogeneous && it->wd->item_width)
+     {
+       /* homogenous genlist shortcut */
+       if (!it->mincalcd)
+         {
+            it->w = it->minw = it->wd->item_width;
+            it->h = it->minh = it->wd->item_height;
+            it->mincalcd = EINA_TRUE;
+         }
+     }
+   else
+     {
+       if (it->itc->func.label_get)
+         {
+            const Eina_List *l;
+            const char *key;
+
+            it->labels = _elm_stringlist_get(edje_object_data_get(it->base, "labels"));
+            EINA_LIST_FOREACH(it->labels, l, key)
+              {
+                 char *s = it->itc->func.label_get(it->data, it->wd->obj, l->data);
+
+                 if (s)
+                   {
+                      edje_object_part_text_set(it->base, l->data, s);
+                      free(s);
+                   }
+              }
+         }
+       if (it->itc->func.icon_get)
+         {
+            const Eina_List *l;
+            const char *key;
+
+            it->icons = _elm_stringlist_get(edje_object_data_get(it->base, "icons"));
+            EINA_LIST_FOREACH(it->icons, l, key)
+              {
+                 Evas_Object *ic = it->itc->func.icon_get(it->data, it->wd->obj, l->data);
+
+                 if (ic)
+                   {
+                      it->icon_objs = eina_list_append(it->icon_objs, ic);
+                      edje_object_part_swallow(it->base, key, ic);
+                      evas_object_show(ic);
+                      elm_widget_sub_object_add(it->wd->obj, ic);
+                   }
+              }
+         }
+       if (it->itc->func.state_get)
+         {
+            const Eina_List *l;
+            const char *key;
+
+            it->states = _elm_stringlist_get(edje_object_data_get(it->base, "states"));
+            EINA_LIST_FOREACH(it->states, l, key)
+              {
+                 Eina_Bool on = it->itc->func.state_get(it->data, it->wd->obj, l->data);
+
+                 if (on)
+                   {
+                      snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
+                      edje_object_signal_emit(it->base, buf, "elm");
+                   }
+              }
+         }
+       if (!it->mincalcd)
+         {
+            Evas_Coord mw = -1, mh = -1;
+             
+             if (!it->display_only)
+               elm_coords_finger_size_adjust(1, &mw, 1, &mh);
+            edje_object_size_min_restricted_calc(it->base, &mw, &mh, mw, mh);
+             if (!it->display_only)
+               elm_coords_finger_size_adjust(1, &mw, 1, &mh);
+            it->w = it->minw = mw;
+            it->h = it->minh = mh;
+            it->mincalcd = EINA_TRUE;
+
+            if (in == 0 && it->wd->homogeneous)
+              {
+                 it->wd->item_width = mw;
+                 it->wd->item_height = mh;
+              }
+         }
+       if (!calc) evas_object_show(it->base);
+     }
+   it->realized = EINA_TRUE;
+   it->want_unrealize = EINA_FALSE;
+}
+
+static void
+_item_unrealize(Elm_Genlist_Item *it)
+{
+   Evas_Object *icon;
+
+   if (!it->realized) return;
+   if (it->long_timer)
+     {
+       ecore_timer_del(it->long_timer);
+       it->long_timer = NULL;
+     }
+   evas_object_del(it->base);
+   it->base = NULL;
+   evas_object_del(it->spacer);
+   it->spacer = NULL;
+   _elm_stringlist_free(it->labels);
+   it->labels = NULL;
+   _elm_stringlist_free(it->icons);
+   it->icons = NULL;
+   _elm_stringlist_free(it->states);
+
+   EINA_LIST_FREE(it->icon_objs, icon) 
+     evas_object_del(icon);
+
+   it->states = NULL;
+   it->realized = EINA_FALSE;
+   it->want_unrealize = EINA_FALSE;
+}
+
+static int
+_item_block_recalc(Item_Block *itb, int in, int qadd, int norender)
+{
+   const Eina_List *l;
+   Elm_Genlist_Item *it;
+   Evas_Coord minw = 0, minh = 0;
+   int showme = 0, changed = 0;
+   Evas_Coord y = 0;
+
+   itb->num = in;
+   EINA_LIST_FOREACH(itb->items, l, it)
+     {
+       if (it->delete_me) continue;
+       showme |= it->showme;
+       if (!itb->realized)
+         {
+             if (qadd)
+               {
+                  if (!it->mincalcd) changed = 1;
+                  if (changed)
+                    {
+                       _item_realize(it, in, 1);
+                       _item_unrealize(it);
+                    }
+               }
+             else
+               {
+                  _item_realize(it, in, 1);
+                  _item_unrealize(it);
+               }
+         }
+       else
+          {
+             Eina_Bool was_realized = it->realized;
+
+             _item_realize(it, in, 0);
+             if (!was_realized)
+               evas_object_smart_callback_call(it->wd->obj, "realized", it);
+          }
+       minh += it->minh;
+       if (minw < it->minw) minw = it->minw;
+       in++;
+       it->x = 0;
+       it->y = y;
+       y += it->h;
+     }
+   itb->minw = minw;
+   itb->minh = minh;
+   itb->changed = EINA_FALSE;
+   /* force an evas norender to garbage collect deleted objects */
+   if (norender) evas_norender(evas_object_evas_get(itb->wd->obj));
+   return showme;
+}
+
+static void
+_item_block_realize(Item_Block *itb, int in, int full)
+{
+   const Eina_List *l;
+   Elm_Genlist_Item *it;
+
+   if (itb->realized) return;
+   EINA_LIST_FOREACH(itb->items, l, it)
+     {
+       if (it->delete_me) continue;
+       if (full)
+          {
+             Eina_Bool was_realized = it->realized;
+
+             _item_realize(it, in, 0);
+             if (!was_realized)
+               evas_object_smart_callback_call(it->wd->obj, "realized", it);
+          }
+       in++;
+     }
+   itb->realized = EINA_TRUE;
+   itb->want_unrealize = EINA_FALSE;
+}
+
+static void
+_item_block_unrealize(Item_Block *itb)
+{
+   const Eina_List *l;
+   Elm_Genlist_Item *it;
+   int dragging = 0;
+
+   if (!itb->realized) return;
+   EINA_LIST_FOREACH(itb->items, l, it)
+     {
+        if (it->dragging)
+          {
+             dragging = 1;
+             it->want_unrealize = EINA_TRUE;
+          }
+        else
+          _item_unrealize(it);
+     }
+   if (!dragging)
+     {
+        itb->realized = EINA_FALSE;
+        itb->want_unrealize = EINA_TRUE;
+     }
+   else
+     itb->want_unrealize = EINA_FALSE;
+}
+
+static void
+_item_block_position(Item_Block *itb, int in)
+{
+   const Eina_List *l;
+   Elm_Genlist_Item *it;
+   Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
+   int vis;
+
+   evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
+   evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy, &cvw, &cvh);
+   EINA_LIST_FOREACH(itb->items, l, it)
+     {
+       if (it->delete_me) continue;
+       it->x = 0;
+       it->y = y;
+       it->w = itb->w;
+       vis = (ELM_RECTS_INTERSECT(itb->x - it->wd->pan_x + ox,
+                                   itb->y - it->wd->pan_y + oy,
+                                   itb->w, itb->h,
+                                   cvx, cvy, cvw, cvh));
+       if ((itb->realized) && (!it->realized))
+         {
+            if (vis)
+               {
+                  Eina_Bool was_realized = it->realized;
+
+                  _item_realize(it, in, 0);
+                  if (!was_realized)
+                    evas_object_smart_callback_call(it->wd->obj, 
+                                                    "realized", it);
+               }
+         }
+       if (it->realized)
+         {
+            if (vis)
+              {
+                 evas_object_resize(it->base, it->w, it->h);
+                 evas_object_move(it->base,
+                                  ox + itb->x + it->x - itb->wd->pan_x,
+                                  oy + itb->y + it->y - itb->wd->pan_y);
+                 evas_object_show(it->base);
+              }
+            else
+               {
+                  if (!it->dragging)
+                    _item_unrealize(it);
+               }
+         }
+       y += it->h;
+       in++;
+     }
+}
+
+static void
+_calc_job(void *data)
+{
+   Widget_Data *wd = data;
+   Item_Block *itb;
+   Evas_Coord minw = -1, minh = 0, y = 0, ow, oh;
+   Item_Block *chb = NULL;
+   int in = 0, minw_change = 0;
+   if (!wd) return;
+   EINA_INLIST_FOREACH(wd->blocks, itb)
+     {
+       int showme = 0;
+
+        itb->num = in;
+        showme = itb->showme;
+        itb->showme = 0;
+       if (chb)
+         {
+            if (itb->realized) _item_block_unrealize(itb);
+         }
+       if (itb->changed)
+         {
+            if (itb->realized) _item_block_unrealize(itb);
+            showme = _item_block_recalc(itb, in, 0, 1);
+            chb = itb;
+         }
+       itb->y = y;
+       itb->x = 0;
+       minh += itb->minh;
+       if (minw == -1) minw = itb->minw;
+       else if (minw < itb->minw)
+         {
+            minw = itb->minw;
+            minw_change = 1;
+         }
+       itb->w = minw;
+       itb->h = itb->minh;
+       y += itb->h;
+       in += itb->count;
+       if (showme)
+         {
+            wd->show_item->showme = 0;
+             if (wd->bring_in)
+               elm_smart_scroller_region_bring_in(wd->scr,
+                                                  wd->show_item->x + wd->show_item->block->x,
+                                                  wd->show_item->y + wd->show_item->block->y,
+                                                  wd->show_item->block->w,
+                                                  wd->show_item->h);
+             else
+               elm_smart_scroller_child_region_show(wd->scr,
+                                                    wd->show_item->x + wd->show_item->block->x,
+                                                    wd->show_item->y + wd->show_item->block->y,
+                                                    wd->show_item->block->w,
+                                                    wd->show_item->h);
+            wd->show_item = NULL;
+            showme = 0;
+         }
+     }
+   if (minw_change)
+     {
+       EINA_INLIST_FOREACH(wd->blocks, itb)
+         {
+            itb->minw = minw;
+            itb->w = itb->minw;
+         }
+     }
+   if ((chb) && (EINA_INLIST_GET(chb)->next))
+     {
+       EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
+         if (itb->realized) _item_block_unrealize(itb);
+     }
+   evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
+   if (minw < ow) minw = ow;
+   if ((minw != wd->minw) || (minh != wd->minh))
+     {
+       wd->minw = minw;
+       wd->minh = minh;
+       evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
+       _sizing_eval(wd->obj);
+     }
+   wd->calc_job = NULL;
+   evas_object_smart_changed(wd->pan_smart);
+}
+
+static void
+_update_job(void *data)
+{
+   Widget_Data *wd = data;
+   Eina_List *l2;
+   Item_Block *itb;
+   int num, num0, position = 0, recalc = 0;
+   if (!wd) return;
+   wd->update_job = NULL;
+   num = 0;
+   EINA_INLIST_FOREACH(wd->blocks, itb)
+     {
+        Evas_Coord itminw, itminh;
+        Elm_Genlist_Item *it;
+
+        if (!itb->updateme)
+          {
+             num += itb->count;
+             if (position)
+               _item_block_position(itb, num);
+             continue;
+          }
+        num0 = num;
+        recalc = 0;
+        EINA_LIST_FOREACH(itb->items, l2, it)
+          {
+             if (it->updateme)
+               {
+                  itminw = it->w;
+                  itminh = it->h;
+
+                  it->updateme = 0;
+                  if (it->realized)
+                    {
+                       _item_unrealize(it);
+                       _item_realize(it, num, 0);
+                       evas_object_smart_callback_call(it->wd->obj, 
+                                                       "realized", it);
+                    }
+                  else
+                    {
+                       _item_realize(it, num, 1);
+                       _item_unrealize(it);
+                    }
+                  if ((it->minw != itminw) || (it->minh != itminh))
+                    recalc = 1;
+               }
+             num++;
+          }
+        itb->updateme = 0;
+        if (recalc)
+          {
+             position = 1;
+             itb->changed = EINA_TRUE;
+             _item_block_recalc(itb, num0, 0, 1);
+             _item_block_position(itb, num0);
+          }
+     }
+   if (position)
+     {
+       if (wd->calc_job) ecore_job_del(wd->calc_job);
+       wd->calc_job = ecore_job_add(_calc_job, wd);
+     }
+}
+
+static void
+_pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+//   Evas_Coord ow, oh;
+//   evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
+//   ow = sd->wd->minw - ow;
+//   if (ow < 0) ow = 0;
+//   oh = sd->wd->minh - oh;
+//   if (oh < 0) oh = 0;
+//   if (x < 0) x = 0;
+//   if (y < 0) y = 0;
+//   if (x > ow) x = ow;
+//   if (y > oh) y = oh;
+   if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
+   sd->wd->pan_x = x;
+   sd->wd->pan_y = y;
+   evas_object_smart_changed(obj);
+}
+
+static void
+_pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+
+   if (x) *x = sd->wd->pan_x;
+   if (y) *y = sd->wd->pan_y;
+}
+
+static void
+_pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   Evas_Coord ow, oh;
+
+   evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
+   ow = sd->wd->minw - ow;
+   if (ow < 0) ow = 0;
+   oh = sd->wd->minh - oh;
+   if (oh < 0) oh = 0;
+   if (x) *x = ow;
+   if (y) *y = oh;
+}
+
+static void
+_pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+
+   if (w) *w = sd->wd->minw;
+   if (h) *h = sd->wd->minh;
+}
+
+static void
+_pan_add(Evas_Object *obj)
+{
+   Pan *sd;
+   Evas_Object_Smart_Clipped_Data *cd;
+
+   _pan_sc.add(obj);
+   cd = evas_object_smart_data_get(obj);
+   sd = ELM_NEW(Pan);
+   if (!sd) return;
+   sd->__clipped_data = *cd;
+   free(cd);
+   evas_object_smart_data_set(obj, sd);
+}
+
+static void
+_pan_del(Evas_Object *obj)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+
+   if (!sd) return;
+   _pan_sc.del(obj);
+}
+
+static void
+_pan_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   Evas_Coord ow, oh;
+
+   evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
+   if ((ow == w) && (oh == h)) return;
+   if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
+   sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
+}
+
+static void
+_pan_calculate(Evas_Object *obj)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   Item_Block *itb;
+   Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
+   int in = 0;
+
+   evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
+   evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
+   EINA_INLIST_FOREACH(sd->wd->blocks, itb)
+     {
+       itb->w = sd->wd->minw;
+       if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
+                               itb->y - sd->wd->pan_y + oy,
+                               itb->w, itb->h,
+                               cvx, cvy, cvw, cvh))
+         {
+            if ((!itb->realized) || (itb->changed))
+               _item_block_realize(itb, in, 0);
+            _item_block_position(itb,  in);
+         }
+       else
+         {
+            if (itb->realized) _item_block_unrealize(itb);
+         }
+       in += itb->count;
+     }
+}
+
+static void
+_pan_move(Evas_Object *obj, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+
+   if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
+   sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
+}
+
+static void
+_hold_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_hold_set(wd->scr, 1);
+}
+
+static void
+_hold_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_hold_set(wd->scr, 0);
+}
+
+static void
+_freeze_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_freeze_set(wd->scr, 1);
+}
+
+static void
+_freeze_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_freeze_set(wd->scr, 0);
+}
+
+/**
+ * Add a new Genlist object
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Genlist
+ */
+EAPI Evas_Object *
+elm_genlist_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+   Evas_Coord minw, minh;
+   static Evas_Smart *smart = NULL;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "genlist");
+   elm_widget_type_set(obj, "genlist");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_del_pre_hook_set(obj, _del_pre_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   wd->scr = elm_smart_scroller_add(e);
+   elm_smart_scroller_widget_set(wd->scr, obj);
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base", elm_widget_style_get(obj));
+   elm_widget_resize_object_set(obj, wd->scr);
+
+   elm_smart_scroller_bounce_allow_set(wd->scr, 0, 1);
+
+   wd->obj = obj;
+   wd->mode = ELM_LIST_SCROLL;
+   wd->max_items_per_block = 32;
+
+   evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
+   evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
+   evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
+   evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
+
+   if (!smart)
+     {
+       static Evas_Smart_Class sc;
+
+       evas_object_smart_clipped_smart_set(&_pan_sc);
+       sc = _pan_sc;
+       sc.name = "elm_genlist_pan";
+       sc.version = EVAS_SMART_CLASS_VERSION;
+       sc.add = _pan_add;
+       sc.del = _pan_del;
+       sc.resize = _pan_resize;
+       sc.move = _pan_move;
+       sc.calculate = _pan_calculate;
+       smart = evas_smart_class_new(&sc);
+     }
+   if (smart)
+     {
+       wd->pan_smart = evas_object_smart_add(e, smart);
+       wd->pan = evas_object_smart_data_get(wd->pan_smart);
+       wd->pan->wd = wd;
+     }
+
+   elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
+                                    _pan_set, _pan_get,
+                                    _pan_max_get, _pan_child_size_get);
+
+   edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
+                             &minw, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+static Elm_Genlist_Item *
+_item_new(Widget_Data *wd, const Elm_Genlist_Item_Class *itc,
+         const void *data, Elm_Genlist_Item *parent,
+         Elm_Genlist_Item_Flags flags,
+         Evas_Smart_Cb func,
+          const void *func_data)
+{
+   Elm_Genlist_Item *it;
+
+   it = calloc(1, sizeof(Elm_Genlist_Item));
+   if (!it) return NULL;
+   it->wd = wd;
+   it->itc = itc;
+   it->data = data;
+   it->parent = parent;
+   it->flags = flags;
+   it->func.func = func;
+   it->func.data = func_data;
+   return it;
+}
+
+static void
+_item_block_add(Widget_Data *wd, Elm_Genlist_Item *it)
+{
+   Item_Block *itb = NULL;
+
+   if (!it->rel)
+     {
+       newblock:
+       if (it->rel)
+         {
+            itb = calloc(1, sizeof(Item_Block));
+            if (!itb) return;
+            itb->wd = wd;
+            if (!it->rel->block)
+              {
+                 wd->blocks = 
+                    eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
+                 itb->items = eina_list_append(itb->items, it);
+              }
+            else
+              {
+                 if (it->before)
+                   {
+                      wd->blocks = 
+                         eina_inlist_prepend_relative(wd->blocks, 
+                                                      EINA_INLIST_GET(itb), 
+                                                      EINA_INLIST_GET(it->rel->block));
+                      itb->items = 
+                         eina_list_prepend_relative(itb->items, it, it->rel);
+                   }
+                 else
+                   {
+                      wd->blocks = 
+                         eina_inlist_append_relative(wd->blocks, 
+                                                     EINA_INLIST_GET(itb), 
+                                                     EINA_INLIST_GET(it->rel->block));
+                      itb->items = 
+                         eina_list_append_relative(itb->items, it, it->rel);
+                   }
+              }
+         }
+       else
+         {
+            if (it->before)
+              {
+                 if (wd->blocks)
+                   {
+                      itb = (Item_Block *)(wd->blocks);
+                      if (itb->count >= wd->max_items_per_block)
+                        {
+                           itb = calloc(1, sizeof(Item_Block));
+                           if (!itb) return;
+                           itb->wd = wd;
+                           wd->blocks = 
+                              eina_inlist_prepend(wd->blocks, 
+                                                  EINA_INLIST_GET(itb));
+                        }
+                   }
+                 else
+                   {
+                      itb = calloc(1, sizeof(Item_Block));
+                      if (!itb) return;
+                      itb->wd = wd;
+                      wd->blocks = 
+                         eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
+                   }
+                 itb->items = eina_list_prepend(itb->items, it);
+              }
+            else
+              {
+                 if (wd->blocks)
+                   {
+                      itb = (Item_Block *)(wd->blocks->last);
+                      if (itb->count >= wd->max_items_per_block)
+                        {
+                           itb = calloc(1, sizeof(Item_Block));
+                           if (!itb) return;
+                           itb->wd = wd;
+                           wd->blocks = 
+                              eina_inlist_append(wd->blocks, 
+                                                 EINA_INLIST_GET(itb));
+                        }
+                   }
+                 else
+                   {
+                      itb = calloc(1, sizeof(Item_Block));
+                      if (!itb) return;
+                      itb->wd = wd;
+                      wd->blocks = 
+                         eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
+                   }
+                 itb->items = eina_list_append(itb->items, it);
+              }
+         }
+     }
+   else
+     {
+       itb = it->rel->block;
+       if (!itb) goto newblock;
+       if (it->before)
+         itb->items = eina_list_prepend_relative(itb->items, it, it->rel);
+       else
+         itb->items = eina_list_append_relative(itb->items, it, it->rel);
+     }
+   itb->count++;
+   itb->changed = EINA_TRUE;
+   it->block = itb;
+   if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
+   itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
+   if (it->rel)
+     {
+       it->rel->relcount--;
+       if ((it->rel->delete_me) && (it->rel->relcount == 0))
+         _item_del(it->rel);
+       it->rel = NULL;
+     }
+   if (itb->count > itb->wd->max_items_per_block)
+     {
+        int newc;
+        Item_Block *itb2;
+        Elm_Genlist_Item *it2;
+
+        newc = itb->count / 2;
+        itb2 = calloc(1, sizeof(Item_Block));
+        if (!itb2) return;
+        itb2->wd = wd;
+        wd->blocks = 
+          eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2), 
+                                      EINA_INLIST_GET(itb));
+        itb2->changed = EINA_TRUE;
+        while ((itb->count > newc) && (itb->items))
+          {
+             Eina_List *l;
+
+             l = eina_list_last(itb->items);
+             it2 = l->data;
+             itb->items = eina_list_remove_list(itb->items, l);
+             itb->count--;
+
+             itb2->items = eina_list_prepend(itb2->items, it2);
+             it2->block = itb2;
+             itb2->count++;
+          }
+     }
+}
+
+static int
+_queue_proecess(Widget_Data *wd, int norender)
+{
+   int n, showme = 0;
+   double t0, t;
+
+   t0 = ecore_time_get();
+   for (n = 0; (wd->queue) && (n < 128); n++)
+     {
+       Elm_Genlist_Item *it;
+
+       it = wd->queue->data;
+       wd->queue = eina_list_remove_list(wd->queue, wd->queue);
+       it->queued = EINA_FALSE;
+       _item_block_add(wd, it);
+        t = ecore_time_get();
+        if (it->block->changed)
+          {
+             showme = _item_block_recalc(it->block, it->block->num, 1, norender);
+             it->block->changed = 0;
+          }
+        if (showme) it->block->showme = 1;
+        if (eina_inlist_count(wd->blocks) > 1)
+          {
+             if ((t - t0) > (ecore_animator_frametime_get())) break;
+          }
+     }
+   return n;
+}
+
+static int
+_item_idler(void *data)
+{
+   Widget_Data *wd = data;
+   
+   if (_queue_proecess(wd, 1) > 0)
+     {
+       if (wd->calc_job) ecore_job_del(wd->calc_job);
+       wd->calc_job = ecore_job_add(_calc_job, wd);
+     }
+   if (!wd->queue)
+     {
+       wd->queue_idler = NULL;
+       return 0;
+     }
+   return 1;
+}
+
+static void
+_item_queue(Widget_Data *wd, Elm_Genlist_Item *it)
+{
+   if (it->queued) return;
+   it->queued = EINA_TRUE;
+   wd->queue = eina_list_append(wd->queue, it);
+   while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
+     {
+        if (wd->queue_idler)
+          {
+             ecore_idler_del(wd->queue_idler);
+             wd->queue_idler = NULL;
+          }
+        _queue_proecess(wd, 0);
+     }
+   if (!wd->queue_idler) wd->queue_idler = ecore_idler_add(_item_idler, wd);
+}
+
+/**
+ * Append item to the end of the genlist
+ *
+ * This appends the given item to the end of the list or the end of the
+ * children if the parent is given.
+ *
+ * @param obj The genlist object
+ * @param itc The item class for the item
+ * @param data The item data
+ * @param parent The parent item, or NULL if none
+ * @param flags Item flags
+ * @param func Convenience function called when item selected
+ * @param func_data Data passed to @p func above.
+ * @return A handle to the item added or NULL if not possible
+ *
+ * @ingroup Genlist
+ */
+EAPI Elm_Genlist_Item *
+elm_genlist_item_append(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
+                       const void *data, Elm_Genlist_Item *parent,
+                       Elm_Genlist_Item_Flags flags,
+                       Evas_Smart_Cb func, const void *func_data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_Genlist_Item *it = _item_new(wd, itc, data, parent, flags, func, func_data);
+   if (!wd) return NULL;
+   if (!it) return NULL;
+   if (!it->parent)
+     {
+       wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
+       it->rel = NULL;
+       it->before = 0;
+     }
+   else
+     {
+       Elm_Genlist_Item *it2 = NULL;
+       Eina_List *ll = eina_list_last(it->parent->items);
+       if (ll) it2 = ll->data;
+       it->parent->items = eina_list_append(it->parent->items, it);
+       if (!it2) it2 = it->parent;
+       wd->items = 
+          eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), 
+                                      EINA_INLIST_GET(it2));
+       it->rel = it2;
+       it->rel->relcount++;
+       it->before = 0;
+     }
+   _item_queue(wd, it);
+   return it;
+}
+
+/**
+ * Prepend item at start of the genlist
+ *
+ * This adds an item to the beginning of the list or beginning of the children
+ * of the parent if given.
+ *
+ * @param obj The genlist object
+ * @param itc The item class for the item
+ * @param data The item data
+ * @param parent The parent item, or NULL if none
+ * @param flags Item flags
+ * @param func Convenience function called when item selected
+ * @param func_data Data passed to @p func above.
+ * @return A handle to the item added or NULL if not possible
+ *
+ * @ingroup Genlist
+ */
+EAPI Elm_Genlist_Item *
+elm_genlist_item_prepend(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
+                        const void *data, Elm_Genlist_Item *parent,
+                        Elm_Genlist_Item_Flags flags,
+                        Evas_Smart_Cb func, const void *func_data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_Genlist_Item *it = _item_new(wd, itc, data, parent, flags, func, func_data);
+   if (!wd) return NULL;
+   if (!it) return NULL;
+   if (!it->parent)
+     wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
+   else
+     {
+       printf("FIXME: 12 tree not handled yet\n");
+     }
+   it->rel = NULL;
+   it->before = 1;
+   _item_queue(wd, it);
+   return it;
+}
+
+/**
+ * Insert item before another in the genlist
+ *
+ * This inserts an item before another in the list. It will be in the same tree
+ * level as the item it is inseted before.
+ *
+ * @param obj The genlist object
+ * @param itc The item class for the item
+ * @param data The item data
+ * @param before The item to insert before
+ * @param flags Item flags
+ * @param func Convenience function called when item selected
+ * @param func_data Data passed to @p func above.
+ * @return A handle to the item added or NULL if not possible
+ *
+ * @ingroup Genlist
+ */
+EAPI Elm_Genlist_Item *
+elm_genlist_item_insert_before(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
+                              const void *data, Elm_Genlist_Item *before,
+                              Elm_Genlist_Item_Flags flags,
+                              Evas_Smart_Cb func, const void *func_data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_Genlist_Item *it = _item_new(wd, itc, data, NULL, flags, func, func_data);
+   if (!wd) return NULL;
+   if (!it) return NULL;
+   if (!it->parent)
+     wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), 
+                                              EINA_INLIST_GET(before));
+   else
+     {
+       printf("FIXME: 13 tree not handled yet\n");
+     }
+   it->rel = before;
+   it->rel->relcount++;
+   it->before = 1;
+   _item_queue(wd, it);
+   return it;
+}
+
+/**
+ * Insert and item after another in the genlst
+ *
+ * This inserts an item after another in the list. It will be in the same tree
+ * level as the item it is inseted after.
+ *
+ * @param obj The genlist object
+ * @param itc The item class for the item
+ * @param data The item data
+ * @param after The item to insert after
+ * @param flags Item flags
+ * @param func Convenience function called when item selected
+ * @param func_data Data passed to @p func above.
+ * @return A handle to the item added or NULL if not possible
+ *
+ * @ingroup Genlist
+ */
+EAPI Elm_Genlist_Item *
+elm_genlist_item_insert_after(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
+                             const void *data, Elm_Genlist_Item *after,
+                             Elm_Genlist_Item_Flags flags,
+                             Evas_Smart_Cb func, const void *func_data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_Genlist_Item *it = _item_new(wd, itc, data, NULL, flags, func, func_data);
+   if (!wd) return NULL;
+   if (!it) return NULL;
+   if (!it->parent)
+     wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), 
+                                             EINA_INLIST_GET(after));
+   else
+     {
+       printf("FIXME: 14 tree not handled yet\n");
+     }
+   it->rel = after;
+   it->rel->relcount++;
+   it->before = 0;
+   _item_queue(wd, it);
+   return it;
+}
+
+/**
+ * Clear the genlist
+ *
+ * This clears all items in the list, leaving it empty.
+ *
+ * @param obj The genlist object
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_clear(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   while (wd->items)
+     {
+       Elm_Genlist_Item *it = (Elm_Genlist_Item *)(wd->items);
+
+       wd->items = eina_inlist_remove(wd->items, wd->items);
+       if (it->realized) _item_unrealize(it);
+       if (it->itc->func.del) it->itc->func.del(it->data, it->wd->obj);
+       if (it->long_timer) ecore_timer_del(it->long_timer);
+       free(it);
+     }
+   while (wd->blocks)
+     {
+       Item_Block *itb = (Item_Block *)(wd->blocks);
+
+       wd->blocks = eina_inlist_remove(wd->blocks, wd->blocks);
+       if (itb->items) eina_list_free(itb->items);
+       free(itb);
+     }
+   if (wd->calc_job)
+     {
+       ecore_job_del(wd->calc_job);
+       wd->calc_job = NULL;
+     }
+   if (wd->queue_idler)
+     {
+       ecore_idler_del(wd->queue_idler);
+       wd->queue_idler = NULL;
+     }
+   if (wd->queue)
+     {
+       eina_list_free(wd->queue);
+       wd->queue = NULL;
+     }
+   if (wd->selected)
+     {
+       eina_list_free(wd->selected);
+       wd->selected = NULL;
+     }
+   wd->show_item = NULL;
+   wd->pan_x = 0;
+   wd->pan_y = 0;
+   wd->minw = 0;
+   wd->minh = 0;
+   evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
+   evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
+   _sizing_eval(obj);
+}
+
+/**
+ * Enable or disable multi-select in the genlist
+ *
+ * This enables (EINA_TRUE) or disableds (EINA_FALSE) multi-select in the list. This allows
+ * more than 1 item to be selected.
+ *
+ * @param obj The genlist object
+ * @param multi Multi-select enable/disable
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_multi_select_set(Evas_Object *obj, Eina_Bool multi)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->multi = multi;
+}
+
+/**
+ * Gets if multi-select in genlist is enable or disable
+ *
+ * @param obj The genlist object
+ * @return Multi-select enable/disable
+ * (EINA_TRUE = enabled/EINA_FALSE = disabled)
+ *
+ * @ingroup Genlist
+ */
+EAPI Eina_Bool
+elm_genlist_multi_select_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->multi;
+}
+
+
+/**
+ * Get the selectd item in the genlist
+ *
+ * This gets the selected item in the list (if multi-select is enabled only
+ * the first item in the list is selected - which is not very useful, so see
+ * elm_genlist_selected_items_get()for when multi-select is used).
+ *
+ * If no item is selected, NULL is returned.
+ *
+ * @param obj The genlist object
+ * @return The selected item, or NULL if none.
+ *
+ * @ingroup Genlist
+ */
+EAPI Elm_Genlist_Item *
+elm_genlist_selected_item_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   if (wd->selected) return wd->selected->data;
+   return NULL;
+}
+
+/**
+ * Get a list of selected items in the genlist
+ *
+ * This retgurns a list of the selected items. This list pointer is only valid
+ * so long as no items are selected or unselected (or unselected implicitly
+ * by deletion). The list contains Elm_Genlist_Item pointers.
+ *
+ * @param obj The genlist object
+ * @return The list of selected items, nor NULL if none are selected.
+ *
+ * @ingroup Genlist
+ */
+EAPI const Eina_List *
+elm_genlist_selected_items_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->selected;
+}
+
+/**
+ * Get a list of realized items in genlist
+ *
+ * This returns a list of the realized items in the genlist. The list
+ * contains Elm_Genlist_Item pointers. The list must be freed by the
+ * caller when done with eina_list_free(). The item pointers in the list
+ * are only vallid so long as those items are not deleted or the genlist is
+ * not deleted.
+ *
+ * @param obj The genlist object
+ * @return The list of realized items, nor NULL if none are realized.
+ *
+ * @ingroup Genlist
+ */
+EAPI Eina_List *
+elm_genlist_realized_items_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Eina_List *list = NULL;
+   Item_Block *itb;
+   Eina_Bool done = 0;
+   if (!wd) return NULL;
+   EINA_INLIST_FOREACH(wd->blocks, itb)
+     {
+       if (itb->realized)
+          {
+             Eina_List *l;
+             Elm_Genlist_Item *it;
+             
+             done = 1;
+             EINA_LIST_FOREACH(itb->items, l, it)
+               {
+                  if (it->realized) list = eina_list_append(list, it);
+               }
+          }
+        else
+          {
+             if (done) break;
+          }
+     }
+   return list;
+}
+
+/**
+ * Get the item that is at the x, y canvas coords
+ *
+ * This returns the item at the given coordinates (which are canvas relative
+ * not object-relative). If an item is at that coordinate, that item handle
+ * is returned, and if @p posret is not NULL, the integer pointed to is set
+ * to a value of -1, 0 or 1, depending if the coordinate is on the upper
+ * portion of that item (-1), on the middle section (0) or on the lower part
+ * (1). If NULL is returned as an item (no item found there), then posret
+ * may indicate -1 or 1 based if the coordinate is above or below all items
+ * respectively in the genlist.
+ *
+ * @param it The item
+ * @param x The input x coordinate
+ * @param y The input y coordinate
+ * @param posret The position relative to the item returned here
+ * @return The item at the coordinates or NULL if none
+ *
+ * @ingroup Genlist
+ */
+EAPI Elm_Genlist_Item *
+elm_genlist_at_xy_item_get(const Evas_Object *obj, Evas_Coord x, Evas_Coord y, int *posret)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord ox, oy, ow, oh;
+   Item_Block *itb;
+   Evas_Coord lasty;
+   if (!wd) return NULL;
+   evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
+   lasty = oy;
+   EINA_INLIST_FOREACH(wd->blocks, itb)
+     {
+       Eina_List *l;
+       Elm_Genlist_Item *it;
+
+        if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
+                                 oy + itb->y - itb->wd->pan_y,
+                                 itb->w, itb->h, x, y, 1, 1))
+          continue;
+       EINA_LIST_FOREACH(itb->items, l, it)
+         {
+             Evas_Coord itx, ity;
+
+             itx = ox + itb->x + it->x - itb->wd->pan_x;
+             ity = oy + itb->y + it->y - itb->wd->pan_y;
+             if (ELM_RECTS_INTERSECT(itx, ity, it->w, it->h, x, y, 1, 1))
+               {
+                  if (posret)
+                    {
+                       if (y <= (ity + (it->h / 4))) *posret = -1;
+                       else if (y >= (ity + it->h - (it->h / 4))) *posret = 1;
+                       else *posret = 0;
+                    }
+                  return it;
+               }
+             lasty = ity + it->h;
+         }
+     }
+   if (posret)
+     {
+        if (y > lasty) *posret = 1;
+        else *posret = -1;
+     }
+   return NULL;
+}
+
+/**
+ * Get the first item in the genlist
+ *
+ * This returns the first item in the list.
+ *
+ * @param obj The genlist object
+ * @return The first item, or NULL if none
+ *
+ * @ingroup Genlist
+ */
+EAPI Elm_Genlist_Item *
+elm_genlist_first_item_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   if (!wd->items) return NULL;
+   Elm_Genlist_Item *it = (Elm_Genlist_Item *)(wd->items);
+   while ((it) && (it->delete_me))
+     it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->next);
+   return it;
+}
+
+/**
+ * Get the last item in the genlist
+ *
+ * This returns the last item in the list.
+ *
+ * @return The last item, or NULL if none
+ *
+ * @ingroup Genlist
+ */
+EAPI Elm_Genlist_Item *
+elm_genlist_last_item_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd->items) return NULL;
+   Elm_Genlist_Item *it = (Elm_Genlist_Item *)(wd->items->last);
+   if (!wd) return NULL;
+   while ((it) && (it->delete_me))
+     it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->prev);
+   return it;
+}
+
+/**
+ * Get the next item in the genlist
+ *
+ * This returns the item after the item @p it.
+ *
+ * @param it The item
+ * @return The item after @p it, or NULL if none
+ *
+ * @ingroup Genlist
+ */
+EAPI Elm_Genlist_Item *
+elm_genlist_item_next_get(const Elm_Genlist_Item *it)
+{
+   while (it)
+     {
+       it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->next);
+       if ((it) && (!it->delete_me)) break;
+     }
+   return (Elm_Genlist_Item *)it;
+}
+
+/**
+ * Get the previous item in the genlist
+ *
+ * This returns the item before the item @p it.
+ *
+ * @param it The item
+ * @return The item before @p it, or NULL if none
+ *
+ * @ingroup Genlist
+ */
+EAPI Elm_Genlist_Item *
+elm_genlist_item_prev_get(const Elm_Genlist_Item *it)
+{
+   while (it)
+     {
+       it = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->prev);
+       if ((it) && (!it->delete_me)) break;
+     }
+   return (Elm_Genlist_Item *)it;
+}
+
+/**
+ * Get the genlist object from an item
+ *
+ * This returns the genlist object itself that an item belongs to.
+ *
+ * @param it The item
+ * @return The genlist object
+ *
+ * @ingroup Genlist
+ */
+EAPI Evas_Object *
+elm_genlist_item_genlist_get(const Elm_Genlist_Item *it)
+{
+   if (!it) return NULL;
+   return it->wd->obj;
+}
+
+/**
+ * Get the parent item of the given item
+ *
+ * This returns the prent item of the item @p it given.
+ *
+ * @param it The item
+ * @return The parent of the item or NULL if none
+ *
+ * @ingroup Genlist
+ */
+EAPI Elm_Genlist_Item *
+elm_genlist_item_parent_get(const Elm_Genlist_Item *it)
+{
+   if (!it) return NULL;
+   return it->parent;
+}
+
+/**
+ * Clear all sub-items (children) of the given item
+ *
+ * This clears all items that are children (or their descendants) of the
+ * given item @p it.
+ *
+ * @param it The item
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_item_subitems_clear(Elm_Genlist_Item *it)
+{
+   Eina_List *tl = NULL, *l;
+   Elm_Genlist_Item *it2;
+
+   if (!it) return;
+   EINA_LIST_FOREACH(it->items, l, it2)
+     tl = eina_list_append(tl, it2);
+   EINA_LIST_FREE(tl, it2)
+     elm_genlist_item_del(it2);
+}
+
+/**
+ * Set the selected state of an item
+ *
+ * This sets the selected state (1 selected, 0 not selected) of the given
+ * item @p it.
+ *
+ * @param it The item
+ * @param selected The slected state
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_item_selected_set(Elm_Genlist_Item *it, Eina_Bool selected)
+{
+   Widget_Data *wd = elm_widget_data_get(it->wd->obj);
+   if (!wd) return;
+   if (!it) return;
+   if (it->delete_me) return;
+   selected = !!selected;
+   if (it->selected == selected) return;
+
+   if (selected)
+     {
+       if (!wd->multi)
+         {
+            while (wd->selected)
+              _item_unselect(wd->selected->data);
+         }
+       _item_hilight(it);
+       _item_select(it);
+     }
+   else
+     _item_unselect(it);
+}
+
+/**
+ * Get the selected state of an item
+ *
+ * This gets the selected state of an item (1 selected, 0 not selected).
+ *
+ * @param it The item
+ * @return The selected state
+ *
+ * @ingroup Genlist
+ */
+EAPI Eina_Bool
+elm_genlist_item_selected_get(const Elm_Genlist_Item *it)
+{
+   if (!it) return EINA_FALSE;
+   return it->selected;
+}
+
+/**
+ * Sets the expanded state of an item (if it's a parent)
+ *
+ * This expands or contracts a parent iterm (thus showing or hiding the
+ * children).
+ *
+ * @param it The item
+ * @param expanded The expanded state (1 expanded, 0 not expanded).
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_item_expanded_set(Elm_Genlist_Item *it, Eina_Bool expanded)
+{
+   if (!it) return;
+   if (it->expanded == expanded) return;
+   it->expanded = expanded;
+   if (it->expanded)
+     {
+       if (it->realized)
+         edje_object_signal_emit(it->base, "elm,state,expanded", "elm");
+       evas_object_smart_callback_call(it->wd->obj, "expanded", it);
+     }
+   else
+     {
+       if (it->realized)
+         edje_object_signal_emit(it->base, "elm,state,contracted", "elm");
+       evas_object_smart_callback_call(it->wd->obj, "contracted", it);
+     }
+}
+
+/**
+ * Get the expanded state of an item
+ *
+ * This gets the expanded state of an item
+ *
+ * @param it The item
+ * @return Thre expanded state
+ *
+ * @ingroup Genlist
+ */
+EAPI Eina_Bool
+elm_genlist_item_expanded_get(const Elm_Genlist_Item *it)
+{
+   if (!it) return EINA_FALSE;
+   return it->expanded;
+}
+
+/**
+ * Sets the disabled state of an item.
+ *
+ * A disabled item cannot be selected or unselected. It will also change
+ * appearance to appear disabled. This sets the disabled state (1 disabled, 0
+ * not disabled).
+ *
+ * @param it The item
+ * @param disabled The disabled state
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_item_disabled_set(Elm_Genlist_Item *it, Eina_Bool disabled)
+{
+   if (!it) return;
+   if (it->disabled == disabled) return;
+   if (it->delete_me) return;
+   it->disabled = disabled;
+   if (it->realized)
+     {
+       if (it->disabled)
+         edje_object_signal_emit(it->base, "elm,state,disabled", "elm");
+       else
+         edje_object_signal_emit(it->base, "elm,state,enabled", "elm");
+     }
+}
+
+/**
+ * Get the disabled state of an item
+ *
+ * This gets the disabld state of the given item.
+ *
+ * @param it The item
+ * @return The disabled state
+ *
+ * @ingroup Genlist
+ */
+EAPI Eina_Bool
+elm_genlist_item_disabled_get(const Elm_Genlist_Item *it)
+{
+   if (!it) return EINA_FALSE;
+   if (it->delete_me) return EINA_FALSE;
+   return it->disabled;
+}
+
+/**
+ * Sets the display only state of an item.
+ *
+ * A display only item cannot be selected or unselected. It is for display
+ * only and not selecting or otherwise clicking, dragging etc. by the user,
+ * thus finger size rules will not be applied to this item.
+ *
+ * @param it The item
+ * @param display_only The display only state
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_item_display_only_set(Elm_Genlist_Item *it, Eina_Bool display_only)
+{
+   if (!it) return;
+   if (!it->block) return;
+   if (it->display_only == display_only) return;
+   if (it->delete_me) return;
+   it->display_only = display_only;
+   it->mincalcd = EINA_FALSE;
+   it->updateme = EINA_TRUE;
+   it->block->updateme = EINA_TRUE;
+   if (it->wd->update_job) ecore_job_del(it->wd->update_job);
+   it->wd->update_job = ecore_job_add(_update_job, it->wd);
+}
+
+/**
+ * Get the display only state of an item
+ *
+ * This gets the display only state of the given item.
+ *
+ * @param it The item
+ * @return The display only state
+ *
+ * @ingroup Genlist
+ */
+EAPI Eina_Bool
+elm_genlist_item_display_only_get(const Elm_Genlist_Item *it)
+{
+   if (!it) return EINA_FALSE;
+   if (it->delete_me) return EINA_FALSE;
+   return it->display_only;
+}
+
+/**
+ * Show the given item
+ *
+ * This causes genlist to jump to the given item @p it and show it (by scrolling),
+ * if it is not fully visible.
+ *
+ * @param it The item
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_item_show(Elm_Genlist_Item *it)
+{
+   if (!it) return;
+   if (it->delete_me) return;
+   if ((it->queued) || (!it->mincalcd))
+     {
+       it->wd->show_item = it;
+        it->wd->bring_in = 1;
+       it->showme = EINA_TRUE;
+       return;
+     }
+   if (it->wd->show_item)
+     {
+       it->wd->show_item->showme = EINA_FALSE;
+       it->wd->show_item = NULL;
+     }
+   elm_smart_scroller_child_region_show(it->wd->scr,
+                                       it->x + it->block->x,
+                                       it->y + it->block->y,
+                                       it->block->w, it->h);
+}
+
+/**
+ * Bring in the given item
+ *
+ * This causes genlist to jump to the given item @p it and show it (by scrolling),
+ * if it is not fully visible. This may use animation to do so and take a
+ * period of time
+ *
+ * @param it The item
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_item_bring_in(Elm_Genlist_Item *it)
+{
+   if (!it) return;
+   if (it->delete_me) return;
+   if ((it->queued) || (!it->mincalcd))
+     {
+       it->wd->show_item = it;
+        it->wd->bring_in = 1;
+       it->showme = EINA_TRUE;
+       return;
+     }
+   if (it->wd->show_item)
+     {
+       it->wd->show_item->showme = EINA_FALSE;
+       it->wd->show_item = NULL;
+     }
+   elm_smart_scroller_region_bring_in(it->wd->scr,
+                                      it->x + it->block->x,
+                                      it->y + it->block->y,
+                                      it->block->w, it->h);
+}
+
+/**
+ * Show the given item at the top
+ *
+ * This causes genlist to jump to the given item @p it and show it (by scrolling),
+ * if it is not fully visible.
+ *
+ * @param it The item
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_item_top_show(Elm_Genlist_Item *it)
+{
+   Evas_Coord ow, oh;
+
+   if (!it) return;
+   if (it->delete_me) return;
+   if ((it->queued) || (!it->mincalcd))
+     {
+       it->wd->show_item = it;
+        it->wd->bring_in = 1;
+       it->showme = EINA_TRUE;
+       return;
+     }
+   if (it->wd->show_item)
+     {
+       it->wd->show_item->showme = EINA_FALSE;
+       it->wd->show_item = NULL;
+     }
+   evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
+   elm_smart_scroller_child_region_show(it->wd->scr,
+                                       it->x + it->block->x,
+                                       it->y + it->block->y,
+                                       it->block->w, oh);
+}
+
+/**
+ * Bring in the given item at the top
+ *
+ * This causes genlist to jump to the given item @p it and show it (by scrolling),
+ * if it is not fully visible. This may use animation to do so and take a
+ * period of time
+ *
+ * @param it The item
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_item_top_bring_in(Elm_Genlist_Item *it)
+{
+   Evas_Coord ow, oh;
+
+   if (!it) return;
+   if (it->delete_me) return;
+   if ((it->queued) || (!it->mincalcd))
+     {
+       it->wd->show_item = it;
+        it->wd->bring_in = 1;
+       it->showme = EINA_TRUE;
+       return;
+     }
+   if (it->wd->show_item)
+     {
+       it->wd->show_item->showme = EINA_FALSE;
+       it->wd->show_item = NULL;
+     }
+   evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
+   elm_smart_scroller_region_bring_in(it->wd->scr,
+                                      it->x + it->block->x,
+                                      it->y + it->block->y,
+                                      it->block->w, oh);
+}
+
+/**
+ * Show the given item at the middle
+ *
+ * This causes genlist to jump to the given item @p it and show it (by scrolling),
+ * if it is not fully visible.
+ *
+ * @param it The item
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_item_middle_show(Elm_Genlist_Item *it)
+{
+   Evas_Coord ow, oh;
+
+   if (!it) return;
+   if (it->delete_me) return;
+   if ((it->queued) || (!it->mincalcd))
+     {
+       it->wd->show_item = it;
+        it->wd->bring_in = 1;
+       it->showme = EINA_TRUE;
+       return;
+     }
+   if (it->wd->show_item)
+     {
+       it->wd->show_item->showme = EINA_FALSE;
+       it->wd->show_item = NULL;
+     }
+   evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
+   elm_smart_scroller_child_region_show(it->wd->scr,
+                                       it->x + it->block->x,
+                        it->y + it->block->y - oh/2 + it->h/2,
+                                       it->block->w, oh);
+}
+
+
+/**
+ * Bring in the given item at the middle
+ *
+ * This causes genlist to jump to the given item @p it and show it (by scrolling),
+ * if it is not fully visible. This may use animation to do so and take a
+ * period of time
+ *
+ * @param it The item
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_item_middle_bring_in(Elm_Genlist_Item *it)
+{
+   Evas_Coord ow, oh;
+
+   if (!it) return;
+   if (it->delete_me) return;
+   if ((it->queued) || (!it->mincalcd))
+     {
+       it->wd->show_item = it;
+        it->wd->bring_in = 1;
+       it->showme = EINA_TRUE;
+       return;
+     }
+   if (it->wd->show_item)
+     {
+       it->wd->show_item->showme = EINA_FALSE;
+       it->wd->show_item = NULL;
+     }
+   evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
+   elm_smart_scroller_region_bring_in(it->wd->scr,
+                                      it->x + it->block->x,
+                                      it->y + it->block->y - oh/2 + it->h/2,
+                                      it->block->w, oh);
+}
+
+/**
+ * Delete a given item
+ *
+ * This deletes the item from genlist and calls the genlist item del class
+ * callback defined in the item class, if it is set.
+ *
+ * @param it The item
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_item_del(Elm_Genlist_Item *it)
+{
+   if (!it) return;
+   if ((it->relcount > 0) || (it->walking > 0))
+     {
+       elm_genlist_item_subitems_clear(it);
+       it->delete_me = EINA_TRUE;
+       if (it->wd->show_item == it) it->wd->show_item = NULL;
+       if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
+       if (it->block)
+         {
+            if (it->realized) _item_unrealize(it);
+            it->block->changed = EINA_TRUE;
+            if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
+            it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
+         }
+       if (it->itc->func.del) it->itc->func.del(it->data, it->wd->obj);
+       return;
+     }
+   _item_del(it);
+}
+
+/**
+ * Set the data item from the genlist item
+ *
+ * This set the data value passed on the elm_genlist_item_append() and
+ * related item addition calls. This function will also call
+ * elm_genlist_item_update() so the item will be updated to reflect the
+ * new data.
+ *
+ * @param it The item
+ * @param data The new data pointer to set
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_item_data_set(Elm_Genlist_Item *it, const void *data)
+{
+   if (!it) return;
+   it->data = data;
+   elm_genlist_item_update(it);
+}
+
+/**
+ * Get the data item from the genlist item
+ *
+ * This returns the data value passed on the elm_genlist_item_append() and
+ * related item addition calls.
+ *
+ * @param it The item
+ * @return The data pointer provided when created
+ *
+ * @ingroup Genlist
+ */
+EAPI const void *
+elm_genlist_item_data_get(const Elm_Genlist_Item *it)
+{
+   if (!it) return NULL;
+   return it->data;
+}
+
+/**
+ * Get the real evas object of the genlist item
+ *
+ * This returns the actual evas object used for the specified genlist item.
+ * This may be NULL as it may not be created, and ma be deleted at any time
+ * by genlist. Do not modify this object (move, resize, show, hide etc.) as
+ * genlist is controlling it. This function is for querying, emitting
+ * custom signals or hooking lower level callbacks for events. Do not
+ * delete this object under any circumstances.
+ *
+ * @param it The item
+ * @return The objct pointer
+ *
+ * @ingroup Genlist
+ */
+EAPI const Evas_Object *
+elm_genlist_item_object_get(const Elm_Genlist_Item *it)
+{
+   if (!it) return NULL;
+   return it->base;
+}
+
+/**
+ * Update the contents of an item
+ *
+ * This updates an item by calling all the item class functions again to get
+ * the icons, labels and states. Use this when he original item data has
+ * changed and the changes are desired to be reflected.
+ *
+ * @param it The item
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_item_update(Elm_Genlist_Item *it)
+{
+   if (!it->block) return;
+   if (it->delete_me) return;
+   it->mincalcd = EINA_FALSE;
+   it->updateme = EINA_TRUE;
+   it->block->updateme = EINA_TRUE;
+   if (it->wd->update_job) ecore_job_del(it->wd->update_job);
+   it->wd->update_job = ecore_job_add(_update_job, it->wd);
+}
+
+/**
+ * This sets the horizontal stretching mode
+ *
+ * This sets the mode used for sizing items horizontally. Valid modes are
+ * ELM_LIST_LIMIT and ELM_LIST_SCROLL. The default is ELM_LIST_SCROLL. This
+ * mode means that if items are too wide to fit, the scroller will scroll
+ * horizontally. Otherwise items are expanded to fill the width of the
+ * viewport of the scroller. If it is ELM_LIST_LIMIT, Items will be expanded
+ * to the viewport width and limited to that size.
+ *
+ * @param obj The genlist object
+ * @param mode The mode to use
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_horizontal_mode_set(Evas_Object *obj, Elm_List_Mode mode)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->mode == mode) return;
+   wd->mode = mode;
+   _sizing_eval(obj);
+}
+
+/**
+ * Gets the horizontal stretching mode
+ *
+ * @param obj The genlist object
+ * @return The mode to use
+ * (ELM_LIST_LIMIT, ELM_LIST_SCROLL, ELM_LIST_LIMIT)
+ *
+ * @ingroup Genlist
+ */
+EAPI Elm_List_Mode
+elm_genlist_horizontal_mode_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return ELM_LIST_LAST;
+   return wd->mode;
+}
+
+/**
+ * Set the always select mode.
+ *
+ * Items will only call their selection func and callback when first becoming
+ * selected. Any further clicks will do nothing, unless you enable always
+ * select with elm_genlist_always_select_mode_set(). This means even if
+ * selected, every click will make the selected callbacks be called.
+ *
+ * @param obj The genlist object
+ * @param always_select The always select mode
+ * (EINA_TRUE = on, EINA_FALSE = off)
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_always_select_mode_set(Evas_Object *obj, Eina_Bool always_select)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->always_select = always_select;
+}
+
+/**
+ * Get the always select mode.
+ *
+ * @param obj The genlist object
+ * @return The always select mode
+ * (EINA_TRUE = on, EINA_FALSE = off)
+ *
+ * @ingroup Genlist
+ */
+EAPI Eina_Bool
+elm_genlist_always_select_mode_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->always_select;
+}
+
+/**
+ * Set no select mode
+ *
+ * This will turn off the ability to select items entirely and they will
+ * neither appear selected nor call selected callback functions.
+ *
+ * @param obj The genlist object
+ * @param no_select The no select mode
+ * (EINA_TRUE = on, EINA_FALSE = off)
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_no_select_mode_set(Evas_Object *obj, Eina_Bool no_select)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->no_select = no_select;
+}
+
+/**
+ * Gets no select mode
+ *
+ * @param obj The genlist object
+ * @return The no select mode
+ * (EINA_TRUE = on, EINA_FALSE = off)
+ *
+ * @ingroup Genlist
+ */
+EAPI Eina_Bool
+elm_genlist_no_select_mode_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->no_select;
+}
+
+/**
+ * Set compress mode
+ *
+ * This will enable the compress mode where items are "compressed" horizontally
+ * to fit the genlist scrollable viewport width.
+ *
+ * @param obj The genlist object
+ * @param no_select The compress mode
+ * (EINA_TRUE = on, EINA_FALSE = off)
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_compress_mode_set(Evas_Object *obj, Eina_Bool compress)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->compress = compress;
+}
+
+/**
+ * Get the compress mode
+ *
+ * @param obj The genlist object
+ * @return The compress mode
+ * (EINA_TRUE = on, EINA_FALSE = off)
+ *
+ * @ingroup Genlist
+ */
+EAPI Eina_Bool
+elm_genlist_compress_mode_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->compress;
+}
+
+/**
+ * Set bounce mode
+ *
+ * This will enable or disable the scroller bounce mode for the genlist. See 
+ * elm_scroller_bounce_set() for details
+ *
+ * @param obj The genlist object
+ * @param h_bounce Allow bounce horizontally
+ * @param v_bounce Allow bounce vertically
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce);
+}
+
+/**
+ * Get the bounce mode
+ *
+ * @param obj The genlist object
+ * @param h_bounce Allow bounce horizontally
+ * @param v_bounce Allow bounce vertically
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_bounce_allow_get(obj, h_bounce, v_bounce);
+}
+
+/**
+ * Set homogenous mode
+ *
+ * This will enable the homogeneous mode where items are of the same height and width
+ * so that genlist may do the lazy-loading at its maximum.  This implies 'compressed' mode
+ *
+ * @param obj The genlist object
+ * @param homogeneous Assume the items within the genlist are of the same height and width
+ * (EINA_TRUE = on, EINA_FALSE = off)
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_homogeneous_set(Evas_Object *obj, Eina_Bool homogeneous)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (homogeneous) elm_genlist_compress_mode_set(obj, EINA_TRUE);
+   wd->homogeneous = homogeneous;
+}
+
+/**
+ * Get the homogenous mode
+ *
+ * @param obj The genlist object
+ * @return Assume the items within the genlist are of the same height and width
+ * (EINA_TRUE = on, EINA_FALSE = off)
+ *
+ * @ingroup Genlist
+ */
+EAPI Eina_Bool
+elm_genlist_homogeneous_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->homogeneous;
+}
+
+/**
+ * Set the maximum number of items within an item block
+ *
+ * This will configure the block count to tune to the target with particular performance matrix.
+ *
+ * @param obj The genlist object
+ * @param n   Maximum number of items within an item block
+ *
+ * @ingroup Genlist
+ */
+EAPI void
+elm_genlist_block_count_set(Evas_Object *obj, int n)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->max_items_per_block = n;
+}
+
+/**
+ * Get the maximum number of items within an item block
+ *
+ * @param obj The genlist object
+ * @return Maximum number of items within an item block
+ *
+ * @ingroup Genlist
+ */
+EAPI int
+elm_genlist_block_count_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   return wd->max_items_per_block;
+}
diff --git a/src/lib/elm_hover.c b/src/lib/elm_hover.c
new file mode 100644 (file)
index 0000000..2508aab
--- /dev/null
@@ -0,0 +1,516 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Hover Hover
+ *
+ * A Hover object will over over the @p Parent object at the @p Target
+ * location.  Anything in the background will be given a darker coloring
+ * to indicate that the hover object is on top.
+ *
+ * NOTE: The hover object will take up the entire space of @p Target object.
+ */
+
+typedef struct _Widget_Data Widget_Data;
+typedef struct _Subinfo Subinfo;
+
+struct _Widget_Data
+{
+   Evas_Object *hov, *cov;
+   Evas_Object *offset, *size;
+   Evas_Object *parent, *target;
+   Eina_List *subs;
+};
+
+struct _Subinfo
+{
+   const char *swallow;
+   Evas_Object *obj;
+};
+
+static const char *widtype = NULL;
+static void _del_pre_hook(Evas_Object *obj);
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _reval_content(Evas_Object *obj);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+static void _hov_show_do(Evas_Object *obj);
+static void _hov_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _hov_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _hov_show(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _hov_hide(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+static void
+_del_pre_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Subinfo *si;
+   if (!wd) return;
+   if (evas_object_visible_get(obj))
+     evas_object_smart_callback_call(obj, "clicked", NULL);
+   elm_hover_target_set(obj, NULL);
+   elm_hover_parent_set(obj, NULL);
+   evas_object_event_callback_del_full(wd->hov, EVAS_CALLBACK_MOVE, _hov_move, obj);
+   evas_object_event_callback_del_full(wd->hov, EVAS_CALLBACK_RESIZE, _hov_resize, obj);
+   evas_object_event_callback_del_full(wd->hov, EVAS_CALLBACK_SHOW, _hov_show, obj);
+   evas_object_event_callback_del_full(wd->hov, EVAS_CALLBACK_HIDE, _hov_hide, obj);
+
+   EINA_LIST_FREE(wd->subs, si)
+     {
+       eina_stringshare_del(si->swallow);
+       free(si);
+     }
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   // FIXME: hover contents doesnt seem to propagate resizes properly
+   _elm_theme_object_set(obj, wd->cov, "hover", "base", elm_widget_style_get(obj));
+   edje_object_scale_set(wd->cov, elm_widget_scale_get(obj) *
+                         _elm_config->scale);
+   _reval_content(obj);
+   _sizing_eval(obj);
+   if (evas_object_visible_get(wd->cov)) _hov_show_do(obj);
+}
+
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord x = 0, y = 0, w = 0, h = 0, x2 = 0, y2 = 0, w2 = 0, h2 = 0;
+   if (!wd) return;
+   if (wd->parent) evas_object_geometry_get(wd->parent, &x, &y, &w, &h);
+   if (wd->hov) evas_object_geometry_get(wd->hov, &x2, &y2, &w2, &h2);
+   evas_object_move(wd->cov, x, y);
+   evas_object_resize(wd->cov, w, h);
+   evas_object_size_hint_min_set(wd->offset, x2 - x, y2 - y);
+   evas_object_size_hint_min_set(wd->size, w2, h2);
+   edje_object_part_swallow(wd->cov, "elm.swallow.offset", wd->offset);
+   edje_object_part_swallow(wd->cov, "elm.swallow.size", wd->size);
+}
+
+static void
+_reval_content(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   const Eina_List *l;
+   const Subinfo *si;
+   if (!wd) return;
+   EINA_LIST_FOREACH(wd->subs, l, si)
+     edje_object_part_swallow(wd->cov, si->swallow, si->obj);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *sub = event_info;
+   Eina_List *l;
+   Subinfo *si;
+   if (!wd) return;
+   EINA_LIST_FOREACH(wd->subs, l, si)
+     {
+       if (si->obj == sub)
+         {
+            wd->subs = eina_list_remove_list(wd->subs, l);
+            eina_stringshare_del(si->swallow);
+            free(si);
+            break;
+         }
+     }
+}
+
+static void
+_hov_show_do(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   const Eina_List *l;
+   const Subinfo *si;
+   if (!wd) return;
+   if (wd->cov)
+     {
+       evas_object_show(wd->cov);
+       edje_object_signal_emit(wd->cov, "elm,action,show", "elm");
+     }
+   EINA_LIST_FOREACH(wd->subs, l, si)
+     {
+       char buf[1024];
+
+       if (!strncmp(si->swallow, "elm.swallow.slot.", 17))
+         {
+            snprintf(buf, sizeof(buf), "elm,action,slot,%s,show",
+                     si->swallow + 17);
+            edje_object_signal_emit(wd->cov, buf, "elm");
+         }
+     }
+}
+
+static void
+_hov_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+}
+
+static void
+_hov_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+}
+
+static void
+_hov_show(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _hov_show_do(data);
+}
+
+static void
+_hov_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   const Eina_List *l;
+   const Subinfo *si;
+   if (!wd) return;
+   if (wd->cov)
+     {
+       edje_object_signal_emit(wd->cov, "elm,action,hide", "elm");
+       evas_object_hide(wd->cov);
+     }
+   EINA_LIST_FOREACH(wd->subs, l, si)
+     {
+       char buf[1024];
+
+       if (!strncmp(si->swallow, "elm.swallow.slot.", 17))
+         {
+            snprintf(buf, sizeof(buf), "elm,action,slot,%s,hide",
+                     si->swallow + 17);
+            edje_object_signal_emit(wd->cov, buf, "elm");
+         }
+     }
+}
+
+static void
+_target_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   wd->target = NULL;
+}
+
+static void
+_signal_dismiss(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   evas_object_hide(data);
+   evas_object_smart_callback_call(data, "clicked", NULL);
+}
+
+static void
+_parent_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+}
+
+static void
+_parent_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+}
+
+static void
+_parent_show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+}
+
+static void
+_parent_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (wd) evas_object_hide(wd->cov);
+}
+
+static void
+_parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   elm_hover_parent_set(data, NULL);
+   _sizing_eval(data);
+}
+
+/**
+ * Adds a hover object to @p parent
+ *
+ * @param parent The parent object
+ * @return The hover object or NULL if one could not be created
+ *
+ * @ingroup Hover
+ */
+EAPI Evas_Object *
+elm_hover_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "hover");
+   elm_widget_type_set(obj, "hover");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_pre_hook_set(obj, _del_pre_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_del_hook_set(obj, _del_hook);
+
+   wd->hov = evas_object_rectangle_add(e);
+   evas_object_pass_events_set(wd->hov, 1);
+   evas_object_color_set(wd->hov, 0, 0, 0, 0);
+   elm_widget_resize_object_set(obj, wd->hov);
+   evas_object_event_callback_add(wd->hov, EVAS_CALLBACK_MOVE, _hov_move, obj);
+   evas_object_event_callback_add(wd->hov, EVAS_CALLBACK_RESIZE, _hov_resize, obj);
+   evas_object_event_callback_add(wd->hov, EVAS_CALLBACK_SHOW, _hov_show, obj);
+   evas_object_event_callback_add(wd->hov, EVAS_CALLBACK_HIDE, _hov_hide, obj);
+
+   wd->cov = edje_object_add(e);
+   _elm_theme_object_set(obj, wd->cov, "hover", "base", "default");
+   elm_widget_sub_object_add(obj, wd->cov);
+   edje_object_signal_callback_add(wd->cov, "elm,action,dismiss", "",
+                                   _signal_dismiss, obj);
+
+   wd->offset = evas_object_rectangle_add(e);
+   evas_object_pass_events_set(wd->offset, 1);
+   evas_object_color_set(wd->offset, 0, 0, 0, 0);
+   elm_widget_sub_object_add(obj, wd->offset);
+
+   wd->size = evas_object_rectangle_add(e);
+   evas_object_pass_events_set(wd->size, 1);
+   evas_object_color_set(wd->size, 0, 0, 0, 0);
+   elm_widget_sub_object_add(obj, wd->size);
+
+   edje_object_part_swallow(wd->cov, "elm.swallow.offset", wd->offset);
+   edje_object_part_swallow(wd->cov, "elm.swallow.size", wd->size);
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Sets the target object for the hover.
+ *
+ * @param obj The hover object
+ * @param target The object to center the hover onto. The hover
+ * will take up the entire space that the target object fills.
+ *
+ * @ingroup Hover
+ */
+EAPI void
+elm_hover_target_set(Evas_Object *obj, Evas_Object *target)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (wd->target)
+     evas_object_event_callback_del_full(wd->target, EVAS_CALLBACK_DEL,
+                                    _target_del, obj);
+   wd->target = target;
+   if (wd->target)
+     {
+       evas_object_event_callback_add(wd->target, EVAS_CALLBACK_DEL,
+                                       _target_del, obj);
+       elm_widget_hover_object_set(target, obj);
+       _sizing_eval(obj);
+     }
+}
+
+
+/**
+ * Sets the parent object for the hover.
+ *
+ * @param obj The hover object
+ * @param parent The object to locate the hover over.
+ *
+ * @ingroup Hover
+ */
+EAPI void
+elm_hover_parent_set(Evas_Object *obj, Evas_Object *parent)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->parent)
+     {
+       evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_MOVE,
+                                       _parent_move, obj);
+       evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_RESIZE,
+                                       _parent_resize, obj);
+       evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_SHOW,
+                                       _parent_show, obj);
+       evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_HIDE,
+                                       _parent_hide, obj);
+       evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_DEL,
+                                       _parent_del, obj);
+     }
+   wd->parent = parent;
+   if (wd->parent)
+     {
+       evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_MOVE,
+                                       _parent_move, obj);
+       evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_RESIZE,
+                                       _parent_resize, obj);
+       evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_SHOW,
+                                       _parent_show, obj);
+       evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_HIDE,
+                                       _parent_hide, obj);
+       evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_DEL,
+                                       _parent_del, obj);
+//     elm_widget_sub_object_add(parent, obj);
+     }
+   _sizing_eval(obj);
+}
+
+/**
+ * Gets the target object for the hover.
+ *
+ * @param obj The hover object
+ * @return The target object of the hover.
+ * 
+ * @ingroup Hover
+ */
+EAPI Evas_Object *
+elm_hover_target_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   return wd->target;
+}
+
+/**
+ * Gets the parent object for the hover.
+ *
+ * @param obj The hover object
+ * @return The parent object to locate the hover over.
+ *
+ * @ingroup Hover
+ */
+EAPI Evas_Object *
+elm_hover_parent_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   return wd->parent;
+}
+
+/**
+ * Sets the content of the hover object and the direction in which
+ * it will pop out.
+ *
+ * @param obj The hover object
+ * @param swallow The direction that the object will display in. Multiple
+ * objects can have the same swallow location. Objects placed in the same
+ * swallow will be placed starting at the middle of the hover and ending
+ * farther from the middle.
+ * Accepted values are "left" "right" "top" "bottom" "middle"
+ * @param content The content to place at @p swallow
+ *
+ * @ingroup Hover
+ */
+EAPI void
+elm_hover_content_set(Evas_Object *obj, const char *swallow, Evas_Object *content)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Subinfo *si;
+   const Eina_List *l;
+   char buf[1024];
+   if (!wd) return;
+   snprintf(buf, sizeof(buf), "elm.swallow.slot.%s", swallow);
+   EINA_LIST_FOREACH(wd->subs, l, si)
+     {
+       if (!strcmp(buf, si->swallow))
+         {
+            if (content == si->obj) return;
+            elm_widget_sub_object_del(obj, si->obj);
+            break;
+         }
+     }
+   if (content)
+     {
+       elm_widget_sub_object_add(obj, content);
+       edje_object_part_swallow(wd->cov, buf, content);
+       si = ELM_NEW(Subinfo);
+       si->swallow = eina_stringshare_add(buf);
+       si->obj = content;
+       wd->subs = eina_list_append(wd->subs, si);
+       _sizing_eval(obj);
+     }
+}
+
+/**
+ * Returns the best swallow location for content in the hover.
+ *
+ * @param obj The hover object
+ * @return The edje location to place content into the hover.
+ * See also elm_hover_content_set()
+ *
+ * @ingroup Hover
+ */
+EAPI const char *
+elm_hover_best_content_location_get(const Evas_Object *obj, Elm_Hover_Axis pref_axis)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) "left";
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord x = 0, y = 0, w = 0, h = 0, x2 = 0, y2 = 0, w2 = 0, h2 = 0;
+   Evas_Coord spc_l, spc_r, spc_t, spc_b;
+   if (!wd) return "left";
+   if (wd->parent) evas_object_geometry_get(wd->parent, &x, &y, &w, &h);
+   if (wd->target) evas_object_geometry_get(wd->target, &x2, &y2, &w2, &h2);
+   spc_l = x2 - x;
+   spc_r = (x + w) - (x2 + w2);
+   if (spc_l < 0) spc_l = 0;
+   if (spc_r < 0) spc_r = 0;
+   spc_t = y2 - y;
+   spc_b = (y + h) - (y2 + h2);
+   if (spc_t < 0) spc_t = 0;
+   if (spc_b < 0) spc_b = 0;
+   if (pref_axis == ELM_HOVER_AXIS_HORIZONTAL)
+     {
+       if (spc_l < spc_r) return "right";
+       else return "left";
+     }
+   else if (pref_axis == ELM_HOVER_AXIS_VERTICAL)
+     {
+       if (spc_t < spc_b) return "bottom";
+       else return "top";
+     }
+   if (spc_l < spc_r)
+     {
+       if (spc_t > spc_r) return "top";
+       else if (spc_b > spc_r) return "bottom";
+       return "right";
+     }
+   if (spc_t > spc_r) return "top";
+   else if (spc_b > spc_r) return "bottom";
+   return "left";
+}
diff --git a/src/lib/elm_icon.c b/src/lib/elm_icon.c
new file mode 100644 (file)
index 0000000..c4ae4b6
--- /dev/null
@@ -0,0 +1,290 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Icon Icon
+ *
+ * A standard icon that may be provided by the theme (delete, edit,
+ * arrows etc.) or a custom file (PNG, JPG, EDJE etc.) used for an
+ * icon. The Icon may scale or not and of course... support alpha
+ * channels.
+ * 
+ * Signals that you can add callbacks for are:
+ * 
+ * clicked - This is called when a user has clicked the icon
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *img;
+   const char *stdicon;
+   Eina_Bool scale_up : 1;
+   Eina_Bool scale_down : 1;
+   Eina_Bool smooth : 1;
+   Eina_Bool fill_outside : 1;
+   Eina_Bool no_scale : 1;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   if (wd->stdicon) eina_stringshare_del(wd->stdicon);
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->stdicon)
+     _elm_theme_object_icon_set(obj, wd->img, wd->stdicon, "default");
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   int w, h;
+
+   _els_smart_icon_size_get(wd->img, &w, &h);
+   _els_smart_icon_scale_up_set(wd->img, wd->scale_up);
+   _els_smart_icon_scale_down_set(wd->img, wd->scale_down);
+   _els_smart_icon_smooth_scale_set(wd->img, wd->smooth);
+   _els_smart_icon_fill_inside_set(wd->img, !(wd->fill_outside));
+   if (wd->no_scale) _els_smart_icon_scale_set(wd->img, 1.0);
+   else
+     {
+       _els_smart_icon_scale_set(wd->img, elm_widget_scale_get(obj) *
+                                 _elm_config->scale);
+       _els_smart_icon_size_get(wd->img, &w, &h);
+     }
+   if (!wd->scale_down)
+     {
+       minw = w;
+       minh = h;
+     }
+   if (!wd->scale_up)
+     {
+       maxw = w;
+       maxh = h;
+     }
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Evas_Event_Mouse_Up *ev = event_info;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
+   evas_object_smart_callback_call(data, "clicked", event_info);
+}
+
+/**
+ * Add a new icon to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Icon
+ */
+EAPI Evas_Object *
+elm_icon_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "icon");
+   elm_widget_type_set(obj, "icon");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_can_focus_set(obj, 0);
+
+   wd->img = _els_smart_icon_add(e);
+   evas_object_event_callback_add(wd->img, EVAS_CALLBACK_MOUSE_UP,
+                                 _mouse_up, obj);
+   evas_object_repeat_events_set(wd->img, 1);
+   elm_widget_resize_object_set(obj, wd->img);
+
+   wd->smooth = EINA_TRUE;
+   wd->scale_up = EINA_TRUE;
+   wd->scale_down = EINA_TRUE;
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Set the file that will be used as icon
+ *
+ * @param obj The icon object
+ * @param file The path to file that will be used as icon
+ * @param group The group that the icon belongs in edje file
+ *
+ * @return (1 = sucess, 0 = error)
+ *
+ * @ingroup Icon
+ */
+EAPI Eina_Bool
+elm_icon_file_set(Evas_Object *obj, const char *file, const char *group)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Eina_Bool ret;
+   const char *p;
+
+   if ((!wd) || (!file)) return EINA_FALSE;
+   if (wd->stdicon) eina_stringshare_del(wd->stdicon);
+   wd->stdicon = NULL;
+   if (((p = strrchr(file, '.'))) && (!strcasecmp(p, ".edj")))
+     ret = _els_smart_icon_file_edje_set(wd->img, file, group);
+   else
+     ret = _els_smart_icon_file_key_set(wd->img, file, group);
+   _sizing_eval(obj);
+   return ret;
+}
+
+/**
+ * Set the theme, as standard, for a icon
+ *
+ * @param obj The icon object
+ * @param name The theme name
+ *
+ * @return (1 = sucess, 0 = error)
+ *
+ * @ingroup Icon
+ */
+EAPI Eina_Bool
+elm_icon_standard_set(Evas_Object *obj, const char *name)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Eina_Bool ret;
+
+   if ((!wd) || (!name)) return EINA_FALSE;
+   eina_stringshare_replace(&wd->stdicon, name);
+   ret = _elm_theme_object_icon_set(obj, wd->img, name, "default");
+   _sizing_eval(obj);
+   return ret;
+}
+
+/**
+ * Set the smooth effect for a icon
+ *
+ * @param obj The icon object
+ * @param smooth A bool to set (or no) smooth effect
+ * (1 = smooth, 0 = not smooth)
+ *
+ * @ingroup Icon
+ */
+EAPI void
+elm_icon_smooth_set(Evas_Object *obj, Eina_Bool smooth)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   wd->smooth = smooth;
+   _sizing_eval(obj);
+}
+
+/**
+ * Set if the object are scalable
+ *
+ * @param obj The icon object
+ * @param no_scale A bool to set scale (or no)
+ * (1 = no_scale, 0 = scale)
+ *
+ * @ingroup Icon
+ */
+EAPI void
+elm_icon_no_scale_set(Evas_Object *obj, Eina_Bool no_scale)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   wd->no_scale = no_scale;
+   _sizing_eval(obj);
+}
+
+/**
+ * Set if the object is (up/down) scalable
+ *
+ * @param obj The icon object
+ * @param scale_up A bool to set if the object is scalable up
+ * @param scale_down A bool to set if the object is scalable down
+ *
+ * @ingroup Icon
+ */
+EAPI void
+elm_icon_scale_set(Evas_Object *obj, Eina_Bool scale_up, Eina_Bool scale_down)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   wd->scale_up = scale_up;
+   wd->scale_down = scale_down;
+   _sizing_eval(obj);
+}
+
+/**
+ * Set if the object is filled outside
+ *
+ * @param obj The icon object
+ * @param fill_outside A bool to set if the object is filled outside
+ * (1 = filled, 0 = no filled)
+ *
+ * @ingroup Icon
+ */
+EAPI void
+elm_icon_fill_outside_set(Evas_Object *obj, Eina_Bool fill_outside)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   wd->fill_outside = fill_outside;
+   _sizing_eval(obj);
+}
+
+
+/**
+ * Set the prescale size for the icon
+ *
+ * @param obj The icon object
+ * @param size The prescale size
+ *
+ * @ingroup Icon
+ */
+EAPI void
+elm_icon_prescale_set(Evas_Object *obj, int size)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   _els_smart_icon_scale_size_set(wd->img, size);
+}
diff --git a/src/lib/elm_image.c b/src/lib/elm_image.c
new file mode 100644 (file)
index 0000000..d04df56
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2,t0,(0
+ */
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Image Image
+ *
+ * A standard image that may be provided by the theme (delete, edit,
+ * arrows etc.) or a custom file (PNG, JPG, EDJE etc.) used for an
+ * icon. The Icon may scale or not and of course... support alpha
+ * channels.
+ * 
+ * Signals that you can add callbacks for are:
+ *
+ * clicked - This is called when a user has clicked the image
+ * 
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *img;
+   Eina_Bool scale_up : 1;
+   Eina_Bool scale_down : 1;
+   Eina_Bool smooth : 1;
+   Eina_Bool fill_outside : 1;
+   Eina_Bool no_scale : 1;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   free(wd);
+}
+
+static void
+_del_pre_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   evas_object_del(wd->img);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   int w, h;
+
+   if (!wd) return;
+   _els_smart_icon_size_get(wd->img, &w, &h);
+   _els_smart_icon_scale_up_set(wd->img, wd->scale_up);
+   _els_smart_icon_scale_down_set(wd->img, wd->scale_down);
+   _els_smart_icon_smooth_scale_set(wd->img, wd->smooth);
+   _els_smart_icon_fill_inside_set(wd->img, !(wd->fill_outside));
+   if (wd->no_scale) _els_smart_icon_scale_set(wd->img, 1.0);
+   else
+     {
+       _els_smart_icon_scale_set(wd->img, elm_widget_scale_get(obj) * _elm_config->scale);
+       _els_smart_icon_size_get(wd->img, &w, &h);
+     }
+   if (!wd->scale_down)
+     {
+       minw = w;
+       minh = h;
+     }
+   if (!wd->scale_up)
+     {
+       maxw = w;
+       maxh = h;
+     }
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, "clicked", NULL);
+}
+
+/**
+ * Add a new image to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Image
+ */
+EAPI Evas_Object *
+elm_image_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "image");
+   elm_widget_type_set(obj, "image");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_del_pre_hook_set(obj, _del_pre_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_can_focus_set(obj, 0);
+
+   wd->img = _els_smart_icon_add(e);
+   evas_object_event_callback_add(wd->img, EVAS_CALLBACK_MOUSE_UP,
+                                 _mouse_up, obj);
+   evas_object_repeat_events_set(wd->img, 1);
+   elm_widget_resize_object_set(obj, wd->img);
+
+   wd->smooth = EINA_TRUE;
+   wd->scale_up = EINA_TRUE;
+   wd->scale_down = EINA_TRUE;
+
+   _els_smart_icon_scale_size_set(wd->img, 0);
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Set the file that will be used as image
+ *
+ * @param obj The image object
+ * @param file The path to file that will be used as image
+ * @param group The group that the image belongs in edje file
+ *
+ * @return (1 = sucess, 0 = error)
+ *
+ * @ingroup Image
+ */
+EAPI Eina_Bool
+elm_image_file_set(Evas_Object *obj, const char *file, const char *group)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Eina_Bool ret;
+   const char *p;
+
+   if ((!wd) || (!file)) return EINA_FALSE;
+   if (((p = strrchr(file, '.'))) && (!strcasecmp(p, ".edj")))
+     ret = _els_smart_icon_file_edje_set(wd->img, file, group);
+   else
+     ret = _els_smart_icon_file_key_set(wd->img, file, group);
+   _sizing_eval(obj);
+   return ret;
+}
+
+/**
+ * Set the smooth effect for a image
+ *
+ * @param obj The image object
+ * @param smooth A bool to set (or no) smooth effect
+ * (1 = smooth, 0 = not smooth)
+ *
+ * @ingroup Image
+ */
+EAPI void
+elm_image_smooth_set(Evas_Object *obj, Eina_Bool smooth)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   wd->smooth = smooth;
+   _sizing_eval(obj);
+}
+
+EAPI void
+elm_image_object_size_get(const Evas_Object *obj, int *w, int *h)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   _els_smart_icon_size_get(wd->img, w, h);
+}
+
+/**
+ * Set if the object are scalable
+ *
+ * @param obj The image object.
+ * @param no_scale A bool to set scale (or no).
+ * (1 = no_scale, 0 = scale)
+ *
+ * @ingroup Image
+ */
+EAPI void
+elm_image_no_scale_set(Evas_Object *obj, Eina_Bool no_scale)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   wd->no_scale = no_scale;
+   _sizing_eval(obj);
+
+}
+
+/**
+ * Set if the object is (up/down) scalable
+ *
+ * @param obj The image object
+ * @param scale_up A bool to set if the object is scalable up
+ * @param scale_down A bool to set if the object is scalable down
+ *
+ * @ingroup Image
+ */
+EAPI void
+elm_image_scale_set(Evas_Object *obj, Eina_Bool scale_up, Eina_Bool scale_down)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   wd->scale_up = scale_up;
+   wd->scale_down = scale_down;
+   _sizing_eval(obj);
+}
+
+/**
+ * Set if the object is filled outside
+ *
+ * @param obj The image object
+ * @param fill_outside A bool to set if the object is filled outside
+ * (1 = filled, 0 = no filled)
+ *
+ * @ingroup Image
+ */
+EAPI void
+elm_image_fill_outside_set(Evas_Object *obj, Eina_Bool fill_outside)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   wd->fill_outside = fill_outside;
+   _sizing_eval(obj);
+}
+
+/**
+ * Set the prescale size for the image
+ *
+ * @param obj The image object
+ * @param size The prescale size
+ *
+ * @ingroup Image
+ */
+EAPI void
+elm_image_prescale_set(Evas_Object *obj, int size)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   _els_smart_icon_scale_size_set(wd->img, size);
+}
+
+/**
+ * Set the image orient
+ *
+ * @param obj The image object
+ * @param orient The image orient
+ * (ELM_IMAGE_ORIENT_NONE, ELM_IMAGE_ROTATE_90_CW,
+ *  ELM_IMAGE_ROTATE_180_CW, ELM_IMAGE_ROTATE_90_CCW,
+ *  ELM_IMAGE_FLIP_HORIZONTAL,ELM_IMAGE_FLIP_VERTICAL,
+ *  ELM_IMAGE_FLIP_TRANSPOSE, ELM_IMAGE_FLIP_TRANSVERSE)
+ *
+ * @ingroup Image
+ */
+EAPI void
+elm_image_orient_set(Evas_Object *obj, Elm_Image_Orient orient)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   _els_smart_icon_orient_set(wd->img, orient);
+}
diff --git a/src/lib/elm_index.c b/src/lib/elm_index.c
new file mode 100644 (file)
index 0000000..af2c1e2
--- /dev/null
@@ -0,0 +1,798 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Index Index
+ *
+ * An index object is a type of list that categorizes items in it
+ * by letter.
+ */
+
+typedef struct _Widget_Data Widget_Data;
+typedef struct _Item Item;
+
+struct _Widget_Data
+{
+   Evas_Object *base;
+   Evas_Object *event[2];
+   Evas_Object *bx[2]; // 2 - for now all that's supported
+   Eina_List *items; // 1 list. yes N levels, but only 2 for now and # of items will be small
+   int level;
+   Evas_Coord dx, dy;
+   Ecore_Timer *delay;
+   Eina_Bool level_active[2];
+   Eina_Bool horizontal : 1;
+   Eina_Bool active : 1;
+   Eina_Bool down : 1;
+};
+
+struct _Item
+{
+   Evas_Object *obj;
+   const char *letter;
+   const void *data;
+   int level;
+   Evas_Object *base;
+   Eina_Bool selected : 1;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _index_box_auto_fill(Evas_Object *obj, Evas_Object *box, int level);
+static void _index_box_clear(Evas_Object *obj, Evas_Object *box, int level);
+static void _item_free(Item *it);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Item *it;
+   Eina_List *l, *clear = NULL;
+   if (!wd) return;
+   _index_box_clear(obj, wd->bx[wd->level], wd->level);
+   _index_box_clear(obj, wd->bx[0], 0);
+   EINA_LIST_FOREACH(wd->items, l, it) clear = eina_list_append(clear, it);
+   EINA_LIST_FREE(clear, it) _item_free(it);
+   if (wd->delay) ecore_timer_del(wd->delay);
+   free(wd);
+}
+
+static void
+_layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data)
+{
+   Widget_Data *wd = data;
+   if (!wd) return;
+   _els_box_layout(o, priv, wd->horizontal, 1);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _index_box_clear(obj, wd->bx[0], 0);
+   _index_box_clear(obj, wd->bx[1], 1);
+   if (wd->horizontal)
+     _elm_theme_object_set(obj, wd->base, "index", "base/horizontal", elm_widget_style_get(obj));
+   else
+     _elm_theme_object_set(obj, wd->base, "index", "base/vertical", elm_widget_style_get(obj));
+   edje_object_part_swallow(wd->base, "elm.swallow.event.0", wd->event[0]);
+   edje_object_part_swallow(wd->base, "elm.swallow.index.0", wd->bx[0]);
+   if (edje_object_part_exists(wd->base, "elm.swallow.index.1"))
+     {
+        if (!wd->bx[1])
+          {
+            wd->bx[1] = evas_object_box_add(evas_object_evas_get(wd->base));
+            evas_object_box_layout_set(wd->bx[1], _layout, wd, NULL);
+             elm_widget_sub_object_add(obj, wd->bx[1]);
+          }
+        edje_object_part_swallow(wd->base, "elm.swallow.index.1", wd->bx[1]);
+        evas_object_show(wd->bx[1]);
+     }
+   else if (wd->bx[1])
+     {
+        evas_object_del(wd->bx[1]);
+        wd->bx[1] = NULL;
+     }
+   if (edje_object_part_exists(wd->base, "elm.swallow.event.1"))
+     {
+        if (!wd->event[1])
+          {
+             Evas_Coord minw = 0, minh = 0;
+
+             wd->event[1] = evas_object_rectangle_add(evas_object_evas_get(wd->base));
+             evas_object_color_set(wd->event[1], 0, 0, 0, 0);
+             evas_object_size_hint_min_set(wd->event[1], minw, minh);
+             minw = minh = 0;
+             elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+             elm_widget_sub_object_add(obj, wd->event[1]);
+          }
+        edje_object_part_swallow(wd->base, "elm.swallow.event.1", wd->event[1]);
+     }
+   else if (wd->event[1])
+     {
+        evas_object_del(wd->event[1]);
+        wd->event[1] = NULL;
+     }
+   edje_object_message_signal_process(wd->base);
+   edje_object_scale_set(wd->base, elm_widget_scale_get(obj) * _elm_config->scale);
+   _sizing_eval(obj);
+   _index_box_auto_fill(obj, wd->bx[0], 0);
+   if (wd->active)
+     if (wd->level == 1)
+       _index_box_auto_fill(obj, wd->bx[1], 1);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   if (!wd) return;
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   edje_object_size_min_restricted_calc(wd->base, &minw, &minh, minw, minh);
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static Item *
+_item_new(Evas_Object *obj, const char *letter, const void *item)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Item *it;
+   if (!wd) return NULL;
+   it = calloc(1, sizeof(Item));
+   if (!it) return NULL;
+   it->obj = obj;
+   it->letter = eina_stringshare_add(letter);
+   it->data = item;
+   it->level = wd->level;
+   return it;
+}
+
+static Item *
+_item_find(Evas_Object *obj, const void *item)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Eina_List *l;
+   Item *it;
+   if (!wd) return NULL;
+   EINA_LIST_FOREACH(wd->items, l, it)
+     if (it->data == item) return it;
+   return NULL;
+}
+
+static void
+_item_free(Item *it)
+{
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+   if (!wd) return;
+   wd->items = eina_list_remove(wd->items, it);
+   if (it->base) evas_object_del(it->base);
+   eina_stringshare_del(it->letter);
+   free(it);
+}
+
+// FIXME: always have index filled
+static void
+_index_box_auto_fill(Evas_Object *obj, Evas_Object *box, int level)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Eina_List *l;
+   Item *it;
+   Evas_Coord mw, mh, w, h;
+   int i = 0;
+   if (!wd) return;
+   if (wd->level_active[level]) return;
+   evas_object_geometry_get(box, NULL, NULL, &w, &h);
+   EINA_LIST_FOREACH(wd->items, l, it)
+     {
+        Evas_Object *o;
+        const char *stacking;
+
+        if (it->level != level) continue;
+        o = edje_object_add(evas_object_evas_get(obj));
+        it->base = o;
+        if (i & 0x1)
+          _elm_theme_object_set(obj, o, "index", "item_odd/vertical", "default");
+        else
+          _elm_theme_object_set(obj, o, "index", "item/vertical", "default");
+        edje_object_part_text_set(o, "elm.text", it->letter);
+        edje_object_size_min_restricted_calc(o, &mw, &mh, 0, 0);
+        evas_object_size_hint_min_set(o, mw, mh);
+        evas_object_size_hint_weight_set(o, 1.0, 1.0);
+        evas_object_size_hint_align_set(o, -1.0, -1.0);
+        elm_widget_sub_object_add(obj, o);
+        evas_object_box_append(box, o);
+        stacking = edje_object_data_get(o, "stacking");
+        if (stacking)
+          {
+             if (!strcmp(stacking, "below")) evas_object_lower(o);
+             else if (!strcmp(stacking, "above")) evas_object_raise(o);
+          }
+        evas_object_show(o);
+        i++;
+        evas_object_smart_calculate(box); // force a calc so we know the size
+        evas_object_size_hint_min_get(box, &mw, &mh);
+        if (mh > h)
+          {
+             _index_box_clear(obj, box, level);
+             if (i > 0)
+               {
+                  // FIXME: only i objects fit! try again. overflows right now
+               }
+          }
+     }
+   evas_object_smart_calculate(box);
+   wd->level_active[level] = 1;
+}
+
+static void
+_index_box_clear(Evas_Object *obj, Evas_Object *box __UNUSED__, int level)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Eina_List *l;
+   Item *it;
+   if (!wd) return;
+   if (!wd->level_active[level]) return;
+   EINA_LIST_FOREACH(wd->items, l, it)
+     {
+        if (!it->base) continue;
+        if (it->level != level) continue;
+        evas_object_del(it->base);
+        it->base = 0;
+     }
+   wd->level_active[level] = 0;
+}
+
+static int
+_delay_change(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   void *d;
+   if (!wd) return 0;
+   wd->delay = NULL;
+   d = (void *)elm_index_item_selected_get(data, wd->level);
+   if (d) evas_object_smart_callback_call(data, "delay,changed", d);
+   return 0;
+}
+
+static void
+_sel_eval(Evas_Object *obj, Evas_Coord evx, Evas_Coord evy)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Item *it, *it_closest, *it_last;
+   Eina_List *l;
+   Evas_Coord x, y, w, h, bx, by, bw, bh, xx, yy;
+   double cdv = 0.5;
+   Evas_Coord dist;
+   Eina_Bool change = 0;
+   char *label = NULL, *last = NULL;
+   int i;
+   if (!wd) return;
+   for (i = 0; i <= wd->level; i++)
+     {
+        it_last = NULL;
+        it_closest  = NULL;
+        dist = 0x7fffffff;
+        evas_object_geometry_get(wd->bx[i], &bx, &by, &bw, &bh);
+        EINA_LIST_FOREACH(wd->items, l, it)
+          {
+             if (!((it->level == i) && (it->base))) continue;
+             if ((it->base) && (it->level != wd->level))
+               {
+                  if (it->selected)
+                    {
+                       it_closest = it;
+                       break;
+                    }
+                  continue;
+               }
+             if (it->selected)
+               {
+                  it_last = it;
+                  it->selected = 0;
+               }
+             evas_object_geometry_get(it->base, &x, &y, &w, &h);
+             xx = x + (w / 2);
+             yy = y + (h / 2);
+             x = evx - xx;
+             y = evy - yy;
+             x = (x * x) + (y * y);
+             if ((x < dist) || (!it_closest))
+               {
+                  if (wd->horizontal)
+                    cdv = (double)(xx - bx) / (double)bw; 
+                  else
+                    cdv = (double)(yy - by) / (double)bh;
+                  it_closest = it;
+                  dist = x;
+               }
+          }
+        if ((i == 0) && (wd->level == 0))
+          edje_object_part_drag_value_set(wd->base, "elm.dragable.index.1", 
+                                          cdv, cdv);
+        if (it_closest) it_closest->selected = 1;
+        if (it_closest != it_last)
+          {
+             change = 1;
+             if (it_last)
+               {
+                  const char *stacking, *selectraise;
+
+                  it = it_last;
+                  edje_object_signal_emit(it->base, "elm,state,inactive", "elm");
+                  stacking = edje_object_data_get(it->base, "stacking");
+                  selectraise = edje_object_data_get(it->base, "selectraise");
+                  if ((selectraise) && (!strcmp(selectraise, "on")))
+                    {
+                       if ((stacking) && (!strcmp(stacking, "below")))
+                         evas_object_lower(it->base);
+                    }
+               }
+             if (it_closest)
+               {
+                  const char *selectraise;
+
+                  it = it_closest;
+                  edje_object_signal_emit(it->base, "elm,state,active", "elm");
+                  selectraise = edje_object_data_get(it->base, "selectraise");
+                  if ((selectraise) && (!strcmp(selectraise, "on")))
+                    evas_object_raise(it->base);
+                  evas_object_smart_callback_call((void *)obj, "changed", (void *)it->data);
+                  if (wd->delay) ecore_timer_del(wd->delay);
+                  wd->delay = ecore_timer_add(0.2, _delay_change, obj);
+               }
+          }
+        if (it_closest)
+          {
+             it = it_closest;
+             if (!last)
+               last = strdup(it->letter);
+             else
+               {
+                  if (!label) label = strdup(last);
+                  else
+                    {
+                       label = realloc(label, strlen(label) + strlen(last) + 1);
+                       strcat(label, last);
+                    }
+                  free(last);
+                  last = strdup(it->letter);
+               }
+          }
+     }
+   if (!label) label = strdup("");
+   if (!last) last = strdup("");
+   edje_object_part_text_set(wd->base, "elm.text.body", label);
+   edje_object_part_text_set(wd->base, "elm.text", last);
+   free(label);
+   free(last);
+}
+
+static void 
+_wheel(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+//   Evas_Event_Mouse_Wheel *ev = event_info;
+//   Evas_Object *obj = o;
+   if (!wd) return;
+}
+
+static void 
+_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Event_Mouse_Down *ev = event_info;
+   Evas_Coord x, y;
+   if (!wd) return;
+   if (ev->button != 1) return;
+   wd->down = 1;
+   evas_object_geometry_get(wd->base, &x, &y, NULL, NULL);
+   wd->dx = ev->canvas.x - x;
+   wd->dy = ev->canvas.y - y;
+   elm_index_active_set(data, 1);
+   _sel_eval(data, ev->canvas.x, ev->canvas.y);
+   edje_object_part_drag_value_set(wd->base, "elm.dragable.pointer", 
+                                   wd->dx, wd->dy);
+}
+
+static void 
+_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Event_Mouse_Up *ev = event_info;
+   void *d;
+   if (!wd) return;
+   if (ev->button != 1) return;
+   wd->down = 0;
+   d = (void *)elm_index_item_selected_get(data, wd->level);
+   if (d) evas_object_smart_callback_call(data, "selected", d);
+   elm_index_active_set(data, 0);
+   edje_object_signal_emit(wd->base, "elm,state,level,0", "elm");
+}
+
+static void 
+_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Event_Mouse_Move *ev = event_info;
+   Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
+   char buf[1024];
+   if (!wd) return;
+   if (!wd->down) return;
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   evas_object_geometry_get(wd->base, &x, &y, NULL, NULL);
+   x = ev->cur.canvas.x - x;
+   y = ev->cur.canvas.y - y;
+   dx = x - wd->dx;
+   adx = dx;
+   if (adx < 0) adx = -dx;
+   dy = y - wd->dy;
+   ady = dy;
+   if (ady < 0) ady = -dy;
+   edje_object_part_drag_value_set(wd->base, "elm.dragable.pointer", x, y);
+   if (wd->horizontal)
+     {
+     }
+   else
+     {
+        if (adx > minw)
+          {
+             if (wd->level == 0)
+               { 
+                  wd->level = 1;
+                  snprintf(buf, sizeof(buf), "elm,state,level,%i", wd->level);
+                  edje_object_signal_emit(wd->base, buf, "elm");
+                  evas_object_smart_callback_call(data, "level,up", NULL);
+               }
+          }
+        else
+          {
+             if (wd->level == 1)
+               {
+                  wd->level = 0;
+                  snprintf(buf, sizeof(buf), "elm,state,level,%i", wd->level);
+                  edje_object_signal_emit(wd->base, buf, "elm");
+                  evas_object_smart_callback_call(data, "level,down", NULL);
+               }
+          }
+     }
+   _sel_eval(data, ev->cur.canvas.x, ev->cur.canvas.y);
+}
+
+/**
+ * Add a new index to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Index
+ */
+EAPI Evas_Object *
+elm_index_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas_Object *o;
+   Evas *e;
+   Widget_Data *wd;
+   Evas_Coord minw, minh;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "index");
+   elm_widget_type_set(obj, "index");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   wd->horizontal = EINA_FALSE;
+
+   wd->base = edje_object_add(e);
+   _elm_theme_object_set(obj, wd->base, "index", "base/vertical", "default");
+   elm_widget_resize_object_set(obj, wd->base);
+
+   o = evas_object_rectangle_add(e);
+   wd->event[0] = o;
+   evas_object_color_set(o, 0, 0, 0, 0);
+   minw = minh = 0;
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   evas_object_size_hint_min_set(o, minw, minh);
+   edje_object_part_swallow(wd->base, "elm.swallow.event.0", o);
+   elm_widget_sub_object_add(obj, o);
+   evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_WHEEL, _wheel, obj);
+   evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, obj);
+   evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _mouse_up, obj);
+   evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, obj);
+   evas_object_show(o);
+   if (edje_object_part_exists(wd->base, "elm.swallow.event.1"))
+     {
+        o = evas_object_rectangle_add(e);
+        wd->event[1] = o;
+        evas_object_color_set(o, 0, 0, 0, 0);
+        evas_object_size_hint_min_set(o, minw, minh);
+        edje_object_part_swallow(wd->base, "elm.swallow.event.1", o);
+        elm_widget_sub_object_add(obj, o);
+     }
+
+   wd->bx[0] = evas_object_box_add(e);
+   evas_object_box_layout_set(wd->bx[0], _layout, wd, NULL);
+   elm_widget_sub_object_add(obj, wd->bx[0]);
+   edje_object_part_swallow(wd->base, "elm.swallow.index.0", wd->bx[0]);
+   evas_object_show(wd->bx[0]);
+
+   if (edje_object_part_exists(wd->base, "elm.swallow.index.1"))
+     {
+        wd->bx[1] = evas_object_box_add(e);
+       evas_object_box_layout_set(wd->bx[1], _layout, wd, NULL);
+        elm_widget_sub_object_add(obj, wd->bx[1]);
+        edje_object_part_swallow(wd->base, "elm.swallow.index.1", wd->bx[1]);
+        evas_object_show(wd->bx[1]);
+     }
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Set the active state of the index programatically
+ *
+ * @param obj The index object
+ * @param active The active starte
+ *
+ * @ingroup Index
+ */
+EAPI void
+elm_index_active_set(Evas_Object *obj, Eina_Bool active)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->active == active) return;
+   wd->active = active;
+   wd->level = 0;
+   if (wd->active)
+     {
+        _index_box_clear(obj, wd->bx[1], 1);
+        _index_box_auto_fill(obj, wd->bx[0], 0);
+        edje_object_signal_emit(wd->base, "elm,state,active", "elm");
+     }
+   else
+     edje_object_signal_emit(wd->base, "elm,state,inactive", "elm");
+}
+
+/**
+ * Sets the level of the item.
+ *
+ * @param obj The index object.
+ * @param level To be documented.
+ *
+ * @ingroup Index
+ */
+EAPI void
+elm_index_item_level_set(Evas_Object *obj, int level)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->level == level) return;
+   wd->level = level;
+}
+
+/**
+ * Gets the level of the item.
+ *
+ * @param obj The index object
+ *
+ * @ingroup Index
+ */
+EAPI int
+elm_index_item_level_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   return wd->level;
+}
+
+/**
+ * Returns the selected item.
+ *
+ * @param obj The index object.
+ * @param level to be documented.
+ *
+ * @ingroup Index
+ */
+EAPI const void *
+elm_index_item_selected_get(const Evas_Object *obj, int level)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Eina_List *l;
+   Item *it;
+   if (!wd) return NULL;
+   EINA_LIST_FOREACH(wd->items, l, it)
+     if ((it->selected) && (it->level == level)) return it->data;
+   return NULL;
+}
+
+/**
+ * Appends a new item.
+ *
+ * @param obj The index object.
+ * @param letter Letter under which the item should be indexed
+ * @param item The item to put in the index
+ *
+ * @ingroup Index
+ */
+EAPI void
+elm_index_item_append(Evas_Object *obj, const char *letter, const void *item)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Item *it;
+   if (!wd) return;
+   it = _item_new(obj, letter, item);
+   if (!it) return;
+   wd->items = eina_list_append(wd->items, it);
+   _index_box_clear(obj, wd->bx[wd->level], wd->level);
+}
+
+/**
+ * Prepends a new item.
+ *
+ * @param obj The index object.
+ * @param letter Letter under which the item should be indexed
+ * @param item The item to put in the index
+ *
+ * @ingroup Index
+ */
+EAPI void
+elm_index_item_prepend(Evas_Object *obj, const char *letter, const void *item)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Item *it;
+
+   if (!wd) return;
+   it = _item_new(obj, letter, item);
+   if (!it) return;
+   wd->items = eina_list_prepend(wd->items, it);
+   _index_box_clear(obj, wd->bx[wd->level], wd->level);
+}
+
+/**
+ * Append an item after @p relative in letter @p letter.
+ *
+ * @param obj The index object
+ * @param letter Letter under which the item should be indexed
+ * @param item The item to put in the index
+ * @param relative The item to put @p item after
+ *
+ * @ingroup Index
+ */
+EAPI void
+elm_index_item_append_relative(Evas_Object *obj, const char *letter, const void *item, const void *relative)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Item *it, *it_rel;
+   if (!wd) return;
+   if (!relative)
+     {
+        elm_index_item_append(obj, letter, item);
+        return;
+     }
+   it = _item_new(obj, letter, item);
+   it_rel = _item_find(obj, relative);
+   if (!it_rel)
+     {
+        elm_index_item_append(obj, letter, item);
+        return;
+     }
+   if (!it) return;
+   wd->items = eina_list_append_relative(wd->items, it, it_rel);
+   _index_box_clear(obj, wd->bx[wd->level], wd->level);
+}
+
+/**
+ * Prepend an item before @p relative in letter @p letter.
+ *
+ * @param obj The index object
+ * @param letter Letter under which the item should be indexed
+ * @param item The item to put in the index
+ * @param relative The item to put @p item before
+ *
+ * @ingroup Index
+ */
+EAPI void
+elm_index_item_prepend_relative(Evas_Object *obj, const char *letter, const void *item, const void *relative)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Item *it, *it_rel;
+   if (!wd) return;
+   if (!relative)
+     {
+        elm_index_item_prepend(obj, letter, item);
+        return;
+     }
+   it = _item_new(obj, letter, item);
+   it_rel = _item_find(obj, relative);
+   if (!it_rel)
+     {
+        elm_index_item_append(obj, letter, item);
+        return;
+     }
+   if (!it) return;
+   wd->items = eina_list_prepend_relative(wd->items, it, it_rel);
+   _index_box_clear(obj, wd->bx[wd->level], wd->level);
+}
+
+/**
+ * Remove an item from the index.
+ *
+ * @param obj The index object
+ * @param item The item to remove from the index
+ *
+ * @ingroup Index
+ */
+EAPI void
+elm_index_item_del(Evas_Object *obj, const void *item)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Item *it;
+   if (!wd) return;
+   it = _item_find(obj, item);
+   if (!it) return;
+   _item_free(it);
+   _index_box_clear(obj, wd->bx[wd->level], wd->level);
+}
+
+/**
+ * Clears an index of its items.
+ *
+ * @param obj The index object.
+ *
+ * @ingroup Index
+ */
+EAPI void
+elm_index_item_clear(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Item *it;
+   Eina_List *l, *clear = NULL;
+   if (!wd) return;
+   _index_box_clear(obj, wd->bx[wd->level], wd->level);
+   EINA_LIST_FOREACH(wd->items, l, it)
+     {
+        if (it->level != wd->level) continue;
+        clear = eina_list_append(clear, it);
+     }
+   EINA_LIST_FREE(clear, it) _item_free(it);
+}
+
+/**
+ * Go to item at @p level
+ *
+ * @param obj The index object
+ * @param level The index level
+ *
+ * @ingroup Index
+ */
+EAPI void
+elm_index_item_go(Evas_Object *obj, int level __UNUSED__)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _index_box_auto_fill(obj, wd->bx[0], 0);
+   if (wd->level == 1) _index_box_auto_fill(obj, wd->bx[1], 1);
+}
diff --git a/src/lib/elm_label.c b/src/lib/elm_label.c
new file mode 100644 (file)
index 0000000..ad2b37b
--- /dev/null
@@ -0,0 +1,271 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Label Label
+ *
+ * Display text, with simple html-like markup. The theme of course
+ * can invent new markup tags and style them any way it likes
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *lbl;
+   const char *label;
+   Evas_Coord lastw;
+   Ecore_Job *deferred_recalc_job;
+   Evas_Coord wrap_w;
+   Eina_Bool linewrap : 1;
+   Eina_Bool changed : 1;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+
+static void
+_elm_win_recalc_job(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Coord minw = -1, minh = -1, maxh = -1;
+   Evas_Coord resw, resh, minminw;
+   if (!wd) return;
+   wd->deferred_recalc_job = NULL;
+   evas_object_geometry_get(wd->lbl, NULL, NULL, &resw, &resh);
+   resh = 0;
+   minminw = 0;
+   edje_object_size_min_restricted_calc(wd->lbl, &minw, &minh, 0, 0);
+   minminw = minw;
+   if (wd->wrap_w >= resw) 
+     {
+        resw = wd->wrap_w;
+        edje_object_size_min_restricted_calc(wd->lbl, &minw, &minh, resw, 0);
+        evas_object_size_hint_min_set(data, minw, minh);
+     }
+   else
+     {
+        if (wd->wrap_w > minminw) minminw = wd->wrap_w;
+        edje_object_size_min_restricted_calc(wd->lbl, &minw, &minh, resw, 0);
+        evas_object_size_hint_min_set(data, minminw, minh);
+     }
+   maxh = minh;
+   evas_object_size_hint_max_set(data, -1, maxh);
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->deferred_recalc_job) ecore_job_del(wd->deferred_recalc_job);
+   if (wd->label) eina_stringshare_del(wd->label);
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->linewrap)
+     _elm_theme_object_set(obj, wd->lbl, "label", "base_wrap", elm_widget_style_get(obj));
+   else
+     _elm_theme_object_set(obj, wd->lbl, "label", "base", elm_widget_style_get(obj));
+   edje_object_part_text_set(wd->lbl, "elm.text", wd->label);
+   edje_object_scale_set(wd->lbl, elm_widget_scale_get(obj) * 
+                         _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   Evas_Coord resw, resh;
+   if (!wd) return;
+   if (wd->linewrap)
+     {
+        evas_object_geometry_get(wd->lbl, NULL, NULL, &resw, &resh);
+        if ((resw == wd->lastw) && (!wd->changed)) return;
+        wd->changed = EINA_FALSE;
+        wd->lastw = resw;
+        _elm_win_recalc_job(obj);
+// FIXME: works ok. but NOT for genlist. what should genlist do?        
+//        if (wd->deferred_recalc_job) ecore_job_del(wd->deferred_recalc_job);
+//        wd->deferred_recalc_job = ecore_job_add(_elm_win_recalc_job, obj);
+     }
+   else
+     {
+        evas_object_geometry_get(wd->lbl, NULL, NULL, &resw, &resh);
+        edje_object_size_min_calc(wd->lbl, &minw, &minh);
+        evas_object_size_hint_min_set(obj, minw, minh);
+        maxh = minh;
+        evas_object_size_hint_max_set(obj, maxw, maxh);
+     }
+}
+
+static void 
+_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (wd->linewrap) _sizing_eval(data);
+}
+/**
+ * Add a new label to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Label
+ */
+EAPI Evas_Object *
+elm_label_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "label");
+   elm_widget_type_set(obj, "label");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_can_focus_set(obj, 0);
+
+   wd->linewrap = EINA_FALSE;
+
+   wd->lbl = edje_object_add(e);
+   _elm_theme_object_set(obj, wd->lbl, "label", "base", "default");
+   wd->label = eina_stringshare_add("<br>");
+   edje_object_part_text_set(wd->lbl, "elm.text", "<br>");
+   elm_widget_resize_object_set(obj, wd->lbl);
+   
+   evas_object_event_callback_add(wd->lbl, EVAS_CALLBACK_RESIZE, _resize, obj);
+   
+   wd->changed = 1;
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Set the label on the label object
+ *
+ * @param obj The label object
+ * @param label The label will be used on the label object
+ *
+ * @ingroup Label
+ */
+EAPI void
+elm_label_label_set(Evas_Object *obj, const char *label)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (!label) label = "";
+   eina_stringshare_replace(&wd->label, label);
+   edje_object_part_text_set(wd->lbl, "elm.text", label);
+   wd->changed = 1;
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the label used on the label object
+ *
+ * @param obj The label object
+ * @return The string inside the label
+ * @ingroup Label
+ */
+EAPI const char *
+elm_label_label_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->label;
+}
+
+/**
+ * Set the wrapping behavior of the label
+ *
+ * @param obj The label object
+ * @param wrap To wrap text or not
+ * @ingroup Label
+ */
+EAPI void
+elm_label_line_wrap_set(Evas_Object *obj, Eina_Bool wrap)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   const char *t;
+   if (wd->linewrap == wrap) return;
+   wd->linewrap = wrap;
+   t = eina_stringshare_add(elm_label_label_get(obj));
+   if (wd->linewrap)
+     _elm_theme_object_set(obj, wd->lbl, "label", "base_wrap", elm_widget_style_get(obj));
+   else
+     _elm_theme_object_set(obj, wd->lbl, "label", "base", elm_widget_style_get(obj));
+   elm_label_label_set(obj, t);
+   eina_stringshare_del(t);
+   wd->changed = 1;
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the wrapping behavior of the label
+ *
+ * @param obj The label object
+ * @return To wrap text or not
+ * @ingroup Label
+ */
+EAPI Eina_Bool
+elm_label_line_wrap_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->linewrap;
+}
+
+/**
+ * Set wrap width of the label
+ *
+ * @param obj The label object
+ * @param w The wrap width in pixels at a minimum where words need to wrap
+ * @ingroup Label
+ */
+EAPI void
+elm_label_wrap_width_set(Evas_Object *obj, Evas_Coord w)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->wrap_w == w) return;
+   wd->wrap_w = w;
+   _sizing_eval(obj);
+}
+
+/**
+ * get wrap width of the label
+ *
+ * @param obj The label object
+ * @return The wrap width in pixels at a minimum where words need to wrap
+ * @ingroup Label
+ */
+EAPI Evas_Coord
+elm_label_wrap_width_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   return wd->wrap_w;
+}
diff --git a/src/lib/elm_layout.c b/src/lib/elm_layout.c
new file mode 100644 (file)
index 0000000..9bd273a
--- /dev/null
@@ -0,0 +1,294 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Layout Layout
+ *
+ * This takes a standard Edje design file and wraps it very thinly
+ * in a widget and handles swallowing widgets into swallow regions
+ * in the Edje object, allowing Edje to be used as a design and
+ * layout tool
+ */
+
+typedef struct _Widget_Data Widget_Data;
+typedef struct _Subinfo Subinfo;
+
+struct _Widget_Data
+{
+   Evas_Object *lay;
+   Eina_List *subs;
+   Eina_Bool needs_size_calc:1;
+};
+
+struct _Subinfo
+{
+   const char *swallow;
+   Evas_Object *obj;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Subinfo *si;
+   if (!wd) return;
+   EINA_LIST_FREE(wd->subs, si)
+     {
+       eina_stringshare_del(si->swallow);
+       free(si);
+     }
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   edje_object_scale_set(wd->lay, elm_widget_scale_get(obj) *
+                         _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+static void
+_changed_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->needs_size_calc)
+     {
+       _sizing_eval(obj);
+       wd->needs_size_calc = 0;
+     }
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1;
+   if (!wd) return;
+   edje_object_size_min_calc(wd->lay, &minw, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+static void
+_request_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->needs_size_calc) return;
+   wd->needs_size_calc = 1;
+   evas_object_smart_changed(obj);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _request_sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *sub = event_info;
+   Eina_List *l;
+   Subinfo *si;
+   if (!wd) return;
+   EINA_LIST_FOREACH(wd->subs, l, si)
+     {
+       if (si->obj == sub)
+         {
+            evas_object_event_callback_del_full(sub,
+                                            EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                            _changed_size_hints,
+                                            obj);
+            wd->subs = eina_list_remove_list(wd->subs, l);
+            eina_stringshare_del(si->swallow);
+            free(si);
+            break;
+         }
+     }
+}
+
+static void
+_signal_size_eval(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   _request_sizing_eval(data);
+}
+
+/**
+ * Add a new layout to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Layout
+ */
+EAPI Evas_Object *
+elm_layout_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "layout");
+   elm_widget_type_set(obj, "layout");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_changed_hook_set(obj, _changed_hook);
+
+   wd->lay = edje_object_add(e);
+   elm_widget_resize_object_set(obj, wd->lay);
+   edje_object_signal_callback_add(wd->lay, "size,eval", "elm",
+                                   _signal_size_eval, obj);
+   
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+
+   _request_sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Set the file that will be used as layout
+ *
+ * @param obj The layout object
+ * @param file The path to file (edj) that will be used as layout
+ * @param group The group that the layout belongs in edje file
+ *
+ * @return (1 = sucess, 0 = error)
+ *
+ * @ingroup Layout
+ */
+EAPI Eina_Bool
+elm_layout_file_set(Evas_Object *obj, const char *file, const char *group)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   Eina_Bool ret = edje_object_file_set(wd->lay, file, group);
+   if (ret) _request_sizing_eval(obj);
+   return ret;
+}
+
+/**
+ * Set the edje group from the elementary theme that will be used as layout
+ *
+ * @param obj The layout object
+ * @param clas the clas of the group
+ * @param group the group
+ * @param style the style to used
+ *
+ * @return (1 = sucess, 0 = error)
+ *
+ * @ingroup Layout
+ */
+EAPI Eina_Bool
+elm_layout_theme_set(Evas_Object *obj, const char *clas, const char *group, const char *style)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   Eina_Bool ret = _elm_theme_object_set(obj, wd->lay, clas, group, style);
+   if (ret) _request_sizing_eval(obj);
+   return ret;
+}
+
+/**
+ * Set the layout content
+ *
+ * @param obj The layout object
+ * @param swallow The swallow group name in the edje file
+ * @param content The content will be filled in this layout object
+ *
+ * @ingroup Layout
+ */
+EAPI void
+elm_layout_content_set(Evas_Object *obj, const char *swallow, Evas_Object *content)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Subinfo *si;
+   const Eina_List *l;
+   if (!wd) return;
+   EINA_LIST_FOREACH(wd->subs, l, si)
+     {
+       if (!strcmp(swallow, si->swallow))
+         {
+            if (content == si->obj) return;
+            elm_widget_sub_object_del(obj, si->obj);
+            break;
+         }
+     }
+   if (content)
+     {
+       elm_widget_sub_object_add(obj, content);
+       evas_object_event_callback_add(content,
+                                       EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                      _changed_size_hints, obj);
+       edje_object_part_swallow(wd->lay, swallow, content);
+       si = ELM_NEW(Subinfo);
+       si->swallow = eina_stringshare_add(swallow);
+       si->obj = content;
+       wd->subs = eina_list_append(wd->subs, si);
+       _request_sizing_eval(obj);
+     }
+}
+
+/**
+ * Get the edje layout
+ *
+ * @param obj The layout object
+ * 
+ * This returns the edje object. It is not expected to be used to then swallow
+ * objects via edje_object_part_swallow() for example. Use 
+ * elm_layout_content_set() instead so child object handling and sizing is
+ * done properly. This is more intended for setting text, emitting signals,
+ * hooking to singal callbacks etc.
+ *
+ * @return A Evas_Object with the edje layout settings loaded
+ * with function elm_layout_file_set
+ *
+ * @ingroup Layout
+ */
+EAPI Evas_Object *
+elm_layout_edje_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->lay;
+}
+
+/**
+ * Get the edje layout
+ * 
+ * Manually forms a sizing re-evaluation when contents changed state so that
+ * minimum size might have changed and needs re-evaluation. Also note that
+ * a standard signal of "size,eval" "elm" emitted by the edje object will
+ * cause this to happen too
+ *
+ * @param obj The layout object
+ *
+ * @ingroup Layout
+ */
+EAPI void
+elm_layout_sizing_eval(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   _request_sizing_eval(obj);
+}
diff --git a/src/lib/elm_list.c b/src/lib/elm_list.c
new file mode 100644 (file)
index 0000000..b7844b2
--- /dev/null
@@ -0,0 +1,1498 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup List List
+ *
+ * A list is a very simple type of list widget.  For more robust
+ * lists, @ref Genlist should probably be used.
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *scr, *box, *self;
+   Eina_List *items, *selected, *to_delete;
+   Elm_List_Mode mode;
+   Evas_Coord minw[2], minh[2];
+   int walking;
+   Eina_Bool fix_pending : 1;
+   Eina_Bool on_hold : 1;
+   Eina_Bool multi : 1;
+   Eina_Bool always_select : 1;
+   Eina_Bool longpressed : 1;
+   Eina_Bool wasselected : 1;
+};
+
+struct _Elm_List_Item
+{
+   Eina_List *node;
+   Evas_Object *obj, *base;
+   const char *label;
+   Evas_Object *icon, *end;
+   Evas_Smart_Cb func;
+   Evas_Smart_Cb del_cb;
+   const void *data;
+   Ecore_Timer *long_timer;
+   Eina_Bool deleted : 1;
+   Eina_Bool even : 1;
+   Eina_Bool is_even : 1;
+   Eina_Bool fixed : 1;
+   Eina_Bool selected : 1;
+   Eina_Bool hilighted : 1;
+   Eina_Bool dummy_icon : 1;
+   Eina_Bool dummy_end : 1;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _on_focus_hook(void *data, Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+static void _fix_items(Evas_Object *obj);
+static void _mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info);
+static void _mouse_up(void *data, Evas *evas, Evas_Object *obj, void *event_info);
+static void _mouse_move(void *data, Evas *evas, Evas_Object *obj, void *event_info);
+
+#define ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, ...)                    \
+  if (!it)                                                             \
+    {                                                                  \
+       fprintf(stderr, "ERROR: %s:%d:%s() "#it" is NULL.\n",           \
+              __FILE__, __LINE__, __FUNCTION__);                       \
+       return __VA_ARGS__;                                             \
+    }                                                                  \
+  else if (it->deleted)                                                \
+    {                                                                  \
+       fprintf(stderr, "ERROR: %s:%d:%s() "#it" has been DELETED.\n",  \
+              __FILE__, __LINE__, __FUNCTION__);                       \
+       return __VA_ARGS__;                                             \
+    }
+
+
+
+static inline void
+_elm_list_item_call_del_cb(Elm_List_Item *it)
+{
+   if (it->del_cb) it->del_cb((void *)it->data, it->obj, it);
+}
+
+static inline void
+_elm_list_item_free(Elm_List_Item *it)
+{
+   evas_object_event_callback_del_full
+     (it->base, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, it);
+   evas_object_event_callback_del_full
+     (it->base, EVAS_CALLBACK_MOUSE_UP, _mouse_up, it);
+   evas_object_event_callback_del_full
+     (it->base, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, it);
+
+   if (it->icon)
+     evas_object_event_callback_del_full
+       (it->icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+       _changed_size_hints, it->obj);
+
+   if (it->end)
+     evas_object_event_callback_del_full
+       (it->end, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+       _changed_size_hints, it->obj);
+
+   eina_stringshare_del(it->label);
+
+   if (it->long_timer) ecore_timer_del(it->long_timer);
+   if (it->icon) evas_object_del(it->icon);
+   if (it->end) evas_object_del(it->end);
+   if (it->base) evas_object_del(it->base);
+   free(it);
+}
+
+static void
+_elm_list_process_deletions(Widget_Data *wd)
+{
+   Elm_List_Item *it;
+
+   wd->walking++; // avoid nested deletion and also _sub_del() fix_items
+
+   EINA_LIST_FREE(wd->to_delete, it)
+     {
+       _elm_list_item_call_del_cb(it);
+
+       wd->items = eina_list_remove_list(wd->items, it->node);
+       _elm_list_item_free(it);
+     }
+
+   wd->walking--;
+}
+
+static inline void
+_elm_list_walk(Widget_Data *wd)
+{
+   if (wd->walking < 0)
+     {
+       fprintf(stderr, "ERROR: walking was negative. fixed!\n");
+       wd->walking = 0;
+     }
+   wd->walking++;
+}
+
+static inline void
+_elm_list_unwalk(Widget_Data *wd)
+{
+   wd->walking--;
+   if (wd->walking < 0)
+     {
+       fprintf(stderr, "ERROR: walking became negative. fixed!\n");
+       wd->walking = 0;
+     }
+
+   if (wd->walking)
+     return;
+
+   if (wd->to_delete)
+     _elm_list_process_deletions(wd);
+
+   if (wd->fix_pending)
+     {
+       wd->fix_pending = EINA_FALSE;
+       _fix_items(wd->self);
+       _sizing_eval(wd->self);
+     }
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_List_Item *it;
+   Eina_List *n;
+
+   if (!wd) return;
+   if (wd->walking != 0)
+     fprintf(stderr, "ERROR: list deleted while walking.\n");
+
+   _elm_list_walk(wd);
+   EINA_LIST_FOREACH(wd->items, n, it) _elm_list_item_call_del_cb(it);
+   _elm_list_unwalk(wd);
+   if (wd->to_delete) fprintf(stderr, "ERROR: leaking nodes!\n");
+
+   EINA_LIST_FREE(wd->items, it) _elm_list_item_free(it);
+   eina_list_free(wd->selected);
+   free(wd);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   if (!wd) return;
+   if (wd->scr)
+     {
+        evas_object_size_hint_min_get(wd->scr, &minw, &minh);
+        evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
+        evas_object_size_hint_min_set(obj, minw, minh);
+        evas_object_size_hint_max_set(obj, maxw, maxh);
+     }
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_List_Item *it;
+   Eina_List *n;
+   
+   if (!wd) return;
+   if (wd->scr)
+     {
+        elm_scroller_custom_widget_base_theme_set(wd->scr, "list", "base");
+        elm_object_style_set(wd->scr, elm_widget_style_get(obj));
+//        edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
+     }
+   EINA_LIST_FOREACH(wd->items, n, it)
+     {
+        it->fixed = 0;
+     }
+   _fix_items(obj);
+   _sizing_eval(obj);
+}
+
+static void
+_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (elm_widget_focus_get(obj))
+     evas_object_focus_set(wd->scr, 1);
+   else
+     evas_object_focus_set(wd->scr, 0);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+//   _fix_items(data);
+//   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *sub = event_info;
+   const Eina_List *l;
+   Elm_List_Item *it;
+
+   if (!wd) return;
+   if (sub == NULL) abort();
+   if (sub == wd->scr)
+     wd->scr = NULL;
+   else
+     {
+        EINA_LIST_FOREACH(wd->items, l, it)
+          {
+             if ((sub == it->icon) || (sub == it->end))
+               {
+                  if (it->icon == sub) it->icon = NULL;
+                  if (it->end == sub) it->end = NULL;
+                  evas_object_event_callback_del_full
+                    (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, 
+                     obj);
+                  if (!wd->walking)
+                    {
+                       _fix_items(obj);
+                       _sizing_eval(obj);
+                    }
+                  else
+                    wd->fix_pending = EINA_TRUE;
+                  break;
+               }
+          }
+     }
+}
+
+static void
+_item_hilight(Elm_List_Item *it)
+{
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+   const char *selectraise;
+
+   if (!wd) return;
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it);
+   if (it->hilighted) return;
+   _elm_list_walk(wd);
+
+   edje_object_signal_emit(it->base, "elm,state,selected", "elm");
+   selectraise = edje_object_data_get(it->base, "selectraise");
+   if ((selectraise) && (!strcmp(selectraise, "on")))
+     evas_object_raise(it->base);
+   it->hilighted = EINA_TRUE;
+
+   _elm_list_unwalk(wd);
+}
+
+static void
+_item_select(Elm_List_Item *it)
+{
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+
+   if (!wd) return;
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it);
+   if (it->selected)
+     {
+       if (wd->always_select) goto call;
+       return;
+     }
+   it->selected = EINA_TRUE;
+   wd->selected = eina_list_append(wd->selected, it);
+   call:
+   _elm_list_walk(wd);
+
+   if (it->func) it->func((void *)it->data, it->obj, it);
+   evas_object_smart_callback_call(it->obj, "selected", it);
+
+   _elm_list_unwalk(wd);
+}
+
+static void
+_item_unselect(Elm_List_Item *it)
+{
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+   const char *stacking, *selectraise;
+
+   if (!wd) return;
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it);
+   if (!it->hilighted) return;
+   _elm_list_walk(wd);
+
+   edje_object_signal_emit(it->base, "elm,state,unselected", "elm");
+   stacking = edje_object_data_get(it->base, "stacking");
+   selectraise = edje_object_data_get(it->base, "selectraise");
+   if ((selectraise) && (!strcmp(selectraise, "on")))
+     {
+       if ((stacking) && (!strcmp(stacking, "below")))
+         evas_object_lower(it->base);
+     }
+   it->hilighted = EINA_FALSE;
+   if (it->selected)
+     {
+       it->selected = EINA_FALSE;
+       wd->selected = eina_list_remove(wd->selected, it);
+       evas_object_smart_callback_call(it->obj, "unselected", it);
+     }
+
+   _elm_list_unwalk(wd);
+}
+
+static void
+_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Elm_List_Item *it = data;
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+   Evas_Event_Mouse_Move *ev = event_info;
+
+   if (!wd) return;
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it);
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
+     {
+       if (!wd->on_hold)
+         {
+            wd->on_hold = EINA_TRUE;
+             if (it->long_timer)
+               {
+                  ecore_timer_del(it->long_timer);
+                  it->long_timer = NULL;
+               }
+            _item_unselect(it);
+         }
+     }
+}
+
+static int
+_long_press(void *data)
+{
+   Elm_List_Item *it = data;
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+
+   if (!wd) return 0;
+   it->long_timer = NULL;
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, 0);
+   wd->longpressed = EINA_TRUE;
+   evas_object_smart_callback_call(it->obj, "longpressed", it);
+   return 0;
+}
+
+static void
+_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Elm_List_Item *it = data;
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+   Evas_Event_Mouse_Down *ev = event_info;
+
+   if (!wd) return;
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it);
+   if (ev->button != 1) return;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) wd->on_hold = EINA_TRUE;
+   else wd->on_hold = EINA_FALSE;
+   wd->wasselected = it->selected;
+   _item_hilight(it);
+   wd->longpressed = EINA_FALSE;
+   if (it->long_timer) ecore_timer_del(it->long_timer);
+   it->long_timer = ecore_timer_add(1.0, _long_press, it);
+   /* Always call the callbacks last - the user may delete our context! */
+   if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
+     evas_object_smart_callback_call(it->obj, "clicked", it);
+}
+
+static void
+_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Elm_List_Item *it = data;
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+   Evas_Event_Mouse_Up *ev = event_info;
+
+   if (!wd) return;
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it);
+   if (ev->button != 1) return;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) wd->on_hold = EINA_TRUE;
+   else wd->on_hold = EINA_FALSE;
+   wd->longpressed = EINA_FALSE;
+   if (it->long_timer)
+     {
+        ecore_timer_del(it->long_timer);
+        it->long_timer = NULL;
+     }
+   if (wd->on_hold)
+     {
+       wd->on_hold = EINA_FALSE;
+       return;
+     }
+   if (wd->longpressed)
+     {
+        if (!wd->wasselected) _item_unselect(it);
+        wd->wasselected = 0;
+        return;
+     }
+
+   _elm_list_walk(wd); // watch out "return" before unwalk!
+
+   if (wd->multi)
+     {
+       if (!it->selected)
+         {
+            _item_hilight(it);
+            _item_select(it);
+         }
+       else _item_unselect(it);
+     }
+   else
+     {
+       if (!it->selected)
+         {
+            while (wd->selected)
+              _item_unselect(wd->selected->data);
+            _item_hilight(it);
+            _item_select(it);
+         }
+       else
+         {
+            const Eina_List *l, *l_next;
+            Elm_List_Item *it2;
+
+            EINA_LIST_FOREACH_SAFE(wd->selected, l, l_next, it2)
+              if (it2 != it) _item_unselect(it2);
+            _item_hilight(it);
+            _item_select(it);
+         }
+     }
+
+   _elm_list_unwalk(wd);
+}
+
+static Elm_List_Item *
+_item_new(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_List_Item *it;
+
+   if (!wd) return NULL;
+   it = calloc(1, sizeof(Elm_List_Item));
+   it->obj = obj;
+   it->label = eina_stringshare_add(label);
+   it->icon = icon;
+   it->end = end;
+   it->func = func;
+   it->data = data;
+   it->base = edje_object_add(evas_object_evas_get(obj));
+   evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_DOWN,
+                                 _mouse_down, it);
+   evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_UP,
+                                 _mouse_up, it);
+   evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_MOVE,
+                                 _mouse_move, it);
+   evas_object_size_hint_weight_set(it->base, 1.0, 1.0);
+   evas_object_size_hint_align_set(it->base, -1.0, -1.0);
+   if (it->icon)
+     {
+       elm_widget_sub_object_add(obj, it->icon);
+       evas_object_event_callback_add(it->icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                      _changed_size_hints, obj);
+     }
+   if (it->end)
+     {
+       elm_widget_sub_object_add(obj, it->end);
+       evas_object_event_callback_add(it->end, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                      _changed_size_hints, obj);
+     }
+   return it;
+}
+
+static void
+_fix_items(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   const Eina_List *l;
+   Elm_List_Item *it;
+   Evas_Coord minw[2] = { 0, 0 }, minh[2] = { 0, 0 };
+   Evas_Coord mw, mh;
+   int i, redo = 0;
+   const char *style = elm_widget_style_get(obj);
+
+   if (!wd) return;
+   if (wd->walking)
+     {
+       wd->fix_pending = EINA_TRUE;
+       return;
+     }
+
+   _elm_list_walk(wd); // watch out "return" before unwalk!
+
+   EINA_LIST_FOREACH(wd->items, l, it)
+     {
+       if (it->deleted) continue;
+       if (it->icon)
+         {
+            evas_object_size_hint_min_get(it->icon, &mw, &mh);
+            if (mw > minw[0]) minw[0] = mw;
+            if (mh > minh[0]) minh[0] = mh;
+         }
+       if (it->end)
+         {
+            evas_object_size_hint_min_get(it->end, &mw, &mh);
+            if (mw > minw[1]) minw[1] = mw;
+            if (mh > minh[1]) minh[1] = mh;
+         }
+     }
+   if ((minw[0] != wd->minw[0]) || (minw[1] != wd->minw[1]) ||
+       (minw[0] != wd->minh[0]) || (minh[1] != wd->minh[1]))
+     {
+       wd->minw[0] = minw[0];
+       wd->minw[1] = minw[1];
+       wd->minh[0] = minh[0];
+       wd->minh[1] = minh[1];
+       redo = 1;
+     }
+   i = 0;
+   EINA_LIST_FOREACH(wd->items, l, it)
+     {
+       if (it->deleted) continue;
+       it->even = i & 0x1;
+       if ((it->even != it->is_even) || (!it->fixed) || (redo))
+         {
+            const char *stacking;
+
+            if (wd->mode == ELM_LIST_COMPRESS)
+              {
+                 if (it->even)
+                   _elm_theme_object_set(obj, it->base, "list", "item_compress", style);
+                 else
+                   _elm_theme_object_set(obj, it->base, "list", "item_compress_odd", style);
+              }
+            else
+              {
+                 if (it->even)
+                   _elm_theme_object_set(obj, it->base, "list", "item", style);
+                 else
+                   _elm_theme_object_set(obj, it->base, "list", "item_odd", style);
+              }
+            stacking = edje_object_data_get(it->base, "stacking");
+            if (stacking)
+              {
+                 if (!strcmp(stacking, "below"))
+                   evas_object_lower(it->base);
+                 else if (!strcmp(stacking, "above"))
+                   evas_object_raise(it->base);
+              }
+            edje_object_part_text_set(it->base, "elm.text", it->label);
+            if ((!it->icon) && (minh[0] > 0))
+              {
+                 it->icon = evas_object_rectangle_add(evas_object_evas_get(it->base));
+                 evas_object_color_set(it->icon, 0, 0, 0, 0);
+                 it->dummy_icon = EINA_TRUE;
+              }
+            if ((!it->end) && (minh[1] > 0))
+              {
+                 it->end = evas_object_rectangle_add(evas_object_evas_get(it->base));
+                 evas_object_color_set(it->end, 0, 0, 0, 0);
+                 it->dummy_end = EINA_TRUE;
+              }
+            if (it->icon)
+              {
+                 evas_object_size_hint_min_set(it->icon, minw[0], minh[0]);
+                 evas_object_size_hint_max_set(it->icon, 99999, 99999);
+                 edje_object_part_swallow(it->base, "elm.swallow.icon", it->icon);
+              }
+            if (it->end)
+              {
+                 evas_object_size_hint_min_set(it->end, minw[1], minh[1]);
+                 evas_object_size_hint_max_set(it->end, 99999, 99999);
+                 edje_object_part_swallow(it->base, "elm.swallow.end", it->end);
+              }
+            if (!it->fixed)
+              {
+                 // this may call up user and it may modify the list item
+                 // but we're safe as we're flagged as walking.
+                 // just don't process further
+                 edje_object_message_signal_process(it->base);
+                 if (it->deleted)
+                   continue;
+                 mw = mh = -1;
+                 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
+                 edje_object_size_min_restricted_calc(it->base, &mw, &mh, mw, mh);
+                 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
+                 evas_object_size_hint_min_set(it->base, mw, mh);
+                 evas_object_show(it->base);
+              }
+            if ((it->selected) || (it->hilighted))
+              {
+                 const char *selectraise;
+
+                 // this may call up user and it may modify the list item
+                 // but we're safe as we're flagged as walking.
+                 // just don't process further
+                 edje_object_signal_emit(it->base, "elm,state,selected", "elm");
+                 if (it->deleted)
+                   continue;
+
+                 selectraise = edje_object_data_get(it->base, "selectraise");
+                 if ((selectraise) && (!strcmp(selectraise, "on")))
+                   evas_object_raise(it->base);
+                 stacking = edje_object_data_get(it->base, "stacking");
+              }
+            it->fixed = EINA_TRUE;
+            it->is_even = it->even;
+         }
+       i++;
+     }
+
+   _elm_list_unwalk(wd);
+
+   mw = 0; mh = 0;
+   evas_object_size_hint_min_get(wd->box, &mw, &mh);
+   if (wd->scr)
+     {
+        if (wd->mode == ELM_LIST_LIMIT)
+          elm_scroller_content_min_limit(wd->scr, 1, 0);
+        else
+          elm_scroller_content_min_limit(wd->scr, 0, 0);
+     }
+   _sizing_eval(obj);
+}
+
+static void
+_hold_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->scr)
+     elm_widget_scroll_hold_push(wd->scr);
+}
+
+static void
+_hold_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->scr)
+     elm_widget_scroll_hold_pop(wd->scr);
+}
+
+static void
+_freeze_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->scr)
+     elm_widget_scroll_hold_push(wd->scr);
+}
+
+static void
+_freeze_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->scr)
+     elm_widget_scroll_hold_pop(wd->scr);
+}
+
+/**
+ * Adds a list object.
+ *
+ * @param parent The parent object
+ * @return The created object or NULL upon failure
+ *
+ * @ingroup List
+ */
+EAPI Evas_Object *
+elm_list_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   wd->self = obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "list");
+   elm_widget_type_set(obj, "list");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_can_focus_set(obj, 1);
+
+   wd->scr = elm_scroller_add(parent);
+   elm_scroller_custom_widget_base_theme_set(wd->scr, "list", "base");
+   elm_widget_resize_object_set(obj, wd->scr);
+
+   elm_scroller_bounce_set(wd->scr, 0, 1);
+
+   wd->box = elm_box_add(parent);
+   elm_box_homogenous_set(wd->box, 1);
+   evas_object_size_hint_weight_set(wd->box, 1.0, 0.0);
+   evas_object_size_hint_align_set(wd->box, -1.0, 0.0);
+   elm_scroller_content_set(wd->scr, wd->box);
+   evas_object_show(wd->box);
+
+   wd->mode = ELM_LIST_SCROLL;
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+   evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
+   evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
+   evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
+   evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Appends an item to the list object.
+ *
+ * @param obj The list object
+ * @param label The label of the list item
+ * @param icon The icon object to use for the left side of the item
+ * @param end The icon object to use for the right side of the item
+ * @param func The function to call when the item is clicked
+ * @param data The data to associate with the item for related callbacks
+ *
+ * @return The created item or NULL upon failure
+ *
+ * @ingroup List
+ */
+EAPI Elm_List_Item *
+elm_list_item_append(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_List_Item *it = _item_new(obj, label, icon, end, func, data);
+
+   wd->items = eina_list_append(wd->items, it);
+   it->node = eina_list_last(wd->items);
+   elm_box_pack_end(wd->box, it->base);
+   return it;
+}
+
+/**
+ * Prepends an item to the list object.
+ *
+ * @param obj The list object
+ * @param label The label of the list item
+ * @param icon The icon object to use for the left side of the item
+ * @param end The icon object to use for the right side of the item
+ * @param func The function to call when the item is clicked
+ * @param data The data to associate with the item for related callbacks
+ *
+ * @return The created item or NULL upon failure
+ *
+ * @ingroup List
+ */
+EAPI Elm_List_Item *
+elm_list_item_prepend(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_List_Item *it = _item_new(obj, label, icon, end, func, data);
+
+   wd->items = eina_list_prepend(wd->items, it);
+   it->node = wd->items;
+   elm_box_pack_start(wd->box, it->base);
+   return it;
+}
+
+/**
+ * Inserts an item into the list object before @p before.
+ *
+ * @param obj The list object
+ * @param before The list item to insert before
+ * @param label The label of the list item
+ * @param icon The icon object to use for the left side of the item
+ * @param end The icon object to use for the right side of the item
+ * @param func The function to call when the item is clicked
+ * @param data The data to associate with the item for related callbacks
+ *
+ * @return The created item or NULL upon failure
+ *
+ * @ingroup List
+ */
+EAPI Elm_List_Item *
+elm_list_item_insert_before(Evas_Object *obj, Elm_List_Item *before, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data)
+{
+   Widget_Data *wd;
+   Elm_List_Item *it;
+
+   if ((!before) || (!before->node)) return NULL;
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(before, NULL);
+
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   it = _item_new(obj, label, icon, end, func, data);
+   wd->items = eina_list_prepend_relative_list(wd->items, it, before->node);
+   it->node = before->node->prev;
+   elm_box_pack_before(wd->box, it->base, before->base);
+   return it;
+}
+
+/**
+ * Inserts an item into the list object after @p after.
+ *
+ * @param obj The list object
+ * @param after The list item to insert after
+ * @param label The label of the list item
+ * @param icon The icon object to use for the left side of the item
+ * @param end The icon object to use for the right side of the item
+ * @param func The function to call when the item is clicked
+ * @param data The data to associate with the item for related callbacks
+ *
+ * @return The created item or NULL upon failure
+ *
+ * @ingroup List
+ */
+EAPI Elm_List_Item *
+elm_list_item_insert_after(Evas_Object *obj, Elm_List_Item *after, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data)
+{
+   Widget_Data *wd;
+   Elm_List_Item *it;
+
+   if ((!after) || (!after->node)) return NULL;
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(after, NULL);
+
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   it = _item_new(obj, label, icon, end, func, data);
+   wd->items = eina_list_append_relative_list(wd->items, it, after->node);
+   it->node = after->node->next;
+   elm_box_pack_after(wd->box, it->base, after->base);
+   return it;
+}
+
+/**
+ * Insert a new item into the sorted list object.
+ *
+ * @param obj The list object
+ * @param label The label of the list item
+ * @param icon The icon object to use for the left side of the item
+ * @param end The icon object to use for the right side of the item
+ * @param func The function to call when the item is clicked
+ * @param data The data to associate with the item for related callbacks
+ * @param cmp_func The function called for the sort.
+ *
+ * @return The created item or NULL upon failure
+ *
+ * @ingroup List
+ */
+EAPI Elm_List_Item *
+elm_list_item_sorted_insert(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Object *end, Evas_Smart_Cb func, const void *data, Eina_Compare_Cb cmp_func)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_List_Item *it = _item_new(obj, label, icon, end, func, data);
+   Eina_List *l;
+
+   wd->items = eina_list_sorted_insert(wd->items, cmp_func, it);
+   l = eina_list_data_find_list(wd->items, it);
+   l = eina_list_next(l);
+   if (!l)
+     {
+       it->node = eina_list_last(wd->items);
+       elm_box_pack_end(wd->box, it->base);
+     }
+   else
+     {
+       Elm_List_Item *before = eina_list_data_get(l);
+       it->node = before->node->prev;
+       elm_box_pack_before(wd->box, it->base, before->base);
+     }
+   return it;
+}
+
+/**
+ * Clears a list of all items.
+ *
+ * @param obj The list object
+ *
+ * @ingroup List
+ */
+EAPI void
+elm_list_clear(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_List_Item *it;
+
+   if (!wd) return;
+   if (!wd->items) return;
+
+   eina_list_free(wd->selected);
+   wd->selected = NULL;
+
+   if (wd->walking > 0)
+     {
+       Eina_List *n;
+        
+       EINA_LIST_FOREACH(wd->items, n, it)
+         {
+            if (it->deleted) continue;
+            it->deleted = EINA_TRUE;
+            wd->to_delete = eina_list_append(wd->to_delete, it);
+         }
+       return;
+     }
+
+   _elm_list_walk(wd);
+
+   EINA_LIST_FREE(wd->items, it)
+     {
+       _elm_list_item_call_del_cb(it);
+       _elm_list_item_free(it);
+     }
+
+   _elm_list_unwalk(wd);
+
+   _fix_items(obj);
+   _sizing_eval(obj);
+}
+
+/**
+ * Starts the list.  Call before running show() on the list object.
+ *
+ * @param obj The list object
+ *
+ * @ingroup List
+ */
+EAPI void
+elm_list_go(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _fix_items(obj);
+}
+
+/**
+ * Enables/disables the state of multi-select on the list object.
+ *
+ * @param obj The list object
+ * @param multi If true, multi-select is enabled
+ *
+ * @ingroup List
+ */
+EAPI void
+elm_list_multi_select_set(Evas_Object *obj, Eina_Bool multi)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->multi = multi;
+}
+
+/**
+ * Gets the state of multi-select on the list object.
+ *
+ * @param obj The list object
+ * @return If true, multi-select is enabled
+ *
+ * @ingroup List
+ */
+EAPI Eina_Bool
+elm_list_multi_select_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->multi;
+}
+
+/**
+ * Enables/disables horizontal mode of the list
+ *
+ * @param obj The list object
+ * @param mode If true, horizontale mode is enabled
+ *
+ * @ingroup List
+ */
+EAPI void
+elm_list_horizontal_mode_set(Evas_Object *obj, Elm_List_Mode mode)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->mode == mode) return;
+   wd->mode = mode;
+   if (wd->scr)
+     {
+        if (wd->mode == ELM_LIST_LIMIT)
+          elm_scroller_content_min_limit(wd->scr, 1, 0);
+        else
+          elm_scroller_content_min_limit(wd->scr, 0, 0);
+     }
+}
+
+/**
+ * Gets the state of horizontal mode of the list
+ *
+ * @param obj The list object
+ * @return If true, horizontale mode is enabled
+ *
+ * @ingroup List
+ */
+EAPI Elm_List_Mode
+elm_list_horizontal_mode_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_SCROLL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return ELM_LIST_SCROLL;
+   return wd->mode;
+}
+
+/**
+ * Enables/disables the state of always_select, meaning that
+ * an item will always be selected.
+ *
+ * @param obj The list object
+ * @param always_select If true, always_select is enabled
+ *
+ * @ingroup List
+ */
+EAPI void
+elm_list_always_select_mode_set(Evas_Object *obj, Eina_Bool always_select)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->always_select = always_select;
+}
+
+/**
+ * Gets the state of always_select.
+ * See also elm_list_always_select_mode_set()
+ *
+ * @param obj The list object
+ * @return If true, always_select is enabled
+ *
+ * @ingroup List
+ */
+EAPI Eina_Bool
+elm_list_always_select_mode_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->always_select;
+}
+
+/**
+ * Returns a list of all the list items.
+ *
+ * @param obj The list object
+ * @return An Eina_List* of the list items, or NULL on failure
+ *
+ * @ingroup List
+ */
+EAPI const Eina_List *
+elm_list_items_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->items;
+}
+
+/**
+ * Returns the currently selected list item.
+ *
+ * @param obj The list object
+ * @return The selected list item, or NULL on failure
+ *
+ * @ingroup List
+ */
+EAPI Elm_List_Item *
+elm_list_selected_item_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   if (wd->selected) return wd->selected->data;
+   return NULL;
+}
+
+/**
+ * Returns a list of the currently selected list items.
+ *
+ * @param obj The list object
+ * @return An Eina_List* of the selected list items, or NULL on failure
+ *
+ * @ingroup List
+ */
+EAPI const Eina_List *
+elm_list_selected_items_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->selected;
+}
+
+/**
+ * Sets the selected state of @p it.
+ *
+ * @param it The list item
+ * @param selected Enables/disables the selected state
+ *
+ * @ingroup List
+ */
+EAPI void
+elm_list_item_selected_set(Elm_List_Item *it, Eina_Bool selected)
+{
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+   if (!wd) return;
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it);
+   selected = !!selected;
+   if (it->selected == selected) return;
+
+   _elm_list_walk(wd);
+
+   if (selected)
+     {
+       if (!wd->multi)
+         {
+            while (wd->selected)
+              _item_unselect(wd->selected->data);
+         }
+       _item_hilight(it);
+       _item_select(it);
+     }
+   else
+     _item_unselect(it);
+
+   _elm_list_unwalk(wd);
+}
+
+/**
+ * Gets the selected state of @p it.
+ *
+ * @param it The list item
+ * @return If true, the item is selected
+ *
+ * @ingroup List
+ */
+EAPI Eina_Bool
+elm_list_item_selected_get(Elm_List_Item *it)
+{
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, EINA_FALSE);
+   return it->selected;
+}
+
+/**
+ * Brings @p it to the center of the list view.
+ *
+ * @param it The list item
+ *
+ * @ingroup List
+ */
+EAPI void
+elm_list_item_show(Elm_List_Item *it)
+{
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+   Evas_Coord bx, by, bw, bh;
+   Evas_Coord x, y, w, h;
+
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it);
+   evas_object_geometry_get(wd->box, &bx, &by, &bw, &bh);
+   evas_object_geometry_get(it->base, &x, &y, &w, &h);
+   x -= bx;
+   y -= by;
+   if (wd->scr)
+     elm_scroller_region_show(wd->scr, x, y, w, h);
+}
+
+/**
+ * Deletes item @p it from the list.
+ *
+ * @param it The list item to delete
+ *
+ * @ingroup List
+ */
+EAPI void
+elm_list_item_del(Elm_List_Item *it)
+{
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+   if (!wd) return;
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it);
+
+   if (it->selected) _item_unselect(it);
+
+   if (wd->walking > 0)
+     {
+       if (it->deleted) return;
+       it->deleted = EINA_TRUE;
+       wd->to_delete = eina_list_append(wd->to_delete, it);
+       return;
+     }
+
+   wd->items = eina_list_remove_list(wd->items, it->node);
+
+   _elm_list_walk(wd);
+
+   _elm_list_item_call_del_cb(it);
+   _elm_list_item_free(it);
+
+   _elm_list_unwalk(wd);
+}
+
+/**
+ * Set the function called when a list item is freed.
+ *
+ * @param it The item to set the callback on
+ * @param func The function called
+ *
+ * @ingroup List
+ */
+EAPI void
+elm_list_item_del_cb_set(Elm_List_Item *it, Evas_Smart_Cb func)
+{
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it);
+   it->del_cb = func;
+}
+
+/**
+ * Returns the data associated with the item.
+ *
+ * @param it The list item
+ * @return The data associated with @p it
+ *
+ * @ingroup List
+ */
+EAPI void *
+elm_list_item_data_get(const Elm_List_Item *it)
+{
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, NULL);
+   return (void *)it->data;
+}
+
+/**
+ * Returns the left side icon associated with the item.
+ *
+ * @param it The list item
+ * @return The left side icon associated with @p it
+ *
+ * @ingroup List
+ */
+EAPI Evas_Object *
+elm_list_item_icon_get(const Elm_List_Item *it)
+{
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, NULL);
+   if (it->dummy_icon) return NULL;
+   return it->icon;
+}
+
+/**
+ * Sets the left side icon associated with the item.
+ *
+ * @param it The list item
+ * @param icon The left side icon object to associate with @p it
+ *
+ * @ingroup List
+ */
+EAPI void
+elm_list_item_icon_set(Elm_List_Item *it, Evas_Object *icon)
+{
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it);
+   if (it->icon == icon) return;
+   if (it->dummy_icon && !icon) return;
+   if (it->dummy_icon) evas_object_del(it->icon);
+   if (!icon)
+     {
+       icon = evas_object_rectangle_add(evas_object_evas_get(it->obj));
+       evas_object_color_set(icon, 0, 0, 0, 0);
+       it->dummy_icon = EINA_TRUE;
+     }
+   it->icon = icon;
+   if (it->base)
+     edje_object_part_swallow(it->base, "elm.swallow.icon", icon);
+}
+
+/**
+ * Gets the right side icon associated with the item.
+ *
+ * @param it The list item
+ * @return The right side icon object associated with @p it
+ *
+ * @ingroup List
+ */
+EAPI Evas_Object *
+elm_list_item_end_get(const Elm_List_Item *it)
+{
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, NULL);
+   if (it->dummy_end) return NULL;
+   return it->end;
+}
+
+/**
+ * Gets the right side icon associated with the item.
+ *
+ * @param it The list item
+ * @param icon The right side icon object to associate with @p it
+ *
+ * @ingroup List
+ */
+EAPI void
+elm_list_item_end_set(Elm_List_Item *it, Evas_Object *end)
+{
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it);
+   if (it->end == end) return;
+   if (it->dummy_end && !end) return;
+   if (it->dummy_end) evas_object_del(it->end);
+   if (!end)
+     {
+       end = evas_object_rectangle_add(evas_object_evas_get(it->obj));
+       evas_object_color_set(end, 0, 0, 0, 0);
+       it->dummy_end = EINA_TRUE;
+     }
+   it->end = end;
+   if (it->base)
+     edje_object_part_swallow(it->base, "elm.swallow.end", end);
+}
+
+/**
+ * Gets the base object of the item.
+ *
+ * @param it The list item
+ * @return The base object associated with @p it
+ *
+ * @ingroup List
+ */
+EAPI Evas_Object *
+elm_list_item_base_get(const Elm_List_Item *it)
+{
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, NULL);
+   return it->base;
+}
+
+/**
+ * Gets the label of the item.
+ *
+ * @param it The list item
+ * @return The label of @p it
+ *
+ * @ingroup List
+ */
+EAPI const char *
+elm_list_item_label_get(const Elm_List_Item *it)
+{
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, NULL);
+   return it->label;
+}
+
+/**
+ * Sets the label of the item.
+ *
+ * @param it The list item
+ * @param text The label of @p it
+ *
+ * @ingroup List
+ */
+EAPI void
+elm_list_item_label_set(Elm_List_Item *it, const char *text)
+{
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it);
+   if (!eina_stringshare_replace(&it->label, text)) return;
+   if (it->base)
+     edje_object_part_text_set(it->base, "elm.text", it->label);
+}
+
+/**
+ * Gets the item before @p it in the list.
+ *
+ * @param it The list item
+ * @return The item before @p it, or NULL on failure
+ *
+ * @ingroup List
+ */
+EAPI Elm_List_Item *
+elm_list_item_prev(const Elm_List_Item *it)
+{
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, NULL);
+   if (it->node->prev) return it->node->prev->data;
+   else return NULL;
+}
+
+/**
+ * Gets the item after @p it in the list.
+ *
+ * @param it The list item
+ * @return The item after @p it, or NULL on failure
+ *
+ * @ingroup List
+ */
+EAPI Elm_List_Item *
+elm_list_item_next(const Elm_List_Item *it)
+{
+   ELM_LIST_ITEM_CHECK_DELETED_RETURN(it, NULL);
+   if (it->node->next) return it->node->next->data;
+   else return NULL;
+}
+
+/**
+ * Set bounce mode
+ *
+ * This will enable or disable the scroller bounce mode for the list. See
+ * elm_scroller_bounce_set() for details
+ *
+ * @param obj The list object
+ * @param h_bounce Allow bounce horizontally
+ * @param v_bounce Allow bounce vertically
+ *
+ * @ingroup List
+ */
+EAPI void
+elm_list_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->scr)
+     elm_scroller_bounce_set(wd->scr, h_bounce, v_bounce);
+}
+
+/**
+ * Set the scrollbar policy
+ *
+ * This sets the scrollbar visibility policy for the given scroller.
+ * ELM_SMART_SCROLLER_POLICY_AUTO means the scrollber is made visible if it
+ * is needed, and otherwise kept hidden. ELM_SMART_SCROLLER_POLICY_ON turns
+ * it on all the time, and ELM_SMART_SCROLLER_POLICY_OFF always keeps it off.
+ * This applies respectively for the horizontal and vertical scrollbars.
+ *
+ * @param obj The list object
+ * @param policy_h Horizontal scrollbar policy
+ * @param policy_v Vertical scrollbar policy
+ *
+ * @ingroup List
+ */
+EAPI void
+elm_list_scroller_policy_set(Evas_Object *obj, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->scr)
+     elm_scroller_policy_set(wd->scr, policy_h, policy_v);
+}
+
+EAPI void
+elm_list_scroller_policy_get(const Evas_Object *obj, Elm_Scroller_Policy *policy_h, Elm_Scroller_Policy *policy_v)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->scr)
+     elm_scroller_policy_get(wd->scr, policy_h, policy_v);
+}
diff --git a/src/lib/elm_main.c b/src/lib/elm_main.c
new file mode 100644 (file)
index 0000000..e9bc65b
--- /dev/null
@@ -0,0 +1,1363 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+
+#include <dlfcn.h>      /* dlopen,dlclose,etc */
+
+#ifdef HAVE_CRT_EXTERNS_H
+# include <crt_externs.h>
+#endif
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Start Getting Started
+ *
+ * To write an Elementary app, you can get started with the following:
+ *
+ * @code
+ * #include <Elementary.h>
+ * #ifndef ELM_LIB_QUICKLAUNCH
+ * EAPI int
+ * elm_main(int argc, char **argv)
+ * {
+ *    // create window(s) here and do any application init
+ *    elm_run(); // run main loop
+ *    elm_shutdown(); // after mainloop finishes running, shutdown
+ *    return 0; // exit 0 for exit code
+ * }
+ * #endif
+ * ELM_MAIN()
+ * @endcode
+ *
+ * To take full advantage of the quicklaunch architecture for launching
+ * processes as quickly as possible (saving time at startup time like
+ * connecting to X11, loading and linking shared libraries) you may want to
+ * use the following configure.in/configure.ac and Makefile.am and autogen.sh
+ * script to generate your files. It is assumed your application uses the
+ * main.c file for its code.
+ *
+ * configure.in/configure.ac:
+ *
+@verbatim
+AC_INIT(myapp, 0.0.0, myname@mydomain.com)
+AC_PREREQ(2.52)
+AC_CONFIG_SRCDIR(configure.in)
+
+AM_INIT_AUTOMAKE(1.6 dist-bzip2)
+AM_CONFIG_HEADER(config.h)
+
+AC_C_BIGENDIAN
+AC_ISC_POSIX
+AC_PROG_CC
+AM_PROG_CC_STDC
+AC_HEADER_STDC
+AC_C_CONST
+
+AC_LIBTOOL_WIN32_DLL
+define([AC_LIBTOOL_LANG_CXX_CONFIG], [:])dnl
+define([AC_LIBTOOL_LANG_F77_CONFIG], [:])dnl
+AC_PROG_LIBTOOL
+
+PKG_CHECK_MODULES([ELEMENTARY], elementary)
+
+AC_OUTPUT(Makefile)
+@endverbatim
+ *
+ * Makefile.am:
+ *
+@verbatim
+AUTOMAKE_OPTIONS     = 1.4 foreign
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = -I$(top_srcdir) @ELEMENTARY_CFLAGS@
+
+bin_PROGRAMS      = myapp
+myapp_LTLIBRARIES = myapp.la
+
+myappdir = $(libdir)
+
+myapp_la_SOURCES = main.c
+myapp_la_LIBADD = @ELEMENTARY_LIBS@
+myapp_la_CFLAGS =
+myapp_la_LDFLAGS = -module -avoid-version -no-undefined
+
+myapp_SOURCES = main.c
+myapp_LDADD = @ELEMENTARY_LIBS@
+myapp_CFLAGS = -DELM_LIB_QUICKLAUNCH=1
+@endverbatim
+ *
+ * autogen.sh:
+ *
+@verbatim
+#!/bin/sh
+rm -rf autom4te.cache
+rm -f aclocal.m4 ltmain.sh
+rm -rf m4
+mkdir m4
+
+touch README
+echo "Running aclocal..." ; aclocal $ACLOCAL_FLAGS -I m4 || 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
+@endverbatim
+ *
+ * To gnerate all the things needed to bootstrap just run:
+ *
+@verbatim
+./autogen.sh
+@endverbatim
+ *
+ * This will generate Makefile.in's, the confgure script and everything else.
+ * After this it works like all normal autotools projects:
+@verbatim
+./configure
+make
+sudo make install
+@endverbatim
+ *
+ * Note sudo was assumed to get root permissions, as this would install in
+ * /usr/local which is system-owned. Ue any way you like to gain root, or
+ * specify a different prefix with configure:
+ *
+@verbatim
+./confiugre --prefix=$HOME/mysoftware
+@endverbatim
+ *
+ * Also remember that autotools buys you some useful commands like:
+@verbatim
+make uninstall
+@endverbatim
+ *
+ * This uninstalls the software after it was installed with "make install".
+ * It is very useful to clear up what you built if you wish to clean the
+ * system.
+ *
+@verbatim
+make distcheck
+@endverbatim
+ *
+ * This firstly checks if your build tree is "clean" and ready for
+ * distribution. It also builds a tarball (myapp-0.0.0.tar.gz) that is
+ * ready to upload and distribute to the world, that contains the generated
+ * Makefile.in's and configure script. The users do not need to run
+ * autogen.sh - just configure and on. They don't need autotools installed.
+ * This tarball also builds cleanly, has all the sources it needs to build
+ * included (that is sources for your application, not libraries it depends
+ * on like Elementary). It builds cleanly in a buildroot and does not
+ * contain any files that are temporarily generated like binaries and other
+ * build-gnerated files, so the tarball is clean, and no need to worry
+ * about cleaning up your tree before packaging.
+ *
+@verbatim
+make clean
+@endverbatim
+ *
+ * This cleans up all build files (binaries, objects etc.) from the tree.
+ *
+@verbatim
+make distclean
+@endverbatim
+ *
+ * This cleans out all files from the build and from configure's output too.
+ *
+@verbatim
+make maintainer-clean
+@endverbatim
+ *
+ * This deletes all the files autogen.sh will produce so the tree is clean
+ * to be put into a revision-control system (like CVS, SVN or GIT for example).
+ *
+ * The above will build a library - libmyapp.so and install in the target
+ * library directory (default is /usr/local/lib). You will also get a
+ * myapp.a and myapp.la - these are useless and can be deleted. Libtool likes
+ * to generate these all the time. You will also get a binary in the target
+ * binary directory (default is /usr/local/bin). This is a "debug binary".
+ * This will run and dlopen() the myapp.so and then jump to it's elm_main
+ * function. This allows for easy debugging with GDB and Valgrind. When you
+ * are ready to go to production do the following:
+ *
+ * 1. delete the myapp binary. i.e. rm /usr/local/bin/myapp
+ *
+ * 2. symlink the myapp binary to elementary_run (supplied by elementary).
+ * i.e. ln -s elmentary_run /usr/local/bin/myapp
+ *
+ * 3. run elementary_quicklaunch as part of your graphical login session and
+ * keep it running.
+ *
+ * This will man elementary_quicklaunch does pre-initialization before the
+ * application needs to be run, saving the effort at the time the application
+ * is needed, thus speeding up the time it takes to appear.
+ *
+ * If you don't want to use the quicklaunch infrastructure (which is
+ * optional), you can execute the old fashioned way by just running the
+ * myapp binary loader than will load the myapp.so for you, or you can
+ * remove the split-file binary and put it into one binary as things always
+ * have been with the following configure.in/configure.ac and Makfile.am
+ * files:
+ *
+ * configure.in/configure.ac:
+ *
+@verbatim
+AC_INIT(myapp, 0.0.0, myname@mydomain.com)
+AC_PREREQ(2.52)
+AC_CONFIG_SRCDIR(configure.in)
+
+AM_INIT_AUTOMAKE(1.6 dist-bzip2)
+AM_CONFIG_HEADER(config.h)
+
+AC_C_BIGENDIAN
+AC_ISC_POSIX
+AC_PROG_CC
+AM_PROG_CC_STDC
+AC_HEADER_STDC
+AC_C_CONST
+
+PKG_CHECK_MODULES([ELEMENTARY], elementary)
+
+AC_OUTPUT(Makefile)
+@endverbatim
+ *
+ * Makefile.am:
+ *
+@verbatim
+AUTOMAKE_OPTIONS     = 1.4 foreign
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = -I$(top_srcdir) @ELEMENTARY_CFLAGS@
+
+bin_PROGRAMS      = myapp
+
+myapp_SOURCES = main.c
+myapp_LDADD = @ELEMENTARY_LIBS@
+myapp_CFLAGS =
+@endverbatim
+ *
+ * Notice that they are the same as before, just with libtool and library
+ * building sections removed. Both ways work for building elementary
+ * applications. It is up to you to decide what is best for you. If you just
+ * follow the template above, you can do it both ways and can decide at build
+ * time. The more advanced of you may suggest making it a configure option.
+ * That is perfectly valid, bu has been left out here for simplicity, as our
+ * aim to have an Elementary (and EFL) tutorial, not an autoconf & automake
+ * document.
+ *
+ */
+
+static int _elm_signal_exit(void *data, int ev_type, void *ev);
+#ifdef HAVE_ELEMENTARY_X
+static int _elm_window_property_change(void *data, int ev_type, void *ev);
+#endif
+
+char *_elm_appname = NULL;
+const char *_elm_data_dir = NULL;
+const char *_elm_lib_dir = NULL;
+int _elm_log_dom = -1;
+
+EAPI int ELM_EVENT_POLICY_CHANGED = 0;
+
+static int _elm_init_count = 0;
+static int _elm_policies[ELM_POLICY_LAST];
+static Ecore_Event_Handler *_elm_exit_handler = NULL;
+
+static int
+_elm_signal_exit(void *data __UNUSED__, int ev_type __UNUSED__, void *ev __UNUSED__)
+{
+   elm_exit();
+   return 1;
+}
+
+void
+_elm_rescale(void)
+{
+   edje_scale_set(_elm_config->scale);
+   _elm_win_rescale();
+}
+
+/**
+ * @defgroup General General
+ */
+
+/**
+ * Inititalise Elementary
+ *
+ * This call is exported only for use by the ELM_MAIN() macro. There is no
+ * need to use this if you use this macro (which is highly advisable).
+ * @ingroup General
+ */
+EAPI void
+elm_init(int argc, char **argv)
+{
+   _elm_init_count++;
+   if (_elm_init_count != 1) return;
+   elm_quicklaunch_init(argc, argv);
+   elm_quicklaunch_sub_init(argc, argv);
+}
+
+/**
+ * Shut down Elementary
+ *
+ * This should be called at the end of your application just before it ceases
+ * to do any more processing. This will clean up any permanent resources your
+ * application may have allocated via Elementary that would otherwise persist
+ * on an exit without this call.
+ * @ingroup General
+ */
+EAPI void
+elm_shutdown(void)
+{
+   _elm_init_count--;
+   if (_elm_init_count != 0) return;
+   elm_quicklaunch_sub_shutdown();
+   elm_quicklaunch_shutdown();
+}
+
+#ifdef ELM_EDBUS
+static Eina_Bool _elm_need_e_dbus = 0;
+#endif
+EAPI void
+elm_need_e_dbus(void)
+{
+#ifdef ELM_EDBUS
+   if (_elm_need_e_dbus) return;
+   _elm_need_e_dbus = 1;
+   e_dbus_init();
+   e_hal_init();
+#endif   
+}
+
+static void
+_elm_unneed_e_dbus(void)
+{
+#ifdef ELM_EDBUS
+   if (_elm_need_e_dbus)
+     {
+        _elm_need_e_dbus = 0;
+       e_hal_shutdown();
+        e_dbus_shutdown();
+     }
+#endif   
+}
+
+#ifdef ELM_EFREET
+static Eina_Bool _elm_need_efreet = 0;
+#endif
+EAPI void
+elm_need_efreet(void)
+{
+#ifdef ELM_EFREET
+   if (_elm_need_efreet) return;
+   _elm_need_efreet = 1;
+   efreet_init();
+   efreet_mime_init();
+   efreet_trash_init();
+   /*
+     {
+        Eina_List **list;
+        
+        list = efreet_icon_extra_list_get();
+        if (list)
+          {
+             e_user_dir_concat_static(buf, "icons");
+             *list = eina_list_prepend(*list, (void *)eina_stringshare_add(buf));
+             e_prefix_data_concat_static(buf, "data/icons");
+             *list = eina_list_prepend(*list, (void *)eina_stringshare_add(buf));
+          }
+     }
+   */
+#endif
+}
+
+static void
+_elm_unneed_efreet(void)
+{
+#ifdef ELM_EFREET
+   if (_elm_need_efreet)
+     {
+        _elm_need_efreet = 0;
+        efreet_trash_shutdown();
+        efreet_mime_shutdown();
+        efreet_shutdown();
+     }
+#endif   
+}
+
+EAPI void
+elm_quicklaunch_init(int argc, char **argv)
+{
+   char buf[PATH_MAX], *s;
+   
+   eina_init();
+   _elm_log_dom = eina_log_domain_register("elementary", EINA_COLOR_LIGHTBLUE);
+   if (!_elm_log_dom)
+     {
+       EINA_LOG_ERR("could not register elementary log domain.");
+       _elm_log_dom = EINA_LOG_DOMAIN_GLOBAL;
+     }
+
+   eet_init();
+   ecore_init();
+   ecore_app_args_set(argc, (const char **)argv);
+
+   memset(_elm_policies, 0, sizeof(_elm_policies));
+   if (ELM_EVENT_POLICY_CHANGED == 0)
+     ELM_EVENT_POLICY_CHANGED = ecore_event_type_new();
+
+   ecore_file_init();
+   evas_init();
+   edje_init();
+   ecore_evas_init(); // FIXME: check errors
+   _elm_module_init();
+
+   _elm_exit_handler = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, _elm_signal_exit, NULL);
+
+   if (argv) _elm_appname = strdup(ecore_file_file_get(argv[0]));
+
+   if (!_elm_data_dir)
+     {
+       s = getenv("ELM_DATA_DIR");
+       _elm_data_dir = eina_stringshare_add(s);
+     }
+   if (!_elm_data_dir)
+     {
+       s = getenv("ELM_PREFIX");
+       if (s)
+         {
+            snprintf(buf, sizeof(buf), "%s/share/elementary", s);
+            _elm_data_dir = eina_stringshare_add(buf);
+         }
+     }
+   if (!_elm_lib_dir)
+     {
+       s = getenv("ELM_LIB_DIR");
+       _elm_lib_dir = eina_stringshare_add(s);
+     }
+   if (!_elm_lib_dir)
+     {
+       s = getenv("ELM_PREFIX");
+       if (s)
+         {
+            snprintf(buf, sizeof(buf), "%s/lib", s);
+            _elm_lib_dir = eina_stringshare_add(buf);
+         }
+     }
+#ifdef HAVE_DLADDR
+   if ((!_elm_data_dir) || (!_elm_lib_dir))
+     {
+       Dl_info elementary_dl;
+       // libelementary.so/../../share/elementary/
+       if (dladdr(elm_init, &elementary_dl))
+         {
+            char *dir, *dir2;
+
+            dir = ecore_file_dir_get(elementary_dl.dli_fname);
+            if (dir)
+              {
+                  if (!_elm_lib_dir)
+                    {
+                       if (ecore_file_is_dir(dir))
+                         _elm_lib_dir = eina_stringshare_add(dir);
+                    }
+                  if (!_elm_data_dir)
+                    {
+                       dir2 = ecore_file_dir_get(dir);
+                       if (dir2)
+                         {
+                            snprintf(buf, sizeof(buf), "%s/share/elementary", dir2);
+                            if (ecore_file_is_dir(buf))
+                              _elm_data_dir = eina_stringshare_add(buf);
+                            free(dir2);
+                         }
+                    }
+                 free(dir);
+              }
+         }
+     }
+#endif
+   if (!_elm_data_dir)
+     _elm_data_dir = eina_stringshare_add(PACKAGE_DATA_DIR);
+  if (!_elm_data_dir)
+     _elm_data_dir = eina_stringshare_add("/");
+   if (!_elm_lib_dir)
+     _elm_lib_dir = eina_stringshare_add(PACKAGE_LIB_DIR);
+   if (!_elm_lib_dir)
+     _elm_lib_dir = eina_stringshare_add("/");
+
+   _elm_config_init();
+}
+
+EAPI void
+elm_quicklaunch_sub_init(int argc, char **argv)
+{
+   ecore_app_args_set(argc, (const char **)argv);
+   _elm_config_sub_init();
+}
+
+EAPI void
+elm_quicklaunch_sub_shutdown(void)
+{
+   _elm_win_shutdown();
+   if ((_elm_config->engine == ELM_SOFTWARE_X11) ||
+       (_elm_config->engine == ELM_SOFTWARE_16_X11) ||
+       (_elm_config->engine == ELM_XRENDER_X11) ||
+       (_elm_config->engine == ELM_OPENGL_X11) ||
+       (_elm_config->engine == ELM_SOFTWARE_SDL) ||
+       (_elm_config->engine == ELM_SOFTWARE_16_SDL) ||
+       (_elm_config->engine == ELM_OPENGL_SDL) ||
+       (_elm_config->engine == ELM_SOFTWARE_WIN32) ||
+       (_elm_config->engine == ELM_SOFTWARE_16_WINCE))
+     {
+#ifdef HAVE_ELEMENTARY_X
+       ecore_x_disconnect();
+#endif
+       evas_cserve_disconnect();
+     }
+}
+
+EAPI void
+elm_quicklaunch_shutdown(void)
+{
+   eina_stringshare_del(_elm_data_dir);
+   _elm_data_dir = NULL;
+   eina_stringshare_del(_elm_lib_dir);
+   _elm_lib_dir = NULL;
+
+   free(_elm_appname);
+   _elm_appname = NULL;
+   
+   _elm_config_shutdown();
+   
+   ecore_event_handler_del(_elm_exit_handler);
+   _elm_exit_handler = NULL;
+
+   _elm_theme_shutdown();
+   _elm_unneed_efreet();
+   _elm_unneed_e_dbus();
+   _elm_unneed_ethumb();
+   _elm_module_shutdown();
+   ecore_evas_shutdown();
+   edje_shutdown();
+   evas_shutdown();
+   ecore_file_shutdown();
+   ecore_shutdown();
+   eet_shutdown();
+
+   if ((_elm_log_dom > -1) && (_elm_log_dom != EINA_LOG_DOMAIN_GLOBAL))
+     {
+       eina_log_domain_unregister(_elm_log_dom);
+       _elm_log_dom = -1;
+     }
+
+   eina_shutdown();
+}
+
+EAPI void
+elm_quicklaunch_seed(void)
+{
+   Evas_Object *win, *bg, *bt;
+
+   win = elm_win_add(NULL, "seed", ELM_WIN_BASIC);
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+   bt = elm_button_add(win);
+   elm_button_label_set(bt, " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~-_=+\\|]}[{;:'\",<.>/?");
+   elm_win_resize_object_add(win, bt);
+   ecore_main_loop_iterate();
+   evas_object_del(win);
+   ecore_main_loop_iterate();
+   if ((_elm_config->engine == ELM_SOFTWARE_X11) ||
+       (_elm_config->engine == ELM_SOFTWARE_16_X11) ||
+       (_elm_config->engine == ELM_XRENDER_X11) ||
+       (_elm_config->engine == ELM_OPENGL_X11))
+     {
+#ifdef HAVE_ELEMENTARY_X
+       ecore_x_sync();
+#endif
+      }
+   ecore_main_loop_iterate();
+}
+
+static void *qr_handle = NULL;
+static int (*qr_main) (int argc, char **argv) = NULL;
+
+EAPI Eina_Bool
+elm_quicklaunch_prepare(int argc __UNUSED__, char **argv)
+{
+#ifdef HAVE_FORK
+   char *exe = elm_quicklaunch_exe_path_get(argv[0]);
+   if (!exe)
+     {
+       ERR("requested quicklaunch binary '%s' does not exist\n", argv[0]);
+       return EINA_FALSE;
+     }
+   else
+     {
+       char *exe2, *p;
+       char *exename;
+
+       exe2 = malloc(strlen(exe) + 1 + 10);
+       strcpy(exe2, exe);
+       p = strrchr(exe2, '/');
+       if (p) p++;
+       else p = exe2;
+       exename = alloca(strlen(p) + 1);
+       strcpy(exename, p);
+       *p = 0;
+       strcat(p, "../lib/");
+       strcat(p, exename);
+       strcat(p, ".so");
+       if (access(exe2, R_OK | X_OK) == 0)
+         {
+            free(exe);
+            exe = exe2;
+         }
+       else
+         free(exe2);
+     }
+   qr_handle = dlopen(exe, RTLD_NOW | RTLD_GLOBAL);
+   if (!qr_handle)
+     {
+        fprintf(stderr, "dlerr: %s\n", dlerror());
+       WRN("dlopen('%s') failed: %s", exe, dlerror());
+       free(exe);
+       return EINA_FALSE;
+     }
+   INF("dlopen('%s') = %p", exe, qr_handle);
+   free(exe);
+   qr_main = dlsym(qr_handle, "elm_main");
+   INF("dlsym(%p, 'elm_main') = %p", qr_handle, qr_main);
+   if (!qr_main)
+     {
+       WRN("not quicklauncher capable: no elm_main in '%s'", exe);
+       dlclose(qr_handle);
+       qr_handle = NULL;
+       return EINA_FALSE;
+     }
+   return EINA_TRUE;
+#else
+   return EINA_FALSE;
+#endif
+}
+
+#ifdef HAVE_FORK
+static void
+save_env(void)
+{
+   int i, size;
+   extern char **environ;
+   char **oldenv, **p;
+
+   oldenv = environ;
+
+   for (i = 0, size = 0; environ[i] != NULL; i++)
+     size += strlen(environ[i]) + 1;
+
+   p = malloc((i + 1) * sizeof(char *));
+   if (!p) return;
+
+   environ = p;
+
+   for (i = 0; oldenv[i] != NULL; i++)
+     environ[i] = strdup(oldenv[i]);
+   environ[i] = NULL;
+}
+#endif
+
+EAPI Eina_Bool
+elm_quicklaunch_fork(int argc, char **argv, char *cwd, void (postfork_func) (void *data), void *postfork_data)
+{
+#ifdef HAVE_FORK
+   pid_t child;
+   int ret;
+   int real_argc;
+   char **real_argv;
+
+   // FIXME:
+   // need to accept current environment from elementary_run
+   if (!qr_main)
+     {
+       int i;
+       char **args;
+
+       child = fork();
+       if (child > 0) return EINA_TRUE;
+       else if (child < 0)
+         {
+            perror("could not fork");
+            return EINA_FALSE;
+         }
+       setsid();
+       if (chdir(cwd) != 0)
+         perror("could not chdir");
+       args = alloca((argc + 1) * sizeof(char *));
+       for (i = 0; i < argc; i++) args[i] = argv[i];
+       args[argc] = NULL;
+       WRN("%s not quicklaunch capable, fallback...", argv[0]);
+       execvp(argv[0], args);
+       ERR("failed to execute '%s': %s", argv[0], strerror(errno));
+       exit(-1);
+     }
+   child = fork();
+   if (child > 0) return EINA_TRUE;
+   else if (child < 0)
+     {
+       perror("could not fork");
+       return EINA_FALSE;
+     }
+   if (postfork_func) postfork_func(postfork_data);
+
+   setsid();
+   if (chdir(cwd) != 0)
+     perror("could not chdir");
+   // FIXME: this is very linux specific. it changes argv[0] of the process
+   // so ps etc. report what you'd expect. for other unixes and os's this
+   // may just not work
+   save_env();
+   if (argv)
+     {
+       char *lastarg, *p;
+
+       ecore_app_args_get(&real_argc, &real_argv);
+       lastarg = real_argv[real_argc - 1] + strlen(real_argv[real_argc - 1]);
+       for (p = real_argv[0]; p < lastarg; p++) *p = 0;
+       strcpy(real_argv[0], argv[0]);
+     }
+   ecore_app_args_set(argc, (const char **)argv);
+   ret = qr_main(argc, argv);
+   exit(ret);
+   return EINA_TRUE;
+#else
+   return EINA_FALSE;
+#endif
+}
+
+EAPI void
+elm_quicklaunch_cleanup(void)
+{
+#ifdef HAVE_FORK
+   if (qr_handle)
+     {
+       dlclose(qr_handle);
+       qr_handle = NULL;
+       qr_main = NULL;
+     }
+#endif
+}
+
+EAPI int
+elm_quicklaunch_fallback(int argc, char **argv)
+{
+   int ret;
+   elm_quicklaunch_init(argc, argv);
+   elm_quicklaunch_sub_init(argc, argv);
+   elm_quicklaunch_prepare(argc, argv);
+   ret = qr_main(argc, argv);
+   exit(ret);
+   return ret;
+}
+
+EAPI char *
+elm_quicklaunch_exe_path_get(const char *exe)
+{
+   static char *path = NULL;
+   static Eina_List *pathlist = NULL;
+   const char *pathitr;
+   const Eina_List *l;
+   char buf[PATH_MAX];
+   if (exe[0] == '/') return strdup(exe);
+   if ((exe[0] == '.') && (exe[1] == '/')) return strdup(exe);
+   if ((exe[0] == '.') && (exe[1] == '.') && (exe[2] == '/')) return strdup(exe);
+   if (!path)
+     {
+       const char *p, *pp;
+       char *buf2;
+       path = getenv("PATH");
+       buf2 = alloca(strlen(path) + 1);
+       p = path;
+       pp = p;
+       for (;;)
+         {
+            if ((*p == ':') || (*p == 0))
+              {
+                 int len;
+
+                 len = p - pp;
+                 strncpy(buf2, pp, len);
+                 buf2[len] = 0;
+                 pathlist = eina_list_append(pathlist, eina_stringshare_add(buf2));
+                 if (*p == 0) break;
+                 p++;
+                 pp = p;
+              }
+            else
+              {
+                 if (*p == 0) break;
+                 p++;
+              }
+         }
+     }
+   EINA_LIST_FOREACH(pathlist, l, pathitr)
+     {
+       snprintf(buf, sizeof(buf), "%s/%s", pathitr, exe);
+       if (access(buf, R_OK | X_OK) == 0) return strdup(buf);
+     }
+   return NULL;
+}
+
+/**
+ * Run the main loop
+ *
+ * This call should be called just after all initialization is complete. This
+ * function will not return until elm_exit() is called. It will keep looping
+ * running the main event/processing loop for Elementary.
+ * @ingroup General
+ */
+EAPI void
+elm_run(void)
+{
+   ecore_main_loop_begin();
+}
+
+/**
+ * Exit the main loop
+ *
+ * If this call is called, it will flag the main loop to cease processing and
+ * return back to its parent function.
+ * @ingroup General
+ */
+EAPI void
+elm_exit(void)
+{
+   ecore_main_loop_quit();
+}
+
+
+/**
+ * Set new policy value.
+ *
+ * This will emit the ecore event ELM_EVENT_POLICY_CHANGED in the main
+ * loop giving the event information Elm_Event_Policy_Changed with
+ * policy identifier, new and old values.
+ *
+ * @param policy policy identifier as in Elm_Policy.
+ * @param value policy value, depends on identifiers, usually there is
+ *        an enumeration with the same prefix as the policy name, for
+ *        example: ELM_POLICY_QUIT and Elm_Policy_Quit
+ *        (ELM_POLICY_QUIT_NONE, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED).
+ *
+ * @return @c EINA_TRUE on success or @c EINA_FALSE on error (right
+ *         now just invalid policy identifier, but in future policy
+ *         value might be enforced).
+ */
+EAPI Eina_Bool
+elm_policy_set(unsigned int policy, int value)
+{
+   Elm_Event_Policy_Changed *ev;
+
+   if (policy >= ELM_POLICY_LAST)
+     return EINA_FALSE;
+
+   if (value == _elm_policies[policy])
+     return EINA_TRUE;
+
+   /* TODO: validade policy? */
+
+   ev = malloc(sizeof(*ev));
+   ev->policy = policy;
+   ev->new_value = value;
+   ev->old_value = _elm_policies[policy];
+
+   _elm_policies[policy] = value;
+
+   ecore_event_add(ELM_EVENT_POLICY_CHANGED, ev, NULL, NULL);
+
+   return EINA_TRUE;
+}
+
+/**
+ * Gets the policy value set for given identifier.
+ *
+ * @param policy policy identifier as in Elm_Policy.
+ *
+ * @return policy value. Will be 0 if policy identifier is invalid.
+ */
+EAPI int
+elm_policy_get(unsigned int policy)
+{
+   if (policy >= ELM_POLICY_LAST)
+     return 0;
+   return _elm_policies[policy];
+}
+
+/**
+ * Flush all caches & dump all data that can be to lean down to use less memory
+ */
+EAPI void
+elm_all_flush(void)
+{
+   const Eina_List *l;
+   Evas_Object *obj;
+   
+   EINA_LIST_FOREACH(_elm_win_list, l, obj)
+     {
+        Evas *e = evas_object_evas_get(obj);
+        edje_file_cache_flush();
+        edje_collection_cache_flush();
+        evas_image_cache_flush(e);
+        evas_font_cache_flush(e);
+        evas_render_dump(e);
+     }
+}
+
+/**
+ * @defgroup Scaling Selective Widget Scaling
+ *
+ * Different widgets can be scaled independently. These functions allow you to
+ * manipulate this scaling on a per-widget basis. The object and all its
+ * children get their scaling factors multiplied by the scale factor set.
+ * This is multiplicative, in that if a child also has a scale size set it is
+ * in turn multiplied by its parent's scale size. 1.0 means “don't scale”,
+ * 2.0 is double size, 0.5 is half etc.
+ */
+
+/**
+ * Set the scaling factor
+ *
+ * @param obj The object
+ * @param scale Scale factor (from 0.0 up, with 1.0 == no scaling)
+ * @ingroup Scaling
+ */
+EAPI void
+elm_object_scale_set(Evas_Object *obj, double scale)
+{
+   elm_widget_scale_set(obj, scale);
+}
+
+/**
+ * Get the scaling factor
+ *
+ * @param obj The object
+ * @return The scaling factor set by elm_object_scale_set()
+ * @ingroup Scaling
+ */
+EAPI double
+elm_object_scale_get(const Evas_Object *obj)
+{
+   return elm_widget_scale_get(obj);
+}
+
+/**
+ * @defgroup Styles Styles
+ *
+ * Widgets can have different styles of look. These generic API's set
+ * styles of widgets, if they support them (and if the theme(s) do).
+ */
+
+/**
+ * Set the style
+ *
+ * This sets the name of the style
+ * @param obj The object
+ * @param style The style name to use
+ * @ingroup Styles
+ */
+EAPI void
+elm_object_style_set(Evas_Object *obj, const char *style)
+{
+   elm_widget_style_set(obj, style);
+}
+
+/**
+ * Get the style
+ *
+ * This gets the style being used for that widget. Note that the string
+ * pointer is only valid as longas the object is valid and the style doesn't
+ * change.
+ *
+ * @param obj The object
+ * @return The style name
+ * @ingroup Styles
+ */
+EAPI const char *
+elm_object_style_get(const Evas_Object *obj)
+{
+   return elm_widget_style_get(obj);
+}
+
+/**
+ * Set the disable state
+ *
+ * This sets the disable state for the widget.
+ *
+ * @param obj The object
+ * @param disabled The state
+ * @ingroup Styles
+ */
+EAPI void
+elm_object_disabled_set(Evas_Object *obj, Eina_Bool disabled)
+{
+   elm_widget_disabled_set(obj, disabled);
+}
+
+/**
+ * Get the disable state
+ *
+ * This gets the disable state for the widget.
+ *
+ * @param obj The object
+ * @return True, if the widget is disabled
+ * @ingroup Styles
+ */
+EAPI Eina_Bool
+elm_object_disabled_get(const Evas_Object *obj)
+{
+   return elm_widget_disabled_get(obj);
+}
+
+/**
+ * Get the global scaling factor
+ *
+ * This gets the globally configured scaling factor that is applied to all
+ * objects.
+ *
+ * @return The scaling factor
+ * @ingroup Scaling
+ */
+EAPI double
+elm_scale_get(void)
+{
+   return _elm_config->scale;
+}
+
+/**
+ * Set the global scaling factor
+ *
+ * This sets the globally configured scaling factor that is applied to all
+ * objects.
+ *
+ * @param scale The scaling factor to set
+ * @ingroup Scaling
+ */
+EAPI void
+elm_scale_set(double scale)
+{
+   if (_elm_config->scale == scale) return;
+   _elm_config->scale = scale;
+   _elm_rescale();
+}
+
+/**
+ * Set the global scaling factor for all applications on the display
+ * 
+ * This sets the globally configured scaling factor that is applied to all
+ * objects for all applications.
+ * @param scale The scaling factor to set
+ * @ingroup Scaling
+ */
+EAPI void
+elm_scale_all_set(double scale)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int scale_i = (unsigned int)(scale * 1000.0);
+
+   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_SCALE");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &scale_i, 1);
+#endif   
+}
+
+/**
+ * @defgroup Fingers Fingers
+ *
+ * Elementary is designed to be finger-friendly for touchscreens, and so in
+ * addition to scaling for display resolution, it can also scale based on
+ * finger "resolution" (or size).
+ */
+
+/**
+ * Get the configured finger size
+ *
+ * This gets the globally configured finger size in pixels
+ *
+ * @return The finger size
+ * @ingroup Fingers
+ */
+EAPI Evas_Coord
+elm_finger_size_get(void)
+{
+   return _elm_config->finger_size;
+}
+
+/**
+ * Set the configured finger size
+ *
+ * This sets the globally configured finger size in pixels
+ *
+ * @param size The finger size
+ * @ingroup Fingers
+ */
+EAPI void
+elm_finger_size_set(Evas_Coord size)
+{
+   if (_elm_config->finger_size == size) return;
+   _elm_config->finger_size = size;
+   _elm_rescale();
+}
+
+/**
+ * Set the configured finger size for all applications on the display
+ *
+ * This sets the globally configured finger size in pixels for all applications
+ * on the display
+ *
+ * @param size The finger size
+ * @ingroup Fingers
+ */
+EAPI void
+elm_finger_size_all_set(Evas_Coord size)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int size_i = (unsigned int)size;
+
+   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_FINGER_SIZE");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &size_i, 1);
+#endif   
+}
+
+/**
+ * Adjust size of an element for finger usage
+ *
+ * This takes width and height sizes (in pixels) as input and a size multiple
+ * (which is how many fingers you want to place within the area), and adjusts
+ * the size tobe large enough to accomodate finger. On return the w and h
+ * sizes poiner do by these parameters will be modified.
+ *
+ * @param times_w How many fingers should fit horizontally
+ * @param w Pointer to the width size to adjust
+ * @param times_h How many fingers should fit vertically
+ * @param h Pointer to the height size to adjust
+ * @ingroup Fingers
+ */
+EAPI void
+elm_coords_finger_size_adjust(int times_w, Evas_Coord *w, int times_h, Evas_Coord *h)
+{
+   if ((w) && (*w < (_elm_config->finger_size * times_w)))
+     *w = _elm_config->finger_size * times_w;
+   if ((h) && (*h < (_elm_config->finger_size * times_h)))
+     *h = _elm_config->finger_size * times_h;
+}
+
+/**
+ * @defgroup Focus Focus
+ *
+ * Objects have focus. This is what determines where the keyboard input goes to
+ * within the application window.
+ */
+
+/**
+ * Set the focus to the object
+ *
+ * This sets the focus target forkeyboard input to be the object indicated.
+ *
+ * @param obj The object
+ * @ingroup Focus
+ */
+EAPI void
+elm_object_focus(Evas_Object *obj)
+{
+   if (!elm_widget_can_focus_get(obj)) return;
+   elm_widget_focus_steal(obj);
+}
+
+/**
+ * Set the focus to the object
+ *
+ * This sets the focus target forkeyboard input to be the object indicated.
+ *
+ * @param obj The object
+ * @ingroup Focus
+ */
+EAPI void
+elm_object_unfocus(Evas_Object *obj)
+{
+   if (!elm_widget_can_focus_get(obj)) return;
+   elm_widget_focused_object_clear(obj);
+}
+
+/**
+ * Set the ability for the object to focus
+ *
+ * This sets the ability for the object to be able to get keyboard focus or
+ * not. By default all objects are able to be focused.
+ *
+ * @param obj The object
+ * @param enable 1 if the object can be focused, 0 if not
+ * @ingroup Focus
+ */
+EAPI void
+elm_object_focus_allow_set(Evas_Object *obj, Eina_Bool enable)
+{
+   elm_widget_can_focus_set(obj, enable);
+}
+
+/**
+ * Get the ability for the object to focus
+ *
+ * This gets the ability for the object to be able to get keyboard focus or
+ * not. By default all objects are able to be focused.
+ *
+ * @param obj The object
+ * @return 1 if the object is allowed to be focused, 0 if not.
+ * @ingroup Focus
+ */
+EAPI Eina_Bool
+elm_object_focus_allow_get(const Evas_Object *obj)
+{
+   return elm_widget_can_focus_get(obj);
+}
+
+/**
+ * @defgroup Scrollhints Scrollhints
+ *
+ * Objects when inside a scroller can scroll, but this may not always be
+ * desireable in certain situations. This allows an object to hint to itself
+ * and parents to "not scroll" in one of 2 ways.
+ * 
+ * 1. To hold on scrolling. This means just flicking and dragging may no
+ * longer scroll, but pressing/dragging near an edge of the scroller will
+ * still scroll. This is automastically used by the entry object when
+ * selecting text.
+ * 2. To totally freeze scrolling. This means it stops. until popped/released.
+ */
+
+/**
+ * Push the scroll hold by 1
+ *
+ * This increments the scroll hold count by one. If it is more than 0 it will
+ * take effect on the parents of the indicated object.
+ *
+ * @param obj The object
+ * @ingroup Scrollhints
+ */
+EAPI void
+elm_object_scroll_hold_push(Evas_Object *obj)
+{
+   elm_widget_scroll_hold_push(obj);
+}
+
+/**
+ * Pop the scroll hold by 1
+ *
+ * This decrements the scroll hold count by one. If it is more than 0 it will
+ * take effect on the parents of the indicated object.
+ *
+ * @param obj The object
+ * @ingroup Scrollhints
+ */
+EAPI void
+elm_object_scroll_hold_pop(Evas_Object *obj)
+{
+   elm_widget_scroll_hold_pop(obj);
+}
+
+/**
+ * Push the scroll freeze by 1
+ *
+ * This increments the scroll freeze count by one. If it is more than 0 it will
+ * take effect on the parents of the indicated object.
+ *
+ * @param obj The object
+ * @ingroup Scrollhints
+ */
+EAPI void
+elm_object_scroll_freeze_push(Evas_Object *obj)
+{
+   elm_widget_scroll_freeze_push(obj);
+}
+
+/**
+ * Pop the scroll freeze by 1
+ *
+ * This decrements the scroll freeze count by one. If it is more than 0 it will
+ * take effect on the parents of the indicated object.
+ *
+ * @param obj The object
+ * @ingroup Scrollhints
+ */
+EAPI void
+elm_object_scroll_freeze_pop(Evas_Object *obj)
+{
+   elm_widget_scroll_freeze_pop(obj);
+}
+
+/**
+ * @defgroup WidgetNavigation Widget Tree Navigation.
+ *
+ * How to check if an Evas Object is an Elementary widget? How to get
+ * the first elementary widget that is parent of the given object?
+ * These are all covered in widget tree navigation.
+ */
+
+/**
+ * Check if the given Evas Object is an Elementary widget.
+ *
+ * @param obj the object to query.
+ * @return @c EINA_TRUE if it is an elementary widget variant,
+ *         @c EINA_FALSE otherwise
+ */
+EAPI Eina_Bool
+elm_object_widget_check(const Evas_Object *obj)
+{
+   return elm_widget_is(obj);
+}
+
+/**
+ * Get the first parent of the given object that is an Elementary widget.
+ *
+ * @param obj the object to query.
+ * @return the parent object that is an Elementary widget, or @c NULL
+ *         if no parent is, or no parents at all.
+ */
+EAPI Evas_Object *
+elm_object_parent_widget_get(const Evas_Object *obj)
+{
+   return elm_widget_parent_widget_get(obj);
+}
+
+/**
+ * Get the string that represents this Elementary widget.
+ *
+ * @note Elementary is weird and exposes itself as a single
+ *       Evas_Object_Smart_Class of type "elm_widget", so
+ *       evas_object_type_get() always return that, making debug and
+ *       language bindings hard. This function tries to mitigate this
+ *       problem, but the solution is to change Elementary to use
+ *       proper inheritance.
+ *
+ * @param obj the object to query.
+ * @return Elementary widget name, or @c NULL if not a valid widget.
+ */
+EAPI const char *
+elm_object_widget_type_get(const Evas_Object *obj)
+{
+   return elm_widget_type_get(obj);
+}
diff --git a/src/lib/elm_map.c b/src/lib/elm_map.c
new file mode 100644 (file)
index 0000000..945a2b2
--- /dev/null
@@ -0,0 +1,3058 @@
+/*
+ *
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Map Map
+ *
+ * This is a widget specifically for displaying the free map OpenStreetMap.
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * clicked - This is called when a user has clicked the map without dragging
+ * around.
+ *
+ * press - This is called when a user has pressed down on the map.
+ *
+ * longpressed - This is called when a user has pressed down on the map for
+ * a long time without dragging around.
+ *
+ * clicked,double - This is called when a user has double-clicked the photo.
+ *
+ * load,details - Map detailed data load begins.
+ *
+ * loaded,details - This is called when all parts of the map are loaded.
+ *
+ * zoom,start - Zoom animation started.
+ *
+ * zoom,stop - Zoom animation stopped.
+ *
+ * zoom,change - Zoom changed when using an auto zoom mode.
+ *
+ * scroll - the content has been scrolled (moved)
+ *
+ * scroll,anim,start - scrolling animation has started
+ *
+ * scroll,anim,stop - scrolling animation has stopped
+ *
+ * scroll,drag,start - dragging the contents around has started
+ *
+ * scroll,drag,stop - dragging the contents around has stopped
+ *
+ * TODO : doxygen
+ */
+
+
+typedef struct _Widget_Data Widget_Data;
+typedef struct _Pan Pan;
+typedef struct _Grid Grid;
+typedef struct _Grid_Item Grid_Item;
+typedef struct _Marker_Group Marker_Group;
+
+#define DEST_DIR_ZOOM_PATH "/tmp/elm_map/%d/%d/"
+#define DEST_DIR_PATH DEST_DIR_ZOOM_PATH"%d/"
+#define DEST_FILE_PATH "%s%d.png"
+
+// Map sources
+// Currently the size of a tile must be 256*256
+// and the size of the map must be pow(2.0, z)*tile_size
+typedef struct _Map_Sources_Tab
+{
+   Elm_Map_Sources source;
+   const char *name;
+   int zoom_min;
+   int zoom_max;
+   ElmMapSourceURLFunc url_cb;
+} Map_Sources_Tab;
+
+#define ZOOM_MAX 18
+//Zemm min is supposed to be 0
+static char * _mapnik_url_cb(int x, int y, int zoom);
+static char * _osmarender_url_cb(int x, int y, int zoom);
+static char * _cyclemap_url_cb(int x, int y, int zoom);
+static char * _maplint_url_cb(int x, int y, int zoom);
+static Map_Sources_Tab map_sources_tab[] =
+{
+     {ELM_MAP_SOURCE_MAPNIK, "Mapnik", 0, 18, _mapnik_url_cb},
+     {ELM_MAP_SOURCE_OSMARENDER, "Osmarender", 0, 17, _osmarender_url_cb},
+     {ELM_MAP_SOURCE_CYCLEMAP, "Cycle Map", 0, 17, _cyclemap_url_cb},
+     {ELM_MAP_SOURCE_MAPLINT, "Maplint", 12, 16, _maplint_url_cb},
+     {ELM_MAP_SOURCE_CUSTOM_1, "Custom 1", 0, 18, NULL},
+     {ELM_MAP_SOURCE_CUSTOM_2, "Custom 2", 0, 18, NULL},
+     {ELM_MAP_SOURCE_CUSTOM_3, "Custom 3", 0, 18, NULL},
+     {ELM_MAP_SOURCE_CUSTOM_4, "Custom 4", 0, 18, NULL},
+     {ELM_MAP_SOURCE_CUSTOM_5, "Custom 5", 0, 18, NULL},
+     {ELM_MAP_SOURCE_CUSTOM_6, "Custom 6", 0, 18, NULL},
+     {ELM_MAP_SOURCE_CUSTOM_7, "Custom 7", 0, 18, NULL}
+};
+
+struct _Elm_Map_Marker_Class
+{
+   const char *style;
+   int zoom_displayed;
+
+   struct _Elm_Map_Marker_Class_Func {
+      ElmMapMarkerGetFunc get;
+      ElmMapMarkerDelFunc del; //if NULL the object will be destroyed with evas_object_del()
+      ElmMapMarkerIconGetFunc icon_get;
+   } func;
+
+   struct { //this part is private, do not modify these values
+      Eina_Bool set : 1;
+      Evas_Coord edje_w, edje_h;
+   } priv;
+};
+
+struct _Elm_Map_Marker
+{
+   Widget_Data *wd;
+   Elm_Map_Marker_Class *clas;
+   Elm_Map_Group_Class *clas_group;
+   double longitude, latitude;
+
+   Evas_Coord map_size;
+   Evas_Coord x[ZOOM_MAX+1], y[ZOOM_MAX+1];
+   void *data;
+
+   Marker_Group *groups[ZOOM_MAX+1];
+
+   Evas_Object *content;
+};
+
+struct _Elm_Map_Group_Class
+{
+   const char *style;
+   void *data;
+   int zoom_displayed; // display the group if the zoom is >= to zoom_display
+   int zoom_grouped; // group the markers only if the zoom is <= to zoom_groups
+   Eina_Bool hide : 1;
+
+   struct {
+      ElmMapGroupIconGetFunc icon_get;
+   } func;
+   
+   struct { //this part is private, do not modify these values
+      Eina_Bool set : 1;
+      Evas_Coord edje_w, edje_h;
+      Evas_Coord edje_max_w, edje_max_h;
+      
+      Eina_List *objs_used;
+      Eina_List *objs_notused;
+   } priv;
+};
+
+struct _Marker_Group
+{
+   Widget_Data *wd;
+   Eina_Matrixsparse_Cell *cell;
+   Elm_Map_Group_Class *clas;
+
+   Eina_List *markers;
+   long long sum_x, sum_y;
+   Evas_Coord x, y;
+   Evas_Coord w, h;
+
+   Evas_Object *obj, *bubble, *sc, *bx, *rect;
+   Eina_Bool open : 1;
+   Eina_Bool bringin : 1;
+   Eina_Bool update_nbelems : 1;
+   Eina_Bool update_resize : 1;
+   Eina_Bool update_raise : 1;
+   Eina_Bool delete_object : 1;
+};
+
+struct _Grid_Item
+{
+   Widget_Data *wd;
+   Evas_Object *img;
+   //Evas_Object *txt;
+   const char *file;
+   struct {
+      int x, y, w, h;
+   } src, out;
+   Eina_Bool want : 1;
+   Eina_Bool download : 1;
+   Eina_Bool have : 1;
+   Ecore_File_Download_Job *job;
+   int try_num;
+};
+
+struct _Grid
+{
+   Widget_Data *wd;
+   int tsize; // size of tile (tsize x tsize pixels)
+   int zoom; // zoom level tiles want for optimal display (1, 2, 4, 8)
+   int iw, ih; // size of image in pixels
+   int w, h; // size of grid image in pixels (represented by grid)
+   int gw, gh; // size of grid in tiles
+   Eina_Matrixsparse *grid;
+};
+
+struct _Widget_Data
+{
+   Evas_Object *obj;
+   Evas_Object *scr;
+   Evas_Object *pan_smart;
+   Evas_Object *rect;
+   Pan *pan;
+   Evas_Coord pan_x, pan_y, minw, minh;
+
+   int id;
+   int zoom;
+   Elm_Map_Zoom_Mode mode;
+
+   Ecore_Job *calc_job;
+   Ecore_Timer *scr_timer;
+   Ecore_Timer *long_timer;
+   Ecore_Animator *zoom_animator;
+   double t_start, t_end;
+   struct {
+      int w, h;
+      int ow, oh, nw, nh;
+      struct {
+         double x, y;
+      } spos;
+   } size;
+   struct {
+      Eina_Bool show : 1;
+      Evas_Coord x, y ,w ,h;
+   } show;
+   int tsize;
+   int nosmooth;
+   int preload_num;
+   Eina_List *grids;
+   Eina_Bool resized : 1;
+   Eina_Bool longpressed : 1;
+   Eina_Bool on_hold : 1;
+   Eina_Bool paused : 1;
+   Eina_Bool paused_markers : 1;
+   
+   struct {
+      Eina_Bool enabled;
+      double lon, lat;
+   } center_on;
+
+   Ecore_Job *markers_place_job;
+   Eina_Matrixsparse *markers[ZOOM_MAX+1];
+   Eina_List *cells_displayed; // list of Eina_Matrixsparse_Cell
+   Evas_Coord markers_max_num;
+   int marker_max_w, marker_max_h;
+   int marker_zoom;
+   Eina_List *opened_bubbles; //opened bubbles, list of Map_Group *
+
+   Eina_List *groups_clas; // list of Elm_Map_Group_Class*
+   Eina_List *markers_clas; // list of Elm_Map_Markers_Class*
+
+   Elm_Map_Sources source;
+};
+
+struct _Pan
+{
+   Evas_Object_Smart_Clipped_Data __clipped_data;
+   Widget_Data *wd;
+};
+
+static const char *widtype = NULL;
+
+static const char SIG_CHANGED[] = "changed";
+static const char SIG_CLICKED[] = "clicked";
+static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
+static const char SIG_LOADED_DETAIL[] = "loaded,detail";
+static const char SIG_LOAD_DETAIL[] = "load,detail";
+static const char SIG_LONGPRESSED[] = "longpressed";
+static const char SIG_PRESS[] = "press";
+static const char SIG_SCROLL[] = "scroll";
+static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
+static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
+static const char SIG_ZOOM_CHANGE[] = "zoom,change";
+static const char SIG_ZOOM_START[] = "zoom,start";
+static const char SIG_ZOOM_STOP[] = "zoom,stop";
+static const Evas_Smart_Cb_Description _signals[] = {
+  {SIG_CHANGED, ""},
+  {SIG_CLICKED, ""},
+  {SIG_CLICKED_DOUBLE, ""},
+  {SIG_LOADED_DETAIL, ""},
+  {SIG_LOAD_DETAIL, ""},
+  {SIG_LONGPRESSED, ""},
+  {SIG_PRESS, ""},
+  {SIG_SCROLL, ""},
+  {SIG_SCROLL_DRAG_START, ""},
+  {SIG_SCROLL_DRAG_STOP, ""},
+  {SIG_ZOOM_CHANGE, ""},
+  {SIG_ZOOM_START, ""},
+  {SIG_ZOOM_STOP, ""},
+  {NULL, NULL}
+};
+
+static void _pan_calculate(Evas_Object *obj);
+
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _calc_job(void *data);
+static void grid_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh);
+static void grid_clear(Evas_Object *obj, Grid *g);
+static Grid *grid_create(Evas_Object *obj);
+static void grid_load(Evas_Object *obj, Grid *g);
+
+
+static void _group_object_create(Marker_Group *group);
+static void _group_object_free(Marker_Group *group);
+static void _group_open_cb(void *data, Evas_Object *obj, const char *emission, const char *soure);
+static void _group_bringin_cb(void *data, Evas_Object *obj, const char *emission, const char *soure);
+static void _group_bubble_create(Marker_Group *group);
+static void _group_bubble_free(Marker_Group *group);
+static void _group_bubble_place(Marker_Group *group);
+
+static int _group_bubble_content_update(Marker_Group *group);
+static void _group_bubble_content_free(Marker_Group *group);
+static void marker_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh);
+static void _bubble_sc_hits_changed_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+static void
+rect_place(Evas_Object *obj, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord ax, ay, gw, gh, hh, ww;
+   if (!wd) return;
+   evas_object_geometry_get(wd->rect, NULL, NULL, &ww, &hh);
+
+   ax = 0;
+   ay = 0;
+   gw = wd->size.w;
+   gh = wd->size.h;
+
+   if (ww == gw && hh == gh) return;
+
+   if (ow > gw) ax = (ow - gw) / 2;
+   if (oh > gh) ay = (oh - gh) / 2;
+   evas_object_move(wd->rect,
+                    ox + 0 - px + ax,
+                    oy + 0 - py + ay);
+   evas_object_resize(wd->rect, gw, gh);
+   
+   if (wd->show.show)
+     {
+       wd->show.show = EINA_FALSE;
+       elm_smart_scroller_child_region_show(wd->scr, wd->show.x, wd->show.y, wd->show.w, wd->show.h);
+     }
+}
+
+static void
+marker_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord ax, ay, gw, gh, tx, ty;
+   Eina_List *l, *markers;
+   Eina_Matrixsparse_Cell *cell;
+   Marker_Group *group;
+   int xx, yy, ww, hh;
+   char buf[PATH_MAX];
+   int y, x;
+   int g_xx, g_yy, g_hh, g_ww;
+
+   if (!wd) return;
+   if (g != eina_list_data_get(wd->grids)) return;
+
+   ax = 0;
+   ay = 0;
+   gw = wd->size.w;
+   gh = wd->size.h;
+   if (ow > gw) ax = (ow - gw) / 2;
+   if (oh > gh) ay = (oh - gh) / 2;
+
+   if (wd->zoom != wd->marker_zoom)
+     {
+       EINA_LIST_FREE(wd->cells_displayed, cell)
+         {
+            EINA_LIST_FOREACH(eina_matrixsparse_cell_data_get(cell), l, group)
+              {
+                 if (group->obj) _group_object_free(group);
+              }
+         }
+     }
+   wd->marker_zoom = wd->zoom;
+
+   if (wd->paused_markers
+       && (wd->size.nw != wd->size.w || wd->size.nh != wd->size.h) )
+     return;
+
+   g_xx = wd->pan_x / wd->tsize;
+   if (g_xx < 0) g_xx = 0;
+   g_yy = wd->pan_y / wd->tsize;
+   if (g_yy < 0) g_yy = 0;
+   g_ww =  ow / wd->tsize + 1;
+   if (g_xx + g_ww >= g->gw) g_ww = g->gw - g_xx - 1;
+   g_hh =  oh / wd->tsize + 1;
+   if (g_yy + g_hh >= g->gh) g_hh = g->gh - g_yy - 1;
+
+   //hide groups no more displayed
+   EINA_LIST_FREE(wd->cells_displayed, cell)
+     {
+       eina_matrixsparse_cell_position_get(cell, (unsigned long *)&y, (unsigned long *)&x);
+       if (y < g_yy || y > g_yy + g_hh || x < g_xx || x > g_xx + g_ww)
+         {
+            EINA_LIST_FOREACH(eina_matrixsparse_cell_data_get(cell), l, group)
+              {
+                 if (group->obj) _group_object_free(group);
+              }
+         }
+     }
+
+   for (y = g_yy; y <= g_yy + g_hh; y++)
+     {
+       for (x = g_xx; x <= g_xx + g_ww; x++)
+         {
+            if (!wd->markers[wd->zoom]) continue;
+            eina_matrixsparse_cell_idx_get(wd->markers[wd->zoom], y, x, &cell);
+            if (!cell) continue;
+            wd->cells_displayed = eina_list_append(wd->cells_displayed, cell);
+            markers = eina_matrixsparse_cell_data_get(cell);
+            EINA_LIST_FOREACH(markers, l, group)
+              {
+                 if (!group->markers) continue;
+                 if (group->clas->zoom_displayed > wd->zoom) continue;
+
+                 xx = group->x;
+                 yy = group->y;
+                 ww = group->w;
+                 hh = group->h;
+
+                 if (eina_list_count(group->markers) == 1)
+                   {
+                      Elm_Map_Marker *m = eina_list_data_get(group->markers);
+                      ww = m->clas->priv.edje_w;
+                      hh = m->clas->priv.edje_h;
+                   }
+
+                 if (ww <= 0) ww = 1;
+                 if (hh <= 0) hh = 1;
+
+                 if ((gw != g->w) && (g->w > 0))
+                   {
+                      tx = xx;
+                      xx = ((long long )gw * xx) / g->w;
+                      ww = (((long long)gw * (tx + ww)) / g->w) - xx;
+                   }
+                 if ((gh != g->h) && (g->h > 0))
+                   {
+                      ty = yy;
+                      yy = ((long long)gh * yy) / g->h;
+                      hh = (((long long)gh * (ty + hh)) / g->h) - yy;
+                   }
+
+                 if (!group->clas->hide
+                      && xx-px+ax+ox >= ox && xx-px+ax+ox<= ox+ow
+                      && yy-py+ay+oy >= oy && yy-py+ay+oy<= oy+oh)
+                   {
+                      if (!group->obj) _group_object_create(group);
+
+                      if (group->update_nbelems)
+                        {
+                           group->update_nbelems = EINA_FALSE;
+                           if (eina_list_count(group->markers) > 1)
+                             {
+                                snprintf(buf, sizeof(buf), "%d", eina_list_count(group->markers));
+                                edje_object_part_text_set(elm_layout_edje_get(group->obj), "elm.text", buf);
+                             }
+                           else
+                             edje_object_part_text_set(elm_layout_edje_get(group->obj), "elm.text", "");
+                        }
+                      evas_object_move(group->obj,
+                                        xx - px + ax + ox - ww/2,
+                                        yy - py + ay + oy - hh/2);
+                      if (!wd->paused_markers || group->update_resize)
+                        {
+                           group->update_resize = EINA_FALSE;
+                           evas_object_resize(group->obj, ww, hh);
+                        }
+                      if (group->update_raise)
+                        {
+                           group->update_raise = EINA_FALSE;
+                           evas_object_raise(group->obj);
+                           evas_object_show(group->obj);
+                        }
+                      if (group->bubble) _group_bubble_place(group);
+                   }
+                 else if (group->obj)
+                   {
+                      _group_object_free(group);
+                   }
+              }
+         }
+     }
+}
+
+static void
+grid_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord ax, ay, gw, gh, tx, ty;
+   int xx, yy, ww, hh;
+
+   if (!wd) return;
+   
+   ax = 0;
+   ay = 0;
+   gw = wd->size.w;
+   gh = wd->size.h;
+   if (ow > gw) ax = (ow - gw) / 2;
+   if (oh > gh) ay = (oh - gh) / 2;
+
+   Eina_Iterator *it = eina_matrixsparse_iterator_new(g->grid);
+   Eina_Matrixsparse_Cell *cell;
+
+   EINA_ITERATOR_FOREACH(it, cell)
+     {
+       Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
+
+       xx = gi->out.x;
+       yy = gi->out.y;
+       ww = gi->out.w;
+       hh = gi->out.h;
+       if ((gw != g->w) && (g->w > 0))
+         {
+            tx = xx;
+            xx = ((long long )gw * xx) / g->w;
+            ww = (((long long)gw * (tx + ww)) / g->w) - xx;
+         }
+       if ((gh != g->h) && (g->h > 0))
+         {
+            ty = yy;
+            yy = ((long long)gh * yy) / g->h;
+            hh = (((long long)gh * (ty + hh)) / g->h) - yy;
+         }
+       evas_object_move(gi->img,
+                         xx - px + ax + ox,
+                         yy - py + ay + oy);
+        
+       evas_object_resize(gi->img, ww, hh);
+
+       /*evas_object_move(gi->txt,
+         xx - px + ax + ox,
+         yy - py + ay + oy);
+
+         evas_object_resize(gi->txt, ww, hh);
+         */
+     }
+   eina_iterator_free(it);
+}
+
+static void
+grid_clear(Evas_Object *obj, Grid *g)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   char buf[PATH_MAX];
+
+   if (!wd) return;
+   if (!g->grid) return;
+
+   Eina_Iterator *it = eina_matrixsparse_iterator_new(g->grid);
+   Eina_Matrixsparse_Cell *cell;
+
+   snprintf(buf, sizeof(buf), DEST_DIR_ZOOM_PATH, wd->id, g->zoom);
+   ecore_file_recursive_rm(buf);
+
+   EINA_ITERATOR_FOREACH(it, cell)
+     {
+       Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
+       evas_object_del(gi->img);
+       //evas_object_del(gi->txt);
+
+       if (gi->want)
+         {
+            gi->want = EINA_FALSE;
+            wd->preload_num--;
+            if (wd->preload_num == 0)
+              {
+                 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
+                       "elm,state,busy,stop", "elm");
+                 evas_object_smart_callback_call(obj, SIG_LOADED_DETAIL, NULL);
+              }
+         }
+
+       if (gi->job)
+         {
+            DBG("DOWNLOAD abort %s", gi->file);
+            ecore_file_download_abort(gi->job);
+            ecore_file_remove(gi->file);
+            gi->job = NULL;
+         }
+       if (gi->file)
+         eina_stringshare_del(gi->file);
+        
+       free(gi);
+     }
+   eina_matrixsparse_free(g->grid);
+   eina_iterator_free(it);
+   g->grid = NULL;
+   g->gw = 0;
+   g->gh = 0;
+}
+
+static void
+_tile_update(Grid_Item *gi)
+{
+   gi->want = EINA_FALSE;
+   gi->download = EINA_FALSE;
+   evas_object_image_file_set(gi->img, gi->file, NULL);
+   if (evas_object_image_load_error_get(gi->img) != EVAS_LOAD_ERROR_NONE)
+     ecore_file_remove(gi->file);
+   
+   evas_object_show(gi->img);
+
+   //evas_object_text_text_set(gi->txt, gi->file);
+   //evas_object_show(gi->txt);
+
+   gi->have = EINA_TRUE;
+   gi->wd->preload_num--;
+   if (gi->wd->preload_num == 0)
+     {
+       edje_object_signal_emit(elm_smart_scroller_edje_object_get(gi->wd->scr),
+                                "elm,state,busy,stop", "elm");
+       evas_object_smart_callback_call(gi->wd->obj, SIG_LOADED_DETAIL, NULL);
+     }
+}
+
+
+static void
+_tile_downloaded(void *data, const char *file __UNUSED__, int status)
+{
+   Grid_Item *gi = data;
+
+   gi->download = EINA_FALSE;
+   gi->job = NULL;
+
+   DBG("DOWNLOAD done %s", gi->file);
+   if (gi->want && !status) _tile_update(gi);
+
+   if (status)
+     {
+       DBG("Download failed %s (%d) ", gi->file, status);
+       ecore_file_remove(gi->file);
+     }
+}
+
+static Grid *
+grid_create(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Grid *g;
+
+   g = calloc(1, sizeof(Grid));
+
+   g->zoom = wd->zoom;
+   g->tsize = wd->tsize;
+   g->wd = wd;
+
+   if (g->zoom > map_sources_tab[wd->source].zoom_max) return NULL;
+   if (g->zoom < map_sources_tab[wd->source].zoom_min) return NULL;
+
+   int size =  pow(2.0, wd->zoom);
+   g->gw = size;
+   g->gh = size;
+
+   g->w = g->tsize * g->gw;
+   g->h = g->tsize * g->gh;
+
+   g->grid = eina_matrixsparse_new(g->gh, g->gw, NULL, NULL);
+
+   return g;
+}
+
+static void
+grid_load(Evas_Object *obj, Grid *g)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   int x, y;
+   int size;
+   Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh, tx, ty, gw, gh, xx, yy, ww, hh;
+   Eina_Iterator *it;
+   Eina_Matrixsparse_Cell *cell;
+   Grid_Item *gi;
+
+   if (!wd) return;
+   evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
+   evas_output_viewport_get(evas_object_evas_get(wd->obj), &cvx, &cvy, &cvw, &cvh);
+                               
+   gw = wd->size.w;
+   gh = wd->size.h;
+
+   if ((gw <= 0) || (gh <= 0)) return;
+
+   size = g->tsize;
+   if ((gw != g->w) && (g->w > 0))
+     size = ((long long)gw * size) / g->w;
+   if (size < (g->tsize / 2)) return; // else we will load to much tiles
+
+   it = eina_matrixsparse_iterator_new(g->grid);
+   
+   EINA_ITERATOR_FOREACH(it, cell)
+     {
+       gi = eina_matrixsparse_cell_data_get(cell);
+
+       xx = gi->out.x;
+       yy = gi->out.y;
+       ww = gi->out.w;
+       hh = gi->out.h;
+
+       if ((gw != g->w) && (g->w > 0))
+         {
+            tx = xx;
+            xx = ((long long )gw * xx) / g->w;
+            ww = (((long long)gw * (tx + ww)) / g->w) - xx;
+         }
+       if ((gh != g->h) && (g->h > 0))
+         {
+            ty = yy;
+            yy = ((long long)gh * yy) / g->h;
+            hh = (((long long)gh * (ty + hh)) / g->h) - yy;
+         }
+
+        if (!ELM_RECTS_INTERSECT(xx - wd->pan_x + ox, 
+                                 yy  - wd->pan_y + oy,
+                                 ww, hh,
+                                 cvx, cvy, cvw, cvh))
+         {
+            if (gi->want)
+              {
+                 wd->preload_num--;
+                 if (wd->preload_num == 0)
+                   {
+                      edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
+                                               "elm,state,busy,stop", "elm");
+                      evas_object_smart_callback_call(obj, SIG_LOADED_DETAIL,
+                                                      NULL);
+                   }
+                 evas_object_hide(gi->img);
+                 //evas_object_hide(gi->txt);
+                 evas_object_image_file_set(gi->img, NULL, NULL);
+                 gi->want = EINA_FALSE;
+                 gi->have = EINA_FALSE;
+                  
+                 if (gi->job)
+                   {
+                      DBG("DOWNLOAD abort %s", gi->file);
+                      ecore_file_download_abort(gi->job);
+                      ecore_file_remove(gi->file);
+                      gi->job = NULL;
+                   }
+                 gi->download = EINA_FALSE;
+              }
+            else if (gi->have)
+              {
+                 evas_object_hide(gi->img);
+                 //evas_object_hide(gi->txt);
+                 evas_object_image_preload(gi->img, 1);
+                 evas_object_image_file_set(gi->img, NULL, NULL);
+                 gi->have = EINA_FALSE;
+                 gi->want = EINA_FALSE;
+              }
+         }
+     }
+   eina_iterator_free(it);
+
+   xx = wd->pan_x / size;
+   if (xx < 0) xx = 0;
+
+   yy = wd->pan_y / size;
+   if (yy < 0) yy = 0;
+
+   ww = ow / size + 1;
+   if (xx + ww >= g->gw) ww = g->gw - xx - 1;
+
+   hh = oh / size + 1;
+   if (yy + hh >= g->gh) hh = g->gh - yy - 1;
+
+   for (y = yy; y <= yy + hh; y++)
+     {
+       for (x = xx; x <= xx + ww; x++)
+         {
+            gi = eina_matrixsparse_data_idx_get(g->grid, y, x);
+
+            if ((!gi) && (g != eina_list_data_get(wd->grids)))
+              continue;
+
+            if (!gi)
+              {
+                 gi = calloc(1, sizeof(Grid_Item));
+                 gi->src.x = x * g->tsize;
+                 gi->src.y = y * g->tsize;
+                 gi->src.w = g->tsize;
+                 gi->src.h = g->tsize;
+
+                 gi->out.x = gi->src.x;
+                 gi->out.y = gi->src.y;
+                 gi->out.w = gi->src.w;
+                 gi->out.h = gi->src.h;
+
+                 gi->wd = wd;
+                  
+                 gi->img = evas_object_image_add(evas_object_evas_get(obj));
+                 evas_object_image_scale_hint_set
+                    (gi->img, EVAS_IMAGE_SCALE_HINT_DYNAMIC);
+                 evas_object_image_filled_set(gi->img, 1);
+                  
+                 evas_object_smart_member_add(gi->img,
+                                               wd->pan_smart);
+                 elm_widget_sub_object_add(obj, gi->img);
+                 evas_object_pass_events_set(gi->img, 1);
+                  
+                 /*gi->txt = evas_object_text_add(evas_object_evas_get(obj));
+                   evas_object_text_font_set(gi->txt, "Vera", 12);
+                   evas_object_color_set(gi->txt, 100, 100, 100, 255);
+                   evas_object_smart_member_add(gi->txt,
+                   wd->pan_smart);
+                   elm_widget_sub_object_add(obj, gi->txt);
+                   evas_object_pass_events_set(gi->txt, 1);
+                   */
+                 eina_matrixsparse_data_idx_set(g->grid, y, x, gi);
+              }
+             
+            if (!gi->have && !gi->download)
+              {
+                 char buf[PATH_MAX], buf2[PATH_MAX];
+                 char *source;
+                  
+                 gi->want = EINA_TRUE;
+                  
+                 snprintf(buf, sizeof(buf), DEST_DIR_PATH, wd->id, g->zoom, x);
+                 if (!ecore_file_exists(buf))
+                   ecore_file_mkpath(buf);
+                  
+                 snprintf(buf2, sizeof(buf2), DEST_FILE_PATH, buf, y);
+                  
+                 source = map_sources_tab[wd->source].url_cb(x, y, g->zoom);
+                  
+                 eina_stringshare_replace(&gi->file, buf2);
+
+                 if (ecore_file_exists(buf2) || g == eina_list_data_get(wd->grids))
+                   {
+                      gi->download = EINA_TRUE;
+                      wd->preload_num++;
+                      if (wd->preload_num == 1)
+                        {
+                           edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
+                                                    "elm,state,busy,start", "elm");
+                           evas_object_smart_callback_call(obj,
+                                                           SIG_LOAD_DETAIL,
+                                                           NULL);
+                        }
+                       
+                      if (ecore_file_exists(buf2))
+                        _tile_update(gi);
+                      else
+                        {
+                           DBG("DOWNLOAD %s \t in %s", source, buf2);
+                           ecore_file_download(source, buf2, _tile_downloaded, NULL, gi, &(gi->job));
+                           if (!gi->job)
+                             DBG("Can't start to download %s", buf);
+                        }
+                   }
+                 if (source) free(source);
+              }
+            else if (gi->have)
+              evas_object_show(gi->img);
+         }
+     }
+}
+
+static void
+grid_clearall(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Grid *g;
+
+   if (!wd) return;
+   EINA_LIST_FREE(wd->grids, g)
+     {
+       grid_clear(obj, g);
+       free(g);
+     }
+}
+
+static void
+_smooth_update(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Eina_List *l;
+   Grid *g;
+
+   if (!wd) return;
+   EINA_LIST_FOREACH(wd->grids, l, g)
+     {
+       Eina_Iterator *it = eina_matrixsparse_iterator_new(g->grid);
+       Eina_Matrixsparse_Cell *cell;
+        
+       EINA_ITERATOR_FOREACH(it, cell)
+         {
+            Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
+            evas_object_image_smooth_scale_set(gi->img, (wd->nosmooth == 0));
+         }
+       eina_iterator_free(it);
+     }
+}
+
+static void
+_grid_raise(Grid *g)
+{
+   Eina_Iterator *it = eina_matrixsparse_iterator_new(g->grid);
+   Eina_Matrixsparse_Cell *cell;
+
+   g->wd->size.w = g->w;
+   g->wd->size.h = g->h;
+
+   EINA_ITERATOR_FOREACH(it, cell)
+     {
+       Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
+       evas_object_raise(gi->img);
+       //evas_object_raise(gi->txt);
+     }
+   eina_iterator_free(it);
+}
+
+static int
+_scr_timeout(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return 0;
+   wd->nosmooth--;
+   if (wd->nosmooth == 0) _smooth_update(data);
+   wd->scr_timer = NULL;
+   return 0;
+}
+
+static void
+_scr(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (!wd->scr_timer)
+     {
+       wd->nosmooth++;
+       if (wd->nosmooth == 1) _smooth_update(data);
+     }
+   if (wd->scr_timer) ecore_timer_del(wd->scr_timer);
+   wd->scr_timer = ecore_timer_add(0.5, _scr_timeout, data);
+}
+
+static int
+zoom_do(Evas_Object *obj, double t)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord xx, yy, ow, oh;
+
+   if (!wd) return 0;
+   if (t > 1.0) t = 1.0;
+
+   wd->size.w = (wd->size.ow * (1.0 - t)) + (wd->size.nw * t);
+   wd->size.h = (wd->size.oh * (1.0 - t)) + (wd->size.nh * t);
+
+   elm_smart_scroller_child_viewport_size_get(wd->scr, &ow, &oh);
+
+   if (wd->center_on.enabled)
+     {
+       elm_map_utils_convert_geo_into_coord(wd->center_on.lon, wd->center_on.lat, wd->size.w, &xx, &yy);
+       xx -= ow / 2;
+       yy -= oh / 2;
+     }
+   else
+     {
+       xx = (wd->size.spos.x * wd->size.w) - (ow / 2);
+       yy = (wd->size.spos.y * wd->size.h) - (oh / 2);
+     }
+
+   if (xx < 0) xx = 0;
+   else if (xx > (wd->size.w - ow)) xx = wd->size.w - ow;
+   if (yy < 0) yy = 0;
+   else if (yy > (wd->size.h - oh)) yy = wd->size.h - oh;
+
+   wd->show.show = EINA_TRUE;
+   wd->show.x = xx;
+   wd->show.y = yy;
+   wd->show.w = ow;
+   wd->show.h = oh;
+
+   if (wd->calc_job) ecore_job_del(wd->calc_job);
+   wd->calc_job = ecore_job_add(_calc_job, wd);
+   if (t >= 1.0)
+     {
+       return 0;
+     }
+   return 1;
+}
+
+static int
+_zoom_anim(void *data)
+{
+   Evas_Object *obj = data;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   double t;
+   int go;
+
+   if (!wd) return 0;
+   t = ecore_loop_time_get();
+   if (t >= wd->t_end)
+     t = 1.0;
+   else if (wd->t_end > wd->t_start)
+     t = (t - wd->t_start) / (wd->t_end - wd->t_start);
+   else
+     t = 1.0;
+   t = 1.0 - t;
+   t = 1.0 - (t * t);
+   go = zoom_do(obj, t);
+   if (!go)
+     {
+       wd->nosmooth--;
+       if (wd->nosmooth == 0) _smooth_update(data);
+       wd->zoom_animator = NULL;
+       evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
+     }
+   return go;
+}
+
+static int
+_long_press(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return 0;
+   wd->long_timer = NULL;
+   wd->longpressed = EINA_TRUE;
+   evas_object_smart_callback_call(data, SIG_LONGPRESSED, NULL);
+   return 0;
+}
+
+static void
+_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Event_Mouse_Down *ev = event_info;
+   if (!wd) return;
+   if (ev->button != 1) return;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) wd->on_hold = EINA_TRUE;
+   else wd->on_hold = EINA_FALSE;
+   if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
+     evas_object_smart_callback_call(data, SIG_CLICKED_DOUBLE, NULL);
+   else
+     evas_object_smart_callback_call(data, SIG_PRESS, NULL);
+   wd->longpressed = EINA_FALSE;
+   if (wd->long_timer) ecore_timer_del(wd->long_timer);
+   wd->long_timer = ecore_timer_add(1.0, _long_press, data);
+}
+
+static void
+_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Event_Mouse_Up *ev = event_info;
+   if (!wd) return;
+   if (ev->button != 1) return;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) wd->on_hold = EINA_TRUE;
+   else wd->on_hold = EINA_FALSE;
+   if (wd->long_timer)
+     {
+       ecore_timer_del(wd->long_timer);
+       wd->long_timer = NULL;
+     }
+   if (!wd->on_hold)
+     evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
+   wd->on_hold = EINA_FALSE;
+}
+
+static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_NULL;
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Elm_Map_Group_Class *group_clas;
+   Elm_Map_Marker_Class *marker_clas;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   EINA_LIST_FREE(wd->groups_clas, group_clas)
+     {
+       if (group_clas->style)
+         eina_stringshare_del(group_clas->style);
+       free(group_clas);
+     }
+
+   EINA_LIST_FREE(wd->markers_clas, marker_clas)
+     {
+       if (marker_clas->style)
+         eina_stringshare_del(marker_clas->style);
+       free(marker_clas);
+     }
+
+   if (wd->calc_job) ecore_job_del(wd->calc_job);
+   if (wd->scr_timer) ecore_timer_del(wd->scr_timer);
+   if (wd->zoom_animator) ecore_animator_del(wd->zoom_animator);
+   if (wd->long_timer) ecore_timer_del(wd->long_timer);
+
+   free(wd);
+}
+
+static void
+_del_pre_hook(Evas_Object *obj)
+{
+   Marker_Group *group;
+   Elm_Map_Marker *marker;
+   int i;
+   Eina_Bool free_marker = EINA_TRUE;
+   Eina_List *l;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   grid_clearall(obj);
+
+   if (!wd) return;
+   for (i = 0; i < ZOOM_MAX + 1; i++)
+     {
+       if (!wd->markers[i]) continue;
+       Eina_Iterator *it = eina_matrixsparse_iterator_new(wd->markers[i]);
+       Eina_Matrixsparse_Cell *cell;
+        
+       EINA_ITERATOR_FOREACH(it, cell)
+         {
+            l =  eina_matrixsparse_cell_data_get(cell);
+            EINA_LIST_FREE(l, group)
+              {
+                 EINA_LIST_FREE(group->markers, marker)
+                   {
+                      evas_object_event_callback_del_full(group->sc, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                                           _bubble_sc_hits_changed_cb, group);
+                      if (free_marker) free(marker);
+                   }
+                 free(group);
+              }
+            free_marker = EINA_FALSE;
+         }
+       eina_iterator_free(it);
+       eina_matrixsparse_free(wd->markers[i]);
+     }
+
+   evas_object_del(wd->pan_smart);
+   wd->pan_smart = NULL;
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "map", "base", elm_widget_style_get(obj));
+//   edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   if (!wd) return;
+   evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_calc_job(void *data)
+{
+   Widget_Data *wd = data;
+   Evas_Coord minw, minh;
+
+   minw = wd->size.w;
+   minh = wd->size.h;
+   if (wd->resized)
+     {
+       wd->resized = 0;
+       if (wd->mode != ELM_MAP_ZOOM_MODE_MANUAL)
+         {
+            double tz = wd->zoom;
+            wd->zoom = 0.0;
+            elm_map_zoom_set(wd->obj, tz);
+         }
+     }
+   if ((minw != wd->minw) || (minh != wd->minh))
+     {
+       wd->minw = minw;
+       wd->minh = minh;
+       evas_object_smart_callback_call(wd->pan_smart, SIG_CHANGED, NULL);
+       _sizing_eval(wd->obj);
+     }
+   wd->calc_job = NULL;
+   evas_object_smart_changed(wd->pan_smart);
+}
+
+static void
+_pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
+   sd->wd->pan_x = x;
+   sd->wd->pan_y = y;
+   evas_object_smart_changed(obj);
+}
+
+static void
+_pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (x) *x = sd->wd->pan_x;
+   if (y) *y = sd->wd->pan_y;
+}
+
+static void
+_pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   Evas_Coord ow, oh;
+   if (!sd) return;
+   evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
+   ow = sd->wd->minw - ow;
+   if (ow < 0) ow = 0;
+   oh = sd->wd->minh - oh;
+   if (oh < 0) oh = 0;
+   if (x) *x = ow;
+   if (y) *y = oh;
+}
+
+static void
+_pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (w) *w = sd->wd->minw;
+   if (h) *h = sd->wd->minh;
+}
+
+static void
+_pan_add(Evas_Object *obj)
+{
+   Pan *sd;
+   Evas_Object_Smart_Clipped_Data *cd;
+   _pan_sc.add(obj);
+   cd = evas_object_smart_data_get(obj);
+   if (!cd) return;
+   sd = calloc(1, sizeof(Pan));
+   if (!sd) return;
+   sd->__clipped_data = *cd;
+   free(cd);
+   evas_object_smart_data_set(obj, sd);
+}
+
+static void
+_pan_del(Evas_Object *obj)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   _pan_sc.del(obj);
+}
+
+static void
+_pan_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   Evas_Coord ow, oh;
+   if (!sd) return;
+   evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
+   if ((ow == w) && (oh == h)) return;
+   sd->wd->resized = 1;
+   if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
+   sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
+}
+
+static void
+_pan_calculate(Evas_Object *obj)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   Evas_Coord ox, oy, ow, oh;
+   Eina_List *l;
+   Grid *g;
+   if (!sd) return;
+   evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
+   rect_place(sd->wd->obj, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
+   EINA_LIST_FOREACH(sd->wd->grids, l, g)
+     {
+       grid_load(sd->wd->obj, g);
+       grid_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
+       marker_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
+     }
+}
+
+static void
+_pan_move(Evas_Object *obj, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
+   sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
+}
+
+static void
+_hold_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_hold_set(wd->scr, 1);
+}
+
+static void
+_hold_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_hold_set(wd->scr, 0);
+}
+
+static void
+_freeze_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_freeze_set(wd->scr, 1);
+}
+
+static void
+_freeze_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_freeze_set(wd->scr, 0);
+}
+
+static void
+_scr_anim_start(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, "scroll,anim,start", NULL);
+}
+
+static void
+_scr_anim_stop(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, "scroll,anim,stop", NULL);
+}
+
+static void
+_scr_drag_start(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   
+   Widget_Data *wd = elm_widget_data_get(data);
+   wd->center_on.enabled = EINA_FALSE;
+   evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
+}
+
+static void
+_scr_drag_stop(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
+}
+
+static void
+_scr_scroll(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_SCROLL, NULL);
+}
+
+
+static void
+_group_object_create(Marker_Group *group)
+{
+   const char *style = "radio";
+   Evas_Object *icon = NULL;
+
+   if (group->obj) return;
+   if (!group->clas->priv.objs_notused || eina_list_count(group->markers) == 1)
+     {
+       //set icon and style
+       if (eina_list_count(group->markers) == 1)
+         {
+            Elm_Map_Marker *m = eina_list_data_get(group->markers);
+            if (m->clas->style)
+              style = m->clas->style;
+             
+            if (m->clas->func.icon_get)
+              icon = m->clas->func.icon_get(group->wd->obj, m, m->data);
+             
+            group->delete_object = EINA_TRUE;
+         }
+       else
+         {
+            if (group->clas->style)
+              style = group->clas->style;
+             
+            if (group->clas->func.icon_get)
+              icon = group->clas->func.icon_get(group->wd->obj, group->clas->data);
+             
+            group->delete_object = EINA_FALSE;
+         }
+        
+       group->obj = elm_layout_add(group->wd->obj);
+       elm_layout_theme_set(group->obj, "map/marker", style, elm_widget_style_get(group->wd->obj));
+
+       if (icon) elm_layout_content_set(group->obj, "elm.icon", icon);
+        
+       evas_object_smart_member_add(group->obj, group->wd->pan_smart);
+       elm_widget_sub_object_add(group->wd->obj, group->obj);
+        
+       if (!group->delete_object)
+         group->clas->priv.objs_used = eina_list_append(group->clas->priv.objs_used, group->obj);
+     }
+   else
+     {
+       group->delete_object = EINA_FALSE;
+        
+       group->obj = eina_list_data_get(group->clas->priv.objs_notused);
+       group->clas->priv.objs_used = eina_list_append(group->clas->priv.objs_used, group->obj);
+       group->clas->priv.objs_notused = eina_list_remove(group->clas->priv.objs_notused, group->obj);
+       evas_object_show(group->obj);
+     }
+
+   edje_object_signal_callback_add(elm_layout_edje_get(group->obj), "open", "elm", _group_open_cb, group);
+   edje_object_signal_callback_add(elm_layout_edje_get(group->obj), "bringin", "elm", _group_bringin_cb, group);
+
+   group->update_nbelems = EINA_TRUE;
+   group->update_resize = EINA_TRUE;
+   group->update_raise = EINA_TRUE;
+
+   if (group->open) _group_bubble_create(group);
+}
+
+static void
+_group_object_free(Marker_Group *group)
+{
+   if (!group->obj) return;
+   if (!group->delete_object)
+     {
+       group->clas->priv.objs_notused = eina_list_append(group->clas->priv.objs_notused, group->obj);
+       group->clas->priv.objs_used = eina_list_remove(group->clas->priv.objs_used, group->obj);
+       evas_object_hide(group->obj);
+
+       edje_object_signal_callback_del(elm_layout_edje_get(group->obj), "open", "elm", _group_open_cb);
+       edje_object_signal_callback_del(elm_layout_edje_get(group->obj), "bringin", "elm", _group_bringin_cb);
+     }
+   else
+     evas_object_del(group->obj);
+
+   group->obj = NULL;
+   _group_bubble_free(group);
+}
+
+static void
+_group_bubble_mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Marker_Group *group = data;
+
+   if (!evas_object_above_get(group->rect)) return;
+   evas_object_raise(group->bubble);
+   evas_object_raise(group->sc);
+   evas_object_raise(group->rect);
+}
+
+static void
+_group_bubble_create(Marker_Group *group)
+{
+   if (group->bubble) return;
+
+   group->wd->opened_bubbles = eina_list_append(group->wd->opened_bubbles, group);
+   group->bubble = edje_object_add(evas_object_evas_get(group->obj));
+   _elm_theme_object_set(group->wd->obj, group->bubble, "map", "marker_bubble",
+                         elm_widget_style_get(group->wd->obj));
+   evas_object_smart_member_add(group->bubble,
+                                group->wd->obj);
+   elm_widget_sub_object_add(group->wd->obj, group->bubble);
+   
+   _group_bubble_content_free(group);
+   if (!_group_bubble_content_update(group))
+     {
+       //no content, we can delete the bubble
+       _group_bubble_free(group);
+       return;
+     }
+   
+   group->rect = evas_object_rectangle_add(evas_object_evas_get(group->obj));
+   evas_object_color_set(group->rect, 0, 0, 0, 0);
+   evas_object_repeat_events_set(group->rect, EINA_TRUE);
+   evas_object_smart_member_add(group->rect, group->wd->obj);
+   elm_widget_sub_object_add(group->wd->obj, group->rect);
+   
+   evas_object_event_callback_add(group->rect, EVAS_CALLBACK_MOUSE_UP, _group_bubble_mouse_up_cb, group);
+   
+   _group_bubble_place(group);
+}
+
+static void _bubble_sc_hits_changed_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _group_bubble_place(data);
+}
+
+static int
+_group_bubble_content_update(Marker_Group *group)
+{
+   Eina_List *l;
+   Elm_Map_Marker *marker;
+   int i = 0;
+
+   if (!group->bubble) return 1;
+
+   if (!group->sc)
+     {
+       group->sc = elm_scroller_add(group->bubble);
+       elm_scroller_content_min_limit(group->sc, EINA_FALSE, EINA_TRUE);
+       elm_scroller_policy_set(group->sc, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
+       elm_scroller_bounce_set(group->sc, EINA_TRUE, EINA_FALSE);
+       edje_object_part_swallow(group->bubble, "elm.swallow.content", group->sc);
+       evas_object_show(group->sc);
+       evas_object_smart_member_add(group->sc,
+                                     group->wd->obj);
+       elm_widget_sub_object_add(group->wd->obj, group->sc);
+        
+       group->bx = elm_box_add(group->bubble);
+       evas_object_size_hint_align_set(group->bx, -1, -1);
+       evas_object_size_hint_weight_set(group->bx, 0.5, 0.5);
+       elm_box_horizontal_set(group->bx, EINA_TRUE);
+       evas_object_show(group->bx);
+        
+       elm_scroller_content_set(group->sc, group->bx);
+        
+       evas_object_event_callback_add(group->sc, EVAS_CALLBACK_RESIZE,
+                                       _bubble_sc_hits_changed_cb, group);
+     }
+   
+   EINA_LIST_FOREACH(group->markers, l, marker)
+     {
+       if (i >= group->wd->markers_max_num) break;
+       if (!marker->content && marker->clas->func.get)
+         marker->content = marker->clas->func.get(group->wd->obj, marker, marker->data);
+       else if (marker->content)
+         elm_box_unpack(group->bx, marker->content);
+       if (marker->content)
+         {
+            elm_box_pack_end(group->bx, marker->content);
+            i++;
+         }
+     }
+   return i;
+}
+
+static void
+_group_bubble_content_free(Marker_Group *group)
+{
+   Eina_List *l;
+   Elm_Map_Marker *marker;
+
+   if (!group->sc) return;
+   EINA_LIST_FOREACH(group->markers, l, marker)
+     {
+       if (marker->content && marker->clas->func.del)
+         marker->clas->func.del(group->wd->obj, marker, marker->data, marker->content);
+       else if (marker->content)
+         evas_object_del(marker->content);
+       marker->content = NULL;
+     }
+   evas_object_del(group->sc);
+   group->sc = NULL;
+}
+
+static void
+_group_bubble_free(Marker_Group *group)
+{
+   if (!group->bubble) return;
+   group->wd->opened_bubbles = eina_list_remove(group->wd->opened_bubbles, group);
+   evas_object_event_callback_del_full(group->sc, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                       _bubble_sc_hits_changed_cb, group);
+   evas_object_del(group->bubble);
+   evas_object_del(group->rect);
+   group->bubble = NULL;
+   _group_bubble_content_free(group);
+}
+
+static void
+_group_bubble_place(Marker_Group *group)
+{
+   Evas_Coord x, y, w;
+   Evas_Coord xx, yy, ww, hh;
+   const char *s;
+
+   if (!group->bubble || !group->obj) return;
+
+   evas_object_geometry_get(group->obj, &x, &y, &w, NULL);
+   edje_object_size_min_calc(group->bubble, NULL, &hh);
+
+   s = edje_object_data_get(group->bubble, "size_w");
+   ww = atoi(s);
+   xx = x + w / 2 - ww / 2;
+   yy = y-hh;
+
+   evas_object_move(group->bubble, xx, yy);
+   evas_object_resize(group->bubble, ww, hh);
+   evas_object_show(group->bubble);
+
+   evas_object_move(group->rect, xx, yy);
+   evas_object_resize(group->rect, ww, hh);
+   evas_object_show(group->rect);
+}
+
+static void
+_group_bringin_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *soure __UNUSED__)
+{
+   Marker_Group *group = data;
+   Elm_Map_Marker *marker = eina_list_data_get(group->markers);
+   if (!marker) return;
+   group->bringin = EINA_TRUE;
+   elm_map_geo_region_bring_in(group->wd->obj, marker->longitude, marker->latitude);
+}
+
+static void
+_group_open_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *soure __UNUSED__)
+{
+   Marker_Group *group = data;
+
+   if (group->bringin)
+     {
+       group->bringin = EINA_FALSE;
+       return;
+     }
+
+   if (group->bubble)
+     {
+       group->open = EINA_FALSE;
+       _group_bubble_free(group);
+       return;
+     }
+   group->open = EINA_TRUE;
+   _group_bubble_create(group);
+}
+
+static int idnum = 1;
+
+/**
+ * Add a new Map object
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Map
+ */
+EAPI Evas_Object *
+elm_map_add(Evas_Object *parent)
+{
+   Evas *e;
+   Widget_Data *wd;
+   Evas_Coord minw, minh;
+   Evas_Object *obj;
+   static Evas_Smart *smart = NULL;
+
+   if (!ecore_file_download_protocol_available("http://"))
+     {
+       ERR("Ecore must be built with the support of HTTP for the widget map !");
+       return NULL;
+     }
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "map");
+   elm_widget_type_set(obj, "map");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_del_pre_hook_set(obj, _del_pre_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   wd->scr = elm_smart_scroller_add(e);
+   elm_smart_scroller_widget_set(wd->scr, obj);
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "map", "base", "default");
+   evas_object_smart_callback_add(wd->scr, "scroll", _scr, obj);
+   evas_object_smart_callback_add(wd->scr, "drag", _scr, obj);
+   elm_widget_resize_object_set(obj, wd->scr);
+
+   evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
+   evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
+   evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
+   evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
+   evas_object_smart_callback_add(wd->scr, "scroll", _scr_scroll, obj);
+
+   elm_smart_scroller_bounce_allow_set(wd->scr, 1, 1);
+
+   wd->obj = obj;
+
+   wd->markers_max_num = 30;
+   wd->source = ELM_MAP_SOURCE_MAPNIK;
+
+   evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
+   evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
+   evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
+   evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
+
+   if (!smart)
+     {
+       static Evas_Smart_Class sc;
+
+       evas_object_smart_clipped_smart_set(&_pan_sc);
+       sc = _pan_sc;
+       sc.name = "elm_map_pan";
+       sc.version = EVAS_SMART_CLASS_VERSION;
+       sc.add = _pan_add;
+       sc.del = _pan_del;
+       sc.resize = _pan_resize;
+       sc.move = _pan_move;
+       sc.calculate = _pan_calculate;
+       smart = evas_smart_class_new(&sc);
+     }
+   if (smart)
+     {
+       wd->pan_smart = evas_object_smart_add(e, smart);
+       wd->pan = evas_object_smart_data_get(wd->pan_smart);
+       wd->pan->wd = wd;
+     }
+
+   elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
+        _pan_set, _pan_get,
+        _pan_max_get, _pan_child_size_get);
+
+   wd->rect = evas_object_rectangle_add(e);
+   evas_object_event_callback_add(wd->rect, EVAS_CALLBACK_MOUSE_DOWN,
+        _mouse_down, obj);
+   evas_object_event_callback_add(wd->rect, EVAS_CALLBACK_MOUSE_UP,
+        _mouse_up, obj);
+   evas_object_smart_member_add(wd->rect, wd->pan_smart);
+   elm_widget_sub_object_add(obj, wd->rect);
+   evas_object_show(wd->rect);
+   evas_object_color_set(wd->rect, 0, 0, 0, 0);
+
+   wd->zoom = -1;
+   wd->mode = ELM_MAP_ZOOM_MODE_MANUAL;
+   wd->id = ((int)getpid() << 16) | idnum;
+   idnum++;
+
+   wd->tsize = 256;
+
+   edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
+        &minw, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+
+   wd->paused = EINA_TRUE;
+   elm_map_zoom_set(obj, 0);
+   wd->paused = EINA_FALSE;
+
+   _sizing_eval(obj);
+
+   wd->calc_job = ecore_job_add(_calc_job, wd);
+
+   // TODO: convert Elementary to subclassing of Evas_Smart_Class
+   // TODO: and save some bytes, making descriptions per-class and not instance!
+   evas_object_smart_callbacks_descriptions_set(obj, _signals);
+   return obj;
+}
+
+/**
+ * Set the zoom level of the map
+ *
+ * This sets the zoom level. 0 is the world map and 18 is the maximum zoom.
+ *
+ * @param obj The map object
+ * @param zoom The zoom level to set
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_zoom_set(Evas_Object *obj, int zoom)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Eina_List *l;
+   Grid *g, *g_zoom = NULL;
+   Evas_Coord rx, ry, rw, rh;
+   int z;
+   int zoom_changed = 0, started = 0;
+   
+   if (!wd) return;
+   if (zoom < 0 ) zoom = 0;
+   if (zoom > map_sources_tab[wd->source].zoom_max)
+     zoom = map_sources_tab[wd->source].zoom_max;
+   if (zoom < map_sources_tab[wd->source].zoom_min)
+     zoom = map_sources_tab[wd->source].zoom_min;
+   if (zoom == wd->zoom) return;
+   
+   wd->zoom = zoom;
+   wd->size.ow = wd->size.w;
+   wd->size.oh = wd->size.h;
+   elm_smart_scroller_child_pos_get(wd->scr, &rx, &ry);
+   elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
+
+   if (wd->mode == ELM_MAP_ZOOM_MODE_MANUAL)
+     {
+       wd->size.nw = pow(2.0, wd->zoom) * wd->tsize;
+       wd->size.nh = pow(2.0, wd->zoom) * wd->tsize;
+     }
+   else if (wd->mode == ELM_MAP_ZOOM_MODE_AUTO_FIT)
+     {
+       int p2w, p2h;
+       int cumulw, cumulh;
+
+       cumulw = wd->tsize;
+       p2w = 0;
+       while (cumulw <= rw)
+         {
+            p2w++;
+            cumulw *= 2;
+         }
+       p2w--;
+
+       cumulh = wd->tsize;
+       p2h = 0;
+       while (cumulh <= rh)
+         {
+            p2h++;
+            cumulh *= 2;
+         }
+       p2h--;
+        
+       if (p2w < p2h)
+         z = p2w;
+       else
+         z = p2h;
+        
+       wd->zoom = z;
+       wd->size.nw = pow(2.0, wd->zoom) * wd->tsize;
+       wd->size.nh = pow(2.0, wd->zoom) * wd->tsize;
+     }
+   else if (wd->mode == ELM_MAP_ZOOM_MODE_AUTO_FILL)
+     {
+       int p2w, p2h;
+       int cumulw, cumulh;
+        
+       cumulw = wd->tsize;
+       p2w = 0;
+       while (cumulw <= rw)
+         {
+            p2w++;
+            cumulw *= 2;
+         }
+       p2w--;
+
+       cumulh = wd->tsize;
+       p2h = 0;
+       while (cumulh <= rh)
+         {
+            p2h++;
+            cumulh *= 2;
+         }
+       p2h--;
+
+       if (p2w > p2h)
+         z = p2w;
+       else
+         z = p2h;
+        
+       wd->zoom = z;
+       wd->size.nw = pow(2.0, wd->zoom) * wd->tsize;
+       wd->size.nh = pow(2.0, wd->zoom) * wd->tsize;
+     }
+
+   EINA_LIST_FOREACH(wd->grids, l, g)
+     {
+       if (g->zoom == wd->zoom)
+         {
+            wd->grids = eina_list_remove(wd->grids, g);
+            wd->grids = eina_list_prepend(wd->grids, g);
+            _grid_raise(g);
+            goto done;
+         }
+     }
+   g = grid_create(obj);
+   if (g)
+     {
+       if (eina_list_count(wd->grids) > 1)
+         {
+            g_zoom = eina_list_last(wd->grids)->data;
+            wd->grids = eina_list_remove(wd->grids, g_zoom);
+            grid_clear(obj, g_zoom);
+            free(g_zoom);
+         }
+       wd->grids = eina_list_prepend(wd->grids, g);
+     }
+   else
+     {
+       EINA_LIST_FREE(wd->grids, g)
+         {
+            grid_clear(obj, g);
+            free(g);
+         }
+     }
+done:
+
+   wd->t_start = ecore_loop_time_get();
+   wd->t_end = wd->t_start + _elm_config->zoom_friction;
+   if ((wd->size.w > 0) && (wd->size.h > 0))
+     {
+       wd->size.spos.x = (double)(rx + (rw / 2)) / (double)wd->size.ow;
+       wd->size.spos.y = (double)(ry + (rh / 2)) / (double)wd->size.oh;
+     }
+   else
+     {
+       wd->size.spos.x = 0.5;
+       wd->size.spos.y = 0.5;
+     }
+   if (rw > wd->size.ow) wd->size.spos.x = 0.5;
+   if (rh > wd->size.oh) wd->size.spos.y = 0.5;
+   if (wd->size.spos.x > 1.0) wd->size.spos.x = 1.0;
+   if (wd->size.spos.y > 1.0) wd->size.spos.y = 1.0;
+   if (wd->paused)
+     {
+       zoom_do(obj, 1.0);
+     }
+   else
+     {
+       if (!wd->zoom_animator)
+         {
+            wd->zoom_animator = ecore_animator_add(_zoom_anim, obj);
+            wd->nosmooth++;
+            if (wd->nosmooth == 1) _smooth_update(obj);
+            started = 1;
+         }
+     }
+   if (wd->zoom_animator)
+     {
+       if (!_zoom_anim(obj))
+         {
+            ecore_animator_del(wd->zoom_animator);
+            wd->zoom_animator = NULL;
+         }
+     }
+   if (wd->calc_job) ecore_job_del(wd->calc_job);
+   wd->calc_job = ecore_job_add(_calc_job, wd);
+   if (!wd->paused)
+     {
+       if (started)
+         evas_object_smart_callback_call(obj, SIG_ZOOM_START, NULL);
+       if (!wd->zoom_animator)
+         evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
+     }
+
+   if (zoom_changed)
+     evas_object_smart_callback_call(obj, SIG_ZOOM_CHANGE, NULL);
+}
+
+/**
+ * Get the zoom level of the photo
+ *
+ * This returns the current zoom level of the map object. Note that if
+ * you set the fill mode to other than ELM_MAP_ZOOM_MODE_MANUAL
+ * (which is the default), the zoom level may be changed at any time by the
+ * map object itself to account for map size and map viewpoer size
+ *
+ * @param obj The map object
+ * @return The current zoom level
+ *
+ * @ingroup Map
+ */
+EAPI double
+elm_map_zoom_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 1.0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 1.0;
+   return wd->zoom;
+}
+
+/**
+ * Set the zoom mode
+ *
+ * This sets the zoom mode to manual or one of several automatic levels.
+ * Manual (ELM_MAP_ZOOM_MODE_MANUAL) means that zoom is set manually by
+ * elm_map_zoom_set() and will stay at that level until changed by code
+ * or until zoom mode is changed. This is the default mode.
+ * The Automatic modes will allow the map object to automatically
+ * adjust zoom mode based on properties. ELM_MAP_ZOOM_MODE_AUTO_FIT) will
+ * adjust zoom so the photo fits inside the scroll frame with no pixels
+ * outside this area. ELM_MAP_ZOOM_MODE_AUTO_FILL will be similar but
+ * ensure no pixels within the frame are left unfilled. Do not forget that the valid sizes are 2^zoom, consequently the map may be smaller than the scroller view.
+ *
+ * @param obj The map object
+ * @param mode The desired mode
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_zoom_mode_set(Evas_Object *obj, Elm_Map_Zoom_Mode mode)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->mode == mode) return;
+   wd->mode = mode;
+     {
+       double tz = wd->zoom;
+       wd->zoom = 0.0;
+       elm_map_zoom_set(wd->obj, tz);
+     }
+}
+
+/**
+ * Get the zoom mode
+ *
+ * This gets the current zoom mode of the map object
+ *
+ * @param obj The map object
+ * @return The current zoom mode
+ *
+ * @ingroup Map
+ */
+EAPI Elm_Map_Zoom_Mode
+elm_map_zoom_mode_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) ELM_MAP_ZOOM_MODE_MANUAL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return ELM_MAP_ZOOM_MODE_MANUAL;
+   return wd->mode;
+}
+
+/**
+ * Centers the map at @p lon @p lat using an animation to scroll.
+ *
+ * @param obj The map object
+ * @param lon Longitude to center at
+ * @param lon Latitude to center at
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_geo_region_bring_in(Evas_Object *obj, double lon, double lat)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   int rx, ry, rw, rh;
+
+   if (!wd) return;
+   elm_map_utils_convert_geo_into_coord(lon, lat, wd->size.w, &rx, &ry);
+   elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
+
+   rx = rx - rw / 2;
+   ry = ry - rh / 2;
+
+   if (wd->zoom_animator)
+     {
+       wd->nosmooth--;
+       if (wd->nosmooth == 0) _smooth_update(obj);
+       ecore_animator_del(wd->zoom_animator);
+       wd->zoom_animator = NULL;
+       zoom_do(obj, 1.0);
+       evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
+     }
+   elm_smart_scroller_region_bring_in(wd->scr, rx, ry, rw, rh);
+
+   wd->center_on.enabled = EINA_TRUE;
+   wd->center_on.lon = lon;
+   wd->center_on.lat = lat;
+}
+
+/**
+ * Move the map to the current coordinates.
+ *
+ * This move the map to the current coordinates. The map will be centered on these coordinates.
+ *
+ * @param obj The map object
+ * @param lat The latitude.
+ * @param lon The longitude.
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_geo_region_show(Evas_Object *obj, double lon, double lat)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   int rx, ry, rw, rh;
+
+   if (!wd) return;
+   elm_map_utils_convert_geo_into_coord(lon, lat, wd->size.w, &rx, &ry);
+   elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
+
+   rx = rx - rw / 2;
+   ry = ry - rh / 2;
+
+   if (wd->zoom_animator)
+     {
+       wd->nosmooth--;
+       ecore_animator_del(wd->zoom_animator);
+       wd->zoom_animator = NULL;
+       zoom_do(obj, 1.0);
+       evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
+     }
+   elm_smart_scroller_child_region_show(wd->scr, rx, ry, rw, rh);
+
+   wd->center_on.enabled = EINA_TRUE;
+   wd->center_on.lon = lon;
+   wd->center_on.lat = lat;
+}
+
+/**
+ * Move the map to the current coordinates.
+ *
+ * This move the map to the current coordinates. The map will be centered on these coordinates.
+ *
+ * @param obj The map object
+ * @param lat The latitude.
+ * @param lon The longitude.
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_geo_region_get(const Evas_Object *obj, double *lon, double *lat)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord sx, sy, sw, sh;
+
+   if (!wd) return;
+   elm_smart_scroller_child_pos_get(wd->scr, &sx, &sy);
+   elm_smart_scroller_child_viewport_size_get(wd->scr, &sw, &sh);
+   sx += sw / 2;
+   sy += sh / 2;
+
+   elm_map_utils_convert_coord_into_geo(sx, sy, wd->size.w, lon, lat);
+}
+
+/**
+ * Set the paused state for map
+ *
+ * This sets the paused state to on (1) or off (0) for map. The default
+ * is off. This will stop zooming using animation change zoom levels and
+ * change instantly. This will stop any existing animations that are running.
+ *
+ * @param obj The map object
+ * @param paused The pause state to set
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_paused_set(Evas_Object *obj, Eina_Bool paused)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->paused == !!paused) return;
+   wd->paused = paused;
+   if (wd->paused)
+     {
+       if (wd->zoom_animator)
+         {
+            ecore_animator_del(wd->zoom_animator);
+            wd->zoom_animator = NULL;
+            zoom_do(obj, 1.0);
+            evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
+         }
+     }
+}
+
+/**
+ * Set the paused state for the markers
+ *
+ * This sets the paused state to on (1) or off (0) for the markers. The default
+ * is off. This will stop displaying the markers during change zoom levels. Set
+ * to on if you have a large number of markers.
+ *
+ * @param obj The map object
+ * @param paused The pause state to set
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_paused_markers_set(Evas_Object *obj, Eina_Bool paused)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->paused_markers == !!paused) return;
+   wd->paused_markers = paused;
+}
+
+/**
+ * Get the paused state for map
+ *
+ * This gets the current paused state for the map object.
+ *
+ * @param obj The map object
+ * @return The current paused state
+ *
+ * @ingroup Map
+ */
+EAPI Eina_Bool
+elm_map_paused_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->paused;
+}
+
+/**
+ * Get the paused state for the markers
+ *
+ * This gets the current paused state for the markers object.
+ *
+ * @param obj The map object
+ * @return The current paused state
+ *
+ * @ingroup Map
+ */
+EAPI Eina_Bool
+elm_map_paused_markers_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->paused_markers;
+}
+
+/**
+ * Convert a pixel coordinate (x,y) into a geographic coordinate (longitude, latitude).
+ *
+ * @param obj The map object
+ * @param x the coordinate
+ * @param y the coordinate
+ * @param size the size in pixels of the map. The map is a square and generally his size is : pow(2.0, zoom)*256.
+ * @param lon the longitude correspond to x
+ * @param lat the latitude correspond to y
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_utils_convert_coord_into_geo(int x, int y, int size, double *lon, double *lat)
+{
+   if (lon)
+     {
+       *lon = x / (double)size * 360.0 - 180;
+     }
+   if (lat)
+     {
+       double n = ELM_PI - 2.0 * ELM_PI * y / size;
+       *lat = 180.0 / ELM_PI * atan(0.5 * (exp(n) - exp(-n)));
+     }
+}
+
+/**
+ * Convert a geographic coordinate (longitude, latitude) into a pixel coordinate (x, y).
+ *
+ * @param obj The map object
+ * @param lon the longitude
+ * @param lat the latitude
+ * @param size the size in pixels of the map. The map is a square and generally his size is : pow(2.0, zoom)*256.
+ * @param x the coordinate correspond to the longitude
+ * @param y the coordinate correspond to the latitude
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_utils_convert_geo_into_coord(double lon, double lat, int size, int *x, int *y)
+{
+   if (x)
+     *x = floor((lon + 180.0) / 360.0 * size);
+   if (y)
+     *y = floor((1.0 - log( tan(lat * ELM_PI/180.0) + 1.0 / cos(lat * ELM_PI/180.0)) / ELM_PI) / 2.0 * size);
+}
+
+
+
+/**
+ * Add a marker on the map
+ *
+ * @param obj The map object
+ * @param lon the longitude
+ * @param lat the latitude
+ * @param clas the class to use
+ * @param data the data passed to the callbacks
+ *
+ * @return The marker object
+ *
+ * @ingroup Map
+ */
+EAPI Elm_Map_Marker *
+elm_map_marker_add(Evas_Object *obj, double lon, double lat, Elm_Map_Marker_Class *clas, Elm_Map_Group_Class *clas_group, void *data)
+{
+   int i, j;
+   Eina_List *l;
+   Marker_Group *group;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   int mpi, mpj;
+   int tabi[9];
+   int tabj[9];
+   const char *s;
+   const char *style;
+   Evas_Object *o;
+
+   if (!wd) return NULL;
+   if (!clas_group || !clas) return NULL;
+
+   Elm_Map_Marker *marker = ELM_NEW(Elm_Map_Marker);
+
+   marker->wd = wd;
+   marker->clas = clas;
+   marker->clas_group = clas_group;
+   marker->longitude = lon;
+   marker->latitude = lat;
+   marker->data = data;
+
+   tabi[1] = tabi[4] = tabi[6] = -1;
+   tabi[2] = tabi[0] = tabi[7] = 0;
+   tabi[3] = tabi[5] = tabi[8] = 1;
+
+   tabj[1] = tabj[2] = tabj[3] = -1;
+   tabj[4] = tabj[0] = tabj[5] = 0;
+   tabj[6] = tabj[7] = tabj[8] = 1;
+
+   if (!clas_group->priv.set)
+     {
+       style = "radio";
+       if (marker->clas_group && marker->clas_group->style)
+         style = marker->clas_group->style;
+
+       o = edje_object_add(evas_object_evas_get(obj));
+       _elm_theme_object_set(obj, o, "map/marker", style, elm_widget_style_get(obj));
+       s = edje_object_data_get(o, "size_w");
+       clas_group->priv.edje_w = atoi(s);
+       s = edje_object_data_get(o, "size_h");
+       clas_group->priv.edje_h = atoi(s);
+       s = edje_object_data_get(o, "size_max_w");
+       clas_group->priv.edje_max_w = atoi(s);
+       s = edje_object_data_get(o, "size_max_h");
+       clas_group->priv.edje_max_h = atoi(s);
+       evas_object_del(o);
+
+       clas_group->priv.set = EINA_TRUE;
+     }
+
+   if (!clas->priv.set)
+     {
+       style = "radio";
+       if (marker->clas && marker->clas->style)
+         style = marker->clas->style;
+        
+       o = edje_object_add(evas_object_evas_get(obj));
+       _elm_theme_object_set(obj, o, "map/marker", style, elm_widget_style_get(obj));
+       s = edje_object_data_get(o, "size_w");
+       clas->priv.edje_w = atoi(s);
+       s = edje_object_data_get(o, "size_h");
+       clas->priv.edje_h = atoi(s);
+       evas_object_del(o);
+
+       clas->priv.set = EINA_TRUE;
+     }
+
+   for (i = clas_group->zoom_displayed; i <= ZOOM_MAX; i++)
+     {
+       elm_map_utils_convert_geo_into_coord(lon, lat, pow(2.0, i)*wd->tsize,
+                                             &(marker->x[i]), &(marker->y[i]));
+        
+       //search in the matrixsparse the region where the marker will be
+       mpi = marker->x[i] / wd->tsize;
+       mpj = marker->y[i] / wd->tsize;
+
+       if (!wd->markers[i])
+         {
+            int size =  pow(2.0, i);
+            wd->markers[i] = eina_matrixsparse_new(size, size, NULL, NULL);
+         }
+
+       group = NULL;
+       if (i <= clas_group->zoom_grouped)
+         {
+            for (j = 0, group = NULL; j < 9 && !group; j++)
+              {
+                 EINA_LIST_FOREACH(eina_matrixsparse_data_idx_get(wd->markers[i], mpj + tabj[j], mpi + tabi[j]),
+                                    l, group)
+                   {
+                      if (group->clas == marker->clas_group
+                           && ELM_RECTS_INTERSECT(marker->x[i]-clas->priv.edje_w/4,
+                                                  marker->y[i]-clas->priv.edje_h/4, clas->priv.edje_w, clas->priv.edje_h,
+                                                  group->x-group->w/4, group->y-group->h/4, group->w, group->h))
+                        {
+                           group->markers = eina_list_append(group->markers, marker);
+                           group->update_nbelems = EINA_TRUE;
+                           group->update_resize = EINA_TRUE;
+
+                           group->sum_x += marker->x[i];
+                           group->sum_y += marker->y[i];
+                           group->x = group->sum_x / eina_list_count(group->markers);
+                           group->y = group->sum_y / eina_list_count(group->markers);
+
+                           group->w = group->clas->priv.edje_w + group->clas->priv.edje_w/8.
+                              * eina_list_count(group->markers);
+                           group->h = group->clas->priv.edje_h + group->clas->priv.edje_h/8.
+                              * eina_list_count(group->markers);
+                           if (group->w > group->clas->priv.edje_max_w) group->w = group->clas->priv.edje_max_w;
+                           if (group->h > group->clas->priv.edje_max_h) group->h = group->clas->priv.edje_max_h;
+
+                           if (group->obj && eina_list_count(group->markers) == 2)
+                             {
+                                _group_object_free(group);
+                                _group_object_create(group);
+                             }
+                           if (group->bubble)
+                             _group_bubble_content_update(group);
+                            
+                           break;
+                        }
+                   }
+              }
+         }
+       if (!group)
+         {
+            group = calloc(1, sizeof(Marker_Group));
+            group->wd = wd;
+            group->sum_x = marker->x[i];
+            group->sum_y = marker->y[i];
+            group->x = marker->x[i];
+            group->y = marker->y[i];
+            group->w = clas_group->priv.edje_w;
+            group->h = clas_group->priv.edje_h;
+            group->clas = clas_group;
+
+            group->markers = eina_list_append(group->markers, marker);
+            group->update_nbelems = EINA_TRUE;
+            group->update_resize = EINA_TRUE;
+
+            eina_matrixsparse_cell_idx_get(wd->markers[i], mpj, mpi, &(group->cell));
+
+            if (!group->cell)
+              {
+                 l = eina_list_append(NULL, group);
+                 eina_matrixsparse_data_idx_set(wd->markers[i], mpj, mpi, l);
+                 eina_matrixsparse_cell_idx_get(wd->markers[i], mpj, mpi, &(group->cell));
+              }
+            else
+              {
+                 l = eina_matrixsparse_cell_data_get(group->cell);
+                 l = eina_list_append(l, group);
+                 eina_matrixsparse_cell_data_set(group->cell, l);
+              }
+         }
+       marker->groups[i] = group;
+     }
+
+   if (wd->grids)
+     {
+       Evas_Coord ox, oy, ow, oh;
+       evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
+       marker_place(obj, eina_list_data_get(wd->grids), wd->pan_x, wd->pan_y, ox, oy, ow, oh);
+     }
+
+   return marker;
+}
+
+/**
+ * Remove a marker from the map
+ *
+ * @param marker The marker to remove
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_marker_remove(Elm_Map_Marker *marker)
+{
+   int i;
+   Eina_List *groups;
+   Widget_Data *wd = marker->wd;
+
+   if (!marker) return;
+   for (i = 0; i <= ZOOM_MAX; i++)
+     {
+       marker->groups[i]->markers = eina_list_remove(marker->groups[i]->markers, marker);
+       if (eina_list_count(marker->groups[i]->markers) == 0)
+         {
+             groups = eina_matrixsparse_cell_data_get(marker->groups[i]->cell);
+             groups = eina_list_remove(groups, marker->groups[i]);
+             eina_matrixsparse_cell_data_set(marker->groups[i]->cell, groups);
+             
+             _group_object_free(marker->groups[i]);
+             _group_bubble_free(marker->groups[i]);
+             free(marker->groups[i]);
+         }
+       else
+         {
+            marker->groups[i]->sum_x -= marker->x[i];
+            marker->groups[i]->sum_y -= marker->y[i];
+             
+            marker->groups[i]->x = marker->groups[i]->sum_x / eina_list_count(marker->groups[i]->markers);
+            marker->groups[i]->y = marker->groups[i]->sum_y / eina_list_count(marker->groups[i]->markers);
+             
+            marker->groups[i]->w = marker->groups[i]->clas->priv.edje_w
+               + marker->groups[i]->clas->priv.edje_w/8. * eina_list_count(marker->groups[i]->markers);
+            marker->groups[i]->h = marker->groups[i]->clas->priv.edje_h
+               + marker->groups[i]->clas->priv.edje_h/8. * eina_list_count(marker->groups[i]->markers);
+            if (marker->groups[i]->w > marker->groups[i]->clas->priv.edje_max_w)
+              marker->groups[i]->w = marker->groups[i]->clas->priv.edje_max_w;
+            if (marker->groups[i]->h > marker->groups[i]->clas->priv.edje_max_h)
+              marker->groups[i]->h = marker->groups[i]->clas->priv.edje_max_h;
+         }
+       if (marker->groups[i]->obj && eina_list_count(marker->groups[i]->markers) == 1)
+         {
+            _group_object_free(marker->groups[i]);
+            _group_object_create(marker->groups[i]);
+         }
+     }
+
+   if (marker->content && marker->clas->func.del)
+     marker->clas->func.del(marker->wd->obj, marker, marker->data, marker->content);
+   else if (marker->content)
+     evas_object_del(marker->content);
+   
+   free(marker);
+   
+   if (wd->grids)
+     {
+       Evas_Coord ox, oy, ow, oh;
+       evas_object_geometry_get(wd->obj, &ox, &oy, &ow, &oh);
+       marker_place(wd->obj, eina_list_data_get(wd->grids), wd->pan_x, wd->pan_y, ox, oy, ow, oh);
+     }
+}
+
+/**
+ * Move the map to the coordinate of the marker.
+ *
+ * @param marker The marker where the map will be center.
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_marker_bring_in(Elm_Map_Marker *marker)
+{
+   if (!marker) return;
+   elm_map_geo_region_bring_in(marker->wd->obj, marker->longitude, marker->latitude);
+}
+
+
+/**
+ * Move the map to the coordinate of the marker.
+ *
+ * @param marker The marker where the map will be center.
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_marker_show(Elm_Map_Marker *marker)
+{
+   if (!marker) return;
+   elm_map_geo_region_show(marker->wd->obj, marker->longitude, marker->latitude);
+}
+
+/**
+ * Move and zoom the map to display a list of markers.
+ *
+ * The map will be centered on the center point of the markers in the list. Then
+ * the map will be zoomed in order to fit the markers using the maximum zoom which
+ * allows display of all the markers.
+ *
+ * @param markers The list of markers (list of Elm_Map_Marker *)
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_markers_list_show(Eina_List *markers)
+{
+   int zoom;
+   double lon, lat;
+   Eina_List *l;
+   Elm_Map_Marker *marker, *m_max_lon = NULL, *m_max_lat = NULL, *m_min_lon = NULL, *m_min_lat = NULL;
+   Evas_Coord rw, rh, xc, yc;
+   Widget_Data *wd;
+
+   if (!markers) return;
+
+   EINA_LIST_FOREACH(markers, l, marker)
+     {
+       wd = marker->wd;
+
+       if (!m_min_lon || marker->longitude < m_min_lon->longitude)
+         m_min_lon = marker;
+        
+       if (!m_max_lon || marker->longitude > m_max_lon->longitude)
+         m_max_lon = marker;
+        
+       if (!m_min_lat || marker->latitude > m_min_lat->latitude)
+         m_min_lat = marker;
+        
+       if (!m_max_lat || marker->latitude < m_max_lat->latitude)
+         m_max_lat = marker;
+     }
+   
+   lon = (m_max_lon->longitude - m_min_lon->longitude) / 2. + m_min_lon->longitude;
+   lat = (m_max_lat->latitude - m_min_lat->latitude) / 2. + m_min_lat->latitude;
+   
+   elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
+   for (zoom = map_sources_tab[wd->source].zoom_max; zoom>map_sources_tab[wd->source].zoom_min; zoom--)
+     {
+       Evas_Coord size = pow(2.0, zoom)*wd->tsize;
+       elm_map_utils_convert_geo_into_coord(lon, lat, size, &xc, &yc);
+        
+       if (m_min_lon->x[zoom] - wd->marker_max_w >= xc-rw/2
+            && m_min_lat->y[zoom] - wd->marker_max_h >= yc-rh/2
+            && m_max_lon->x[zoom] + wd->marker_max_w <= xc+rw/2
+            && m_max_lat->y[zoom] + wd->marker_max_h <= yc+rh/2)
+         break;
+     }
+
+   elm_map_geo_region_show(wd->obj, lon, lat);
+   elm_map_zoom_set(wd->obj, zoom);
+}
+
+/**
+ * Set the maximum numbers of markers display in a group.
+ *
+ * A group can have a long list of markers, consequently the creation of the content
+ * of the bubble can be very slow. In order to avoid this, a maximum number of items
+ * is displayed in a bubble. By default this number is 30.
+ *
+ * @param obj The map object.
+ * @param max The maximum numbers of items displayed in a bubble.
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_max_marker_per_group_set(Evas_Object *obj, int max)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->markers_max_num = max;
+}
+
+/**
+ * Return the evas object getting from the ElmMapMarkerGetFunc callback
+ *
+ * @param marker The marker.
+ * @return Return the evas object if it exists, else NULL.
+ *
+ * @ingroup Map
+ */
+EAPI Evas_Object *
+elm_map_marker_object_get(Elm_Map_Marker *marker)
+{
+   if (!marker) return NULL;
+   return marker->content;
+}
+
+/**
+ * Update the marker
+ *
+ * @param marker The marker.
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_marker_update(Elm_Map_Marker *marker)
+{
+   if (!marker) return;
+   if (marker->content)
+     {
+       if (marker->clas->func.del)
+         marker->clas->func.del(marker->wd->obj, marker, marker->data, marker->content);
+       else
+         evas_object_del(marker->content);
+       marker->content = NULL;
+       _group_bubble_content_update(marker->groups[marker->wd->zoom]);
+     }
+}
+
+/**
+ * Close all opened bubbles
+ *
+ * @param obj The map object
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_bubbles_close(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Marker_Group *group;
+   Eina_List *l, *l_next;
+   if (!wd) return;
+   EINA_LIST_FOREACH_SAFE(wd->opened_bubbles, l, l_next, group)
+     _group_bubble_free(group);
+}
+
+
+/**
+ * Create a group class.
+ *
+ * Each marker must be associated to a group class. Marker with the same group are grouped if they are close.
+ * The group class defines the style of the marker when a marker is grouped to others markers.
+ *
+ * @param obj The map object
+ * @return Returns the new group class
+ *
+ * @ingroup Map
+ */
+EAPI Elm_Map_Group_Class *
+elm_map_group_class_new(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   Elm_Map_Group_Class *clas = calloc(1, sizeof(Elm_Map_Group_Class));
+   clas->zoom_grouped = ZOOM_MAX;
+   wd->groups_clas = eina_list_append(wd->groups_clas, clas);
+   return clas;
+}
+
+/**
+ * Set the style of a group class (radio, radio2 or empty)
+ *
+ * @param clas the group class
+ * @param style the new style
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_group_class_style_set(Elm_Map_Group_Class *clas, const char *style)
+{
+   if (!clas) return;
+   eina_stringshare_replace(&clas->style, style);
+}
+
+/**
+ * Set the icon callback of a group class.
+ *
+ * A custom icon can be displayed in a marker. The function @ref icon_get must return this icon.
+ *
+ * @param clas the group class
+ * @param icon_get the callback to create the icon
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_group_class_icon_cb_set(Elm_Map_Group_Class *clas, ElmMapGroupIconGetFunc icon_get)
+{
+   if (!clas) return;
+   clas->func.icon_get = icon_get;
+}
+
+/**
+ * Set the data associated to the group class (radio, radio2 or empty)
+ *
+ * @param clas the group class
+ * @param data the new user data
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_group_class_data_set(Elm_Map_Group_Class *clas, void *data)
+{
+   if (!clas) return;
+   clas->data = data;
+}
+
+/**
+ * Set the zoom from where the markers are displayed.
+ *
+ * Markers will not be displayed for a zoom less than @ref zoom
+ *
+ * @param clas the group class
+ * @param zoom the zoom
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_group_class_zoom_displayed_set(Elm_Map_Group_Class *clas, int zoom)
+{
+   if (!clas) return;
+   clas->zoom_displayed = zoom;
+}
+
+/**
+ * Set the zoom from where the markers are no more grouped.
+ *
+ * @param clas the group class
+ * @param zoom the zoom
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_group_class_zoom_grouped_set(Elm_Map_Group_Class *clas, int zoom)
+{
+   if (!clas) return;
+   clas->zoom_grouped = zoom;
+}
+
+/**
+ * Set if the markers associated to the group class @clas are hidden or not.
+ * If @ref hide is true the markers will be hidden.
+ *
+ * @param clas the group class
+ * @param hide if true the markers will be hidden, else they will be displayed.
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_group_class_hide_set(Evas_Object *obj, Elm_Map_Group_Class *clas, Eina_Bool hide)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (!clas) return;
+   if (clas->hide == hide) return;
+   clas->hide = hide;
+   if (wd->grids)
+     {
+       Evas_Coord ox, oy, ow, oh;
+       evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
+       marker_place(obj, eina_list_data_get(wd->grids), wd->pan_x, wd->pan_y, ox, oy, ow, oh);
+     }
+}
+
+
+/**
+ * Create a marker class.
+ *
+ * Each marker must be associated to a class.
+ * The class defines the style of the marker when a marker is displayed alone (not grouped).
+ *
+ * @param obj The map object
+ * @return Returns the new class
+ *
+ * @ingroup Map
+ */
+EAPI Elm_Map_Marker_Class *
+elm_map_marker_class_new(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   Elm_Map_Marker_Class *clas = calloc(1, sizeof(Elm_Map_Marker_Class));
+   wd->markers_clas = eina_list_append(wd->markers_clas, clas);
+   return clas;
+}
+
+/**
+ * Set the style of a class (radio, radio2 or empty)
+ *
+ * @param clas the group class
+ * @param style the new style
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_marker_class_style_set(Elm_Map_Marker_Class *clas, const char *style)
+{
+   if (!clas) return;
+   eina_stringshare_replace(&clas->style, style);
+}
+
+/**
+ * Set the icon callback of a class.
+ *
+ * A custom icon can be displayed in a marker. The function @ref icon_get must return this icon.
+ *
+ * @param clas the group class
+ * @param icon_get the callback to create the icon
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_marker_class_icon_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerIconGetFunc icon_get)
+{
+   if (!clas) return;
+   clas->func.icon_get = icon_get;
+}
+
+/**
+ *
+ * Set the callback of the content of the bubble.
+ *
+ * When the user click on a marker, a bubble is displayed with a content.
+ * The callback @ref get musst return this content. It can be NULL.
+ *
+ * @param clas the group class
+ * @param get the callback to create the content
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_marker_class_get_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerGetFunc get)
+{
+   if (!clas) return;
+   clas->func.get = get;
+}
+
+/**
+ * Set the callback of the content of delete the object created by the callback "get".
+ *
+ * If this callback is defined the user will have to delete (or not) the object inside.
+ * If the callback is not defined the object will be destroyed with evas_object_del()
+ *
+ * @param clas the group class
+ * @param del the callback to delete the content
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_marker_class_del_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerDelFunc del)
+{
+   if (!clas) return;
+   clas->func.del = del;
+}
+
+/**
+ * Set the source of the map.
+ *
+ * Elm_Map retrieves the image which composed the map from a web service. This web service can
+ * be set with this method. A different service can return a different maps with different
+ * information and it can use different zoom value.
+ *
+ * @param clas the group class
+ * @param source the new source
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_source_set(Evas_Object *obj, Elm_Map_Sources source)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Grid *grid;
+   int zoom;
+   if (!wd) return;
+   if (wd->source == source ) return;
+   if (!map_sources_tab[source].url_cb) return;
+
+   EINA_LIST_FREE(wd->grids, grid) grid_clear(obj, grid);
+
+   wd->source = source;
+   zoom = wd->zoom;
+   wd->zoom = -1;
+   
+   if (map_sources_tab[wd->source].zoom_max < zoom)
+     zoom = map_sources_tab[wd->source].zoom_max;
+   if (map_sources_tab[wd->source].zoom_min > zoom)
+     zoom = map_sources_tab[wd->source].zoom_min;
+   
+   elm_map_zoom_set(obj, zoom);
+}
+
+/**
+ * Get the current source
+ *
+ * @param obj the map object
+ * @return Returns the maximum zoom of the source
+ *
+ * @ingroup Map
+ */
+EAPI Elm_Map_Sources
+elm_map_source_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) ELM_MAP_SOURCE_MAPNIK;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return ELM_MAP_SOURCE_MAPNIK;
+   return wd->source;
+}
+
+/**
+ * Set the API of a custom source.
+ *
+ * A custom web service can be associated to the source ELM_MAP_SOURCE_CUSTOM_(1..7).
+ *
+ * @param source the source ID (ELM_MAP_SOURCE_CUSTOM_(1..7))
+ * @param name the name of the source
+ * @param zoom_min the minimum zoom of the source, must be >= 0
+ * @param zoom_max the maximum zoom of the source, must be <= ZOOM_MAX
+ * @param url_cb the callback used to create the url from where a tile (png or jpeg file) is downloaded.
+ *
+ * @ingroup Map
+ */
+EAPI void
+elm_map_source_custom_api_set(Elm_Map_Sources source, const char *name, int zoom_min, int zoom_max, ElmMapSourceURLFunc url_cb)
+{
+   if (!name || !url_cb) return;
+   map_sources_tab[source].name = name;
+   map_sources_tab[source].zoom_min = zoom_min;
+   map_sources_tab[source].zoom_max = zoom_max;
+   map_sources_tab[source].url_cb = url_cb;
+}
+
+/**
+ * Get the maximum zoom of the source.
+ *
+ * @param source the source
+ * @return Returns the maximum zoom of the source
+ *
+ * @ingroup Map
+ */
+EAPI int
+elm_map_source_zoom_max_get(Elm_Map_Sources source)
+{
+   return map_sources_tab[source].zoom_max;
+}
+
+/**
+ * Get the minimum zoom of the source.
+ *
+ * @param source the source
+ * @return Returns the minimum zoom of the source
+ *
+ * @ingroup Map
+ */
+EAPI int
+elm_map_source_zoom_min_get(Elm_Map_Sources source)
+{
+   return map_sources_tab[source].zoom_min;
+}
+
+/**
+ * Get the name of a source.
+ *
+ * @param source the source
+ * @return Returns the name of the source
+ *
+ * @ingroup Map
+ */
+EAPI const char *
+elm_map_source_name_get(Elm_Map_Sources source)
+{
+   return map_sources_tab[source].name;
+}
+
+
+static char *
+_mapnik_url_cb(int x, int y, int zoom)
+{
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf), "http://tile.openstreetmap.org/%d/%d/%d.png",
+            zoom, x, y);
+   return strdup(buf);
+}
+
+static char *
+_osmarender_url_cb(int x, int y, int zoom)
+{
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf), "http://tah.openstreetmap.org/Tiles/tile/%d/%d/%d.png",
+            zoom, x, y);
+   return strdup(buf);
+}
+
+static char *
+_cyclemap_url_cb(int x, int y, int zoom)
+{
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf), "http://andy.sandbox.cloudmade.com/tiles/cycle/%d/%d/%d.png",
+            zoom, x, y);
+   return strdup(buf);
+}
+
+static char *
+_maplint_url_cb(int x, int y, int zoom)
+{
+   char buf[PATH_MAX];
+   snprintf(buf, sizeof(buf), "http://tah.openstreetmap.org/Tiles/maplint/%d/%d/%d.png",
+            zoom, x, y);
+   return strdup(buf);
+}
+
diff --git a/src/lib/elm_mapbuf.c b/src/lib/elm_mapbuf.c
new file mode 100644 (file)
index 0000000..023c4ae
--- /dev/null
@@ -0,0 +1,314 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Mapbuf Mapbuf
+ *
+ * This holds 1 content object and uses an Evas Map to move/resize etc. it.
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *content;
+   Eina_Bool enabled : 1;
+   Eina_Bool alpha : 1;
+   Eina_Bool smooth : 1;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1;
+   Evas_Coord maxw = -1, maxh = -1;
+   if (!wd) return;
+   if (wd->content)
+     {
+        evas_object_size_hint_min_get(wd->content, &minw, &minh);
+        evas_object_size_hint_max_get(wd->content, &maxw, &maxh);
+     }
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *sub = event_info;
+   if (!wd) return;
+   if (sub == wd->content)
+     {
+       evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                            _changed_size_hints, obj);
+       wd->content = NULL;
+       _sizing_eval(obj);
+     }
+}
+
+static void
+_mapbuf(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord x, y, w, h;
+   if (!wd) return;
+   evas_object_geometry_get(obj, &x, &y, &w, &h);
+   if (wd->enabled)
+     {
+        Evas_Map *m;
+
+        m = evas_map_new(4);
+        evas_map_util_points_populate_from_geometry(m, x, y, w, h, 0);
+        evas_map_smooth_set(m, wd->smooth);
+        evas_map_alpha_set(m, wd->alpha);
+        evas_object_map_set(wd->content, m);
+        evas_object_map_enable_set(wd->content, wd->enabled);
+        evas_map_free(m);
+     }
+   else
+     {
+        evas_object_map_set(wd->content, NULL);
+        evas_object_map_enable_set(wd->content, 0);
+        evas_object_move(wd->content, x, y);
+        evas_object_resize(wd->content, w, h);
+     }
+}
+
+static void
+_configure(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->content)
+     {
+        Evas_Coord x, y, w, h;
+        
+        evas_object_geometry_get(obj, &x, &y, &w, &h);
+        if (!wd->enabled) evas_object_move(wd->content, x, y);
+        evas_object_resize(wd->content, w, h);
+        _mapbuf(obj);
+     }
+}
+
+static void
+_move(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   _configure(obj);
+}
+
+static void
+_resize(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{    
+   _configure(obj);
+}
+
+/**
+ * Add a new mapbuf to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Mapbuf
+ */
+EAPI Evas_Object *
+elm_mapbuf_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "mapbuf");
+   elm_widget_type_set(obj, "mapbuf");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, NULL);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, NULL);
+
+   wd->enabled = 0;
+   wd->alpha = 1;
+   wd->smooth = 1;
+   
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Set the mapbuf front content
+ *
+ * @param obj The mapbuf object
+ * @param content The content will be filled in this mapbuf object
+ *
+ * @ingroup Mapbuf
+ */
+EAPI void
+elm_mapbuf_content_set(Evas_Object *obj, Evas_Object *content)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->content == content) return;
+   if ((wd->content != content) && (wd->content))
+     {
+        elm_widget_sub_object_del(obj, wd->content);
+        evas_object_smart_member_del(wd->content);
+     }
+   wd->content = content;
+   if (content)
+     {
+       elm_widget_sub_object_add(content, obj);
+        evas_object_smart_member_add(content, obj);
+       evas_object_event_callback_add(content,
+                                       EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                      _changed_size_hints, obj);
+       _sizing_eval(obj);
+     }
+   _configure(obj);
+}
+
+/**
+ * Set the mapbuf enabled state
+ *
+ * @param obj The mapbuf object
+ * @param enabled The value to set the enabled state to
+ *
+ * @ingroup Mapbuf
+ */
+EAPI void
+elm_mapbuf_enabled_set(Evas_Object *obj, Eina_Bool enabled)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->enabled == enabled) return;
+   wd->enabled = enabled;
+   _configure(obj);
+}
+
+/**
+ * Get the mapbuf enabled state
+ *
+ * @param obj The mapbuf object
+ * @return The value that the enabled state is set to
+ *
+ * @ingroup Mapbuf
+ */
+EAPI Eina_Bool
+elm_mapbuf_enabled_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->enabled;
+}
+
+/**
+ * Sets the mapbuf smooth state
+ *
+ * @param obj The mapbuf object
+ * @param smooth The value of the smooth state of @p obj
+ *
+ * @ingroup Mapbuf
+ */
+EAPI void
+elm_mapbuf_smooth_set(Evas_Object *obj, Eina_Bool smooth)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->smooth == smooth) return;
+   wd->smooth = smooth;
+   _configure(obj);
+}
+
+/**
+ * Gets the mapbuf smooth state
+ *
+ * @param obj The mapbuf object
+ * @return The value of the smooth state of @p obj
+ *
+ * @ingroup Mapbuf
+ */
+EAPI Eina_Bool
+elm_mapbuf_smooth_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->smooth;
+}
+
+/**
+ * Enables/disables the mapbuf alpha channel
+ *
+ * @param obj The mapbuf object
+ * @param alpha The state of the alpha channel
+ *
+ * @ingroup Mapbuf
+ */
+EAPI void
+elm_mapbuf_alpha_set(Evas_Object *obj, Eina_Bool alpha)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->alpha == alpha) return;
+   wd->alpha = alpha;
+   _configure(obj);
+}
+
+/**
+ * Gets the state of the mapbuf alpha channel
+ *
+ * @param obj The mapbuf object
+ * @return The state of the alpha channel
+ *
+ * @ingroup Mapbuf
+ */
+EAPI Eina_Bool
+elm_mapbuf_alpha_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->alpha;
+}
diff --git a/src/lib/elm_menu.c b/src/lib/elm_menu.c
new file mode 100644 (file)
index 0000000..4556e96
--- /dev/null
@@ -0,0 +1,824 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Menu Menu
+ *
+ * A menu is a list of items displayed above the window. Each item can
+ * have a sub-menu. The menu object can be used to display a menu on right
+ * click, in a toolbar, anywhere.
+ *
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Menu_Item
+{
+   Evas_Object *menu;
+   Evas_Object *o;
+   Elm_Menu_Item *parent;
+
+   Eina_Bool separator;
+   Eina_Bool disabled;
+
+   //if classic item or submenu
+   Evas_Object *icon;
+   const char *label;
+
+   Evas_Smart_Cb func;
+   Evas_Smart_Cb del_cb;
+   const void *data;
+
+   //if submenu
+   Eina_Bool open;
+   Evas_Object *hv, *bx, *location;
+   Eina_List *items;
+};
+
+struct _Widget_Data
+{
+   Evas_Object *hv, *bx, *location, *parent;
+   Eina_List *items;
+   Evas_Coord xloc, yloc;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _submenu_sizing_eval(Elm_Menu_Item *parent);
+static void _item_sizing_eval(Elm_Menu_Item *item);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _submenu_hide(Elm_Menu_Item *item);
+static void _submenu_open(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _parent_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _menu_hide(void *data, Evas_Object *obj, void *event_info);
+
+static void
+_del_pre_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_RESIZE, _parent_resize, obj);
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Eina_List *l, *ll = NULL;
+   Elm_Menu_Item *item;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   ll = eina_list_append(ll, wd->items);
+   EINA_LIST_FOREACH(ll, ll, l)
+     {
+       EINA_LIST_FREE(l, item)
+         {
+            ll = eina_list_append(ll, item->items);
+            if (item->del_cb) item->del_cb((void*)item->data, item->o, item);
+            if (item->label) eina_stringshare_del(item->label);
+            if (item->icon) evas_object_del(item->icon);
+            if (item->hv) evas_object_del(item->hv);
+            if (item->location) evas_object_del(item->location);
+            free(item);
+         }
+     }
+   if (wd->hv) evas_object_del(wd->hv);
+   if (wd->location) evas_object_del(wd->location);
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Eina_List *l, *_l, *ll = NULL;
+   Elm_Menu_Item *item;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   ll = eina_list_append(ll, wd->items);
+   EINA_LIST_FOREACH(ll, ll, l)
+     {
+       EINA_LIST_FOREACH(l, _l, item)
+         {
+            ll = eina_list_append(ll, item->items);
+            if (item->separator)
+              _elm_theme_object_set(obj, item->o, "menu", "separator",
+                                     elm_widget_style_get(obj));
+            else if (item->bx)
+              {
+                 _elm_theme_object_set(obj, item->o, "menu", "item_with_submenu",
+                                        elm_widget_style_get(obj));
+                 elm_menu_item_label_set(item, item->label);
+                 elm_menu_item_icon_set(item, item->icon);
+              }
+            else
+              {
+                 _elm_theme_object_set(obj, item->o, "menu", "item",
+                                        elm_widget_style_get(obj));
+                 elm_menu_item_label_set(item, item->label);
+                 elm_menu_item_icon_set(item, item->icon);
+              }
+            if (item->disabled)
+              edje_object_signal_emit(item->o, "elm,state,disabled", "elm");
+            else
+              edje_object_signal_emit(item->o, "elm,state,enabled", "elm");
+            edje_object_message_signal_process(item->o);
+            edje_object_scale_set(item->o, elm_widget_scale_get(obj) *
+                                   _elm_config->scale);
+         }
+     }
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Eina_List *l;
+   Elm_Menu_Item *item;
+   Evas_Coord x_p, y_p, w_p, h_p, x2, y2, w2, h2, bx, by, bw, bh;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if ((!wd) || (!wd->parent)) return;
+   EINA_LIST_FOREACH(wd->items,l,item) _item_sizing_eval(item);
+   evas_object_geometry_get(wd->location, &x_p, &y_p, &w_p, &h_p);
+   evas_object_geometry_get(wd->parent, &x2, &y2, &w2, &h2);
+   evas_object_geometry_get(wd->bx, &bx, &by, &bw, &bh);
+
+   x_p = wd->xloc;
+   y_p = wd->yloc;
+
+   if (x_p+bw > x2+w2) x_p -= x_p+bw - (x2+w2);
+   if (x_p < x2) x_p += x2 - x_p;
+
+   if (y_p+h_p+bh > y2+h2) y_p -= y_p+h_p+bh - (y2+h2);
+   if (y_p < y2) y_p += y2 - y_p;
+
+   evas_object_move(wd->location, x_p, y_p);
+   evas_object_resize(wd->location, bw, h_p);
+   evas_object_size_hint_min_set(wd->location, bw, h_p);
+   evas_object_size_hint_max_set(wd->location, bw, h_p);
+   elm_hover_target_set(wd->hv, wd->location);
+
+   EINA_LIST_FOREACH(wd->items,l,item)
+     {
+       if (item->open) _submenu_sizing_eval(item);
+     }
+}
+
+static void
+_submenu_sizing_eval(Elm_Menu_Item *parent)
+{
+   Eina_List *l;
+   Elm_Menu_Item *item;
+   Evas_Coord x_p, y_p, w_p, h_p, x2, y2, w2, h2, bx, by, bw, bh, px, py, pw, ph;
+   Widget_Data *wd = elm_widget_data_get(parent->menu);
+   if (!wd) return;
+   EINA_LIST_FOREACH(parent->items,l,item) _item_sizing_eval(item);
+   evas_object_geometry_get(parent->location, &x_p, &y_p, &w_p, &h_p);
+   evas_object_geometry_get(parent->o, &x2, &y2, &w2, &h2);
+   evas_object_geometry_get(parent->bx, &bx, &by, &bw, &bh);
+   evas_object_geometry_get(wd->parent, &px, &py, &pw, &ph);
+
+   x_p = x2+w2;
+   y_p = y2;
+
+   if (x_p + bw > px + pw)
+     x_p = x2-bw;
+
+   if (y_p+bh > py+ph)
+     y_p -= y_p+bh - (py+ph);
+   if (y_p < py)
+     y_p += y_p - y_p;
+
+   evas_object_move(parent->location, x_p, y_p);
+   evas_object_resize(parent->location, bw, h_p);
+   evas_object_size_hint_min_set(parent->location, bw, h_p);
+   evas_object_size_hint_max_set(parent->location, bw, h_p);
+   elm_hover_target_set(parent->hv, parent->location);
+
+   EINA_LIST_FOREACH(parent->items,l,item)
+     {
+       if (item->open)
+         _submenu_sizing_eval(item);
+     }
+}
+
+static void
+_item_sizing_eval(Elm_Menu_Item *item)
+{
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   if (!item->separator)
+     elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   edje_object_size_min_restricted_calc(item->o, &minw, &minh, minw, minh);
+   if (!item->separator)
+     elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   evas_object_size_hint_min_set(item->o, minw, minh);
+   evas_object_size_hint_max_set(item->o, maxw, maxh);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+}
+
+static void
+_menu_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+}
+
+static void
+_parent_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+}
+
+static void
+_item_move_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Elm_Menu_Item *item = data;
+   if (item->open) _submenu_sizing_eval(item);
+}
+
+static void
+_hover_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   _menu_hide(data, obj, event_info);
+   evas_object_smart_callback_call(data, "clicked", NULL);
+}
+
+static void
+_menu_hide(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Eina_List *l;
+   Elm_Menu_Item *item2;
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   evas_object_hide(wd->hv);
+   evas_object_hide(data);
+
+   EINA_LIST_FOREACH(wd->items, l, item2)
+     {
+       if (item2->open) _submenu_hide(item2);
+     }
+}
+
+static void
+_submenu_hide(Elm_Menu_Item *item)
+{
+   Eina_List *l;
+   Elm_Menu_Item *item2;
+   evas_object_hide(item->hv);
+   item->open = EINA_FALSE;
+   EINA_LIST_FOREACH(item->items, l, item2)
+     {
+       if (item2->open) _submenu_hide(item2);
+     }
+}
+
+static void
+_menu_item_select(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Elm_Menu_Item *it = data;
+   if (it->items)
+     {
+       if (!it->open) _submenu_open(it, NULL, NULL, NULL);
+       else _submenu_hide(it);
+     }
+   else
+     _menu_hide(it->menu, NULL, NULL);
+
+   if (it->func) it->func((void *)(it->data), it->menu, it);
+}
+
+static void
+_menu_item_activate(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Eina_List *l;
+   Elm_Menu_Item *item2;
+   Elm_Menu_Item *item = data;
+   if (item->parent)
+     {
+       EINA_LIST_FOREACH(item->parent->items, l, item2)
+         {
+            if ((item2->open) && (item2 != item)) _submenu_hide(item2);
+         }
+     }
+   else
+     {
+       Widget_Data *wd = elm_widget_data_get(item->menu);
+       EINA_LIST_FOREACH(wd->items, l, item2)
+         {
+            if ((item2->open) && (item2 != item)) _submenu_hide(item2);
+         }
+     }
+}
+
+static void
+_submenu_open(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Elm_Menu_Item *it = data;
+   it->open = EINA_TRUE;
+   evas_object_show(it->hv);
+   _sizing_eval(it->menu);
+}
+
+static void
+_show(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   evas_object_show(wd->hv);
+}
+
+static void
+_item_obj_create(Elm_Menu_Item *item)
+{
+   Widget_Data *wd = elm_widget_data_get(item->menu);
+   if (!wd) return;
+   item->o = edje_object_add(evas_object_evas_get(wd->bx));
+   evas_object_size_hint_weight_set(item->o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_fill_set(item->o, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   _elm_theme_object_set(item->menu, item->o, "menu", "item",  elm_widget_style_get(item->menu));
+   edje_object_signal_callback_add(item->o, "elm,action,click", "",
+                                   _menu_item_select, item);
+   edje_object_signal_callback_add(item->o, "elm,action,activate", "",
+                                   _menu_item_activate, item);
+   evas_object_show(item->o);
+}
+
+static void
+_item_separator_obj_create(Elm_Menu_Item *item)
+{
+   Widget_Data *wd = elm_widget_data_get(item->menu);
+   if (!wd) return;
+   item->o = edje_object_add(evas_object_evas_get(wd->bx));
+   evas_object_size_hint_weight_set(item->o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_fill_set(item->o, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   _elm_theme_object_set(item->menu, item->o, "menu", "separator",  elm_widget_style_get(item->menu));
+   edje_object_signal_callback_add(item->o, "elm,action,activate", "",
+                                   _menu_item_activate, item);
+   evas_object_show(item->o);
+}
+
+static void
+_item_submenu_obj_create(Elm_Menu_Item *item)
+{
+   Widget_Data *wd = elm_widget_data_get(item->menu);
+   if (!wd) return;
+   item->location = elm_icon_add(wd->bx);
+   item->hv = elm_hover_add(wd->bx);
+   elm_hover_target_set(item->hv, item->location);
+   elm_hover_parent_set(item->hv, wd->parent);
+   elm_object_style_set(item->hv, "submenu");
+
+   item->bx = elm_box_add(wd->bx);
+   evas_object_size_hint_weight_set(item->bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(item->bx);
+   elm_hover_content_set(item->hv, elm_hover_best_content_location_get(item->hv, ELM_HOVER_AXIS_VERTICAL), item->bx);
+
+   _elm_theme_object_set(item->menu, item->o, "menu", "item_with_submenu",  elm_widget_style_get(item->menu));
+   elm_menu_item_label_set(item, item->label);
+   elm_menu_item_icon_set(item, item->icon);
+
+   edje_object_signal_callback_add(item->o, "elm,action,open", "",
+                                   _submenu_open, item);
+   evas_object_event_callback_add(item->o, EVAS_CALLBACK_MOVE, _item_move_resize, item);
+   evas_object_event_callback_add(item->o, EVAS_CALLBACK_RESIZE, _item_move_resize, item);
+
+   evas_object_event_callback_add(item->bx, EVAS_CALLBACK_RESIZE, _menu_resize, item->menu);
+}
+
+/**
+ * Add a new menu to the parent
+ *
+ * @param parent The parent object.
+ * @return The new object or NULL if it cannot be created.
+ *
+ * @ingroup Menu
+ */
+EAPI Evas_Object *
+elm_menu_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "menu");
+   elm_widget_type_set(obj, "menu");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_pre_hook_set(obj, _del_pre_hook);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   wd->location = elm_icon_add(obj);
+   wd->parent = parent;
+
+   wd->hv = elm_hover_add(obj);
+   elm_hover_parent_set(wd->hv, parent);
+   elm_hover_target_set(wd->hv, wd->location);
+   elm_object_style_set(wd->hv, "menu");
+   evas_object_smart_callback_add(wd->hv, "clicked", _hover_clicked_cb, obj);
+
+   wd->bx = elm_box_add(obj);
+   evas_object_size_hint_weight_set(wd->bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(wd->bx);
+   elm_hover_content_set(wd->hv, elm_hover_best_content_location_get(wd->hv, ELM_HOVER_AXIS_VERTICAL), wd->bx);
+
+   evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_RESIZE, _parent_resize, obj);
+
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _show, obj);
+
+   evas_object_event_callback_add(wd->bx, EVAS_CALLBACK_RESIZE, _menu_resize, obj);
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Set the parent
+ *
+ * @param obj The menu object.
+ * @param parent The new parent.
+ * 
+ * @ingroup Menu
+ */
+EAPI void
+elm_menu_parent_set(Evas_Object *obj, Evas_Object *parent)
+{
+   Eina_List *l, *_l, *ll = NULL;
+   Elm_Menu_Item *item;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_hover_parent_set(wd->hv, parent);
+   wd->parent = parent;
+
+   ll = eina_list_append(ll, wd->items);
+   EINA_LIST_FOREACH(ll, ll, l)
+     {
+       EINA_LIST_FOREACH(l, _l, item)
+         {
+            if (item->hv)
+              {
+                 elm_hover_parent_set(item->hv, parent);
+                 ll = eina_list_append(ll, item->items);
+              }
+         }
+     }
+   _sizing_eval(obj);
+}
+
+/**
+ * Move the menu to a new position
+ *
+ * @param obj The menu object.
+ * @param x The new position.
+ * @param y The new position.
+ * 
+ * @ingroup Menu
+ */
+EAPI void
+elm_menu_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->xloc = x;
+   wd->yloc = y;
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the Evas_Object of an Elm_Menu_Item
+ * 
+ * @param it The menu item object.
+ * 
+ * @ingroup Menu
+ */
+EAPI Evas_Object *
+elm_menu_object_get(const Elm_Menu_Item *it)
+{
+   return it->o;
+}
+
+/**
+ * Add an item at the end
+ *
+ * @param obj The menu object.
+ * @param icon A icon display on the item. The icon will be destryed by the menu.
+ * @param label The label of the item.
+ * @param func Function called when the user select the item.
+ * @param data Data sent by the callback.
+ * @return Returns the new item.
+ * 
+ * @ingroup Menu
+ */
+EAPI Elm_Menu_Item *
+elm_menu_item_add(Evas_Object *obj, Elm_Menu_Item *parent, Evas_Object *icon, const char *label, Evas_Smart_Cb func, const void *data)
+{
+   Elm_Menu_Item *subitem;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return NULL;
+   subitem = ELM_NEW(Elm_Menu_Item);
+   if (!subitem) return NULL;
+   subitem->func = func;
+   subitem->data = data;
+   subitem->menu = obj;
+   subitem->parent = parent;
+
+   _item_obj_create(subitem);
+   elm_menu_item_label_set(subitem, label);
+   elm_menu_item_icon_set(subitem, icon);
+
+   if (parent)
+     {
+       if (!parent->bx) _item_submenu_obj_create(parent);
+       elm_box_pack_end(parent->bx, subitem->o);
+       parent->items = eina_list_append(parent->items, subitem);
+     }
+   else
+     {
+       elm_box_pack_end(wd->bx, subitem->o);
+       wd->items = eina_list_append(wd->items, subitem);
+     }
+
+   _sizing_eval(obj);
+   return subitem;
+}
+
+/**
+ * Set the label of a menu item
+ *
+ * @param it The menu item object.
+ * @param label The label to set for @p item
+ *
+ * @ingroup Menu
+ */
+EAPI void
+elm_menu_item_label_set(Elm_Menu_Item *item, const char *label)
+{
+   eina_stringshare_replace(&item->label, label);
+
+   if (label)
+     edje_object_signal_emit(item->o, "elm,state,text,visible", "elm");
+   else
+     edje_object_signal_emit(item->o, "elm,state,text,hidden", "elm");
+
+   edje_object_message_signal_process(item->o);
+   edje_object_part_text_set(item->o, "elm.text", label);
+   _sizing_eval(item->menu);
+}
+
+/**
+ * Get the label of a menu item
+ *
+ * @param it The menu item object.
+ * @return The label of @p item
+ *
+ * @ingroup Menu
+ */
+EAPI const char *
+elm_menu_item_label_get(Elm_Menu_Item *item)
+{
+   if (!item) return NULL;
+   return item->label;
+}
+
+/**
+ * Set the icon of a menu item
+ *
+ * @param it The menu item object.
+ * @param icon The icon object to set for @p item
+ *
+ * @ingroup Menu
+ */
+EAPI void
+elm_menu_item_icon_set(Elm_Menu_Item *item, Evas_Object *icon)
+{
+   if ((item->icon != icon) && (item->icon))
+     elm_widget_sub_object_del(item->menu, item->icon);
+   if ((icon) && (item->icon != icon))
+     {
+       item->icon = icon;
+       elm_widget_sub_object_add(item->menu, icon);
+       evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                       _changed_size_hints, item->menu);
+       edje_object_part_swallow(item->o, "elm.swallow.content", icon);
+       edje_object_signal_emit(item->o, "elm,state,icon,visible", "elm");
+       edje_object_message_signal_process(item->o);
+       _sizing_eval(item->menu);
+     }
+   else
+     item->icon = icon;
+}
+
+
+/**
+ * Set the disabled state of @p item.
+ *
+ * @param it The menu item object.
+ * @param disabled The enabled/disabled state of the item
+ *
+ * @ingroup Menu
+ */
+EAPI void
+elm_menu_item_disabled_set(Elm_Menu_Item *item, Eina_Bool disabled)
+{
+   if (disabled == item->disabled) return;
+   item->disabled = disabled;
+   if (disabled)
+     {
+        edje_object_signal_emit(item->o, "elm,state,disabled", "elm");
+        if (item->open) _submenu_hide(item);
+     }
+   else
+     edje_object_signal_emit(item->o, "elm,state,enabled", "elm");
+   edje_object_message_signal_process(item->o);
+}
+
+/**
+ * Get the disabled state of @p item.
+ * 
+ * @param it The menu item object.
+ * @return The enabled/disabled state of the item
+ * 
+ * @ingroup Menu
+ */
+EAPI Eina_Bool
+elm_menu_item_disabled_get(Elm_Menu_Item *item)
+{
+   if (!item) return 0;
+   return item->disabled;
+}
+
+/**
+ * Add a separator item to menu @p obj under @p parent.
+ *
+ * @param obj The menu object
+ * @param parent The item to add the separator under
+ *
+ * @return The created item or NULL on failure
+ *
+ * @ingroup Menu
+ */
+EAPI Elm_Menu_Item *
+elm_menu_item_separator_add(Evas_Object *obj, Elm_Menu_Item *parent)
+{
+   Elm_Menu_Item *subitem;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   subitem = ELM_NEW(Elm_Menu_Item);
+   if (!subitem) return NULL;
+   subitem->menu = obj;
+   subitem->separator = 1;
+   _item_separator_obj_create(subitem);
+   if (!parent)
+     {
+       elm_box_pack_end(wd->bx, subitem->o);
+       wd->items = eina_list_append(wd->items, subitem);
+     }
+   else
+     {
+       if (!parent->bx) _item_submenu_obj_create(parent);
+       elm_box_pack_end(parent->bx, subitem->o);
+       parent->items = eina_list_append(parent->items, subitem);
+     }
+   _sizing_eval(obj);
+   return subitem;
+}
+
+
+/**
+ * Deletes an item from the menu.
+ *
+ * @param item The item to delete
+ *
+ * @ingroup Menu
+ */
+
+/**
+ * Get the icon of a menu item
+ * 
+ * @param it The menu item object.
+ * @return The icon object of @p item or NULL
+ * 
+ * @ingroup Menu
+ */
+EAPI Evas_Object *
+elm_menu_item_icon_get(Elm_Menu_Item *item)
+{
+   if (!item) return NULL;
+   return item->icon;
+}
+
+/**
+ * Returns whether @p item is a separator.
+ *
+ * @param item The item to check
+ * @return If true, @p item is a separator
+ *
+ * @ingroup Menu
+ */
+EAPI Eina_Bool
+elm_menu_item_is_separator(Elm_Menu_Item *item)
+{
+   if (!item) return 0;
+   return item->separator;
+}
+
+EAPI void
+elm_menu_item_del(Elm_Menu_Item *item)
+{
+   Elm_Menu_Item *_item;
+
+   if (!item) return;
+   if (item->del_cb) item->del_cb((void*)item->data, item->o, item);
+
+   EINA_LIST_FREE(item->items, _item) elm_menu_item_del(_item);
+   if (item->label) eina_stringshare_del(item->label);
+   if (item->icon) evas_object_del(item->icon);
+   if (item->hv) evas_object_del(item->hv);
+   if (item->location) evas_object_del(item->location);
+   if (item->o) evas_object_del(item->o);
+
+   if (item->parent)
+     item->parent->items = eina_list_remove(item->parent->items, item);
+   else
+     {
+       Widget_Data *wd = elm_widget_data_get(item->menu);
+       wd->items = eina_list_remove(wd->items, item);
+     }
+
+   free(item);
+}
+
+/**
+ * Set the function called when a menu item is freed.
+ *
+ * @param it The item to set the callback on
+ * @param func The function called
+ *
+ * @ingroup Menu
+ */
+EAPI void
+elm_menu_item_del_cb_set(Elm_Menu_Item *it, Evas_Smart_Cb func)
+{
+   if (!it) return;
+   it->del_cb = func;
+}
+
+/**
+ * Returns the data associated with menu item @p it.
+ *
+ * @param it The item
+ * @return The data associated with @p it
+ *
+ * @ingroup Menu
+ */
+EAPI void *
+elm_menu_item_data_get(const Elm_Menu_Item *it)
+{
+   if (!it) return NULL;
+   return (void *)it->data;
+}
+
+/**
+ * Sets the data to be associated with menu item @p it.
+ *
+ * @param item The item
+ * @param data The data to be associated with @p item
+ *
+ * @ingroup Menu
+ */
+EAPI void
+elm_menu_item_data_set(Elm_Menu_Item *item, const void *data)
+{
+   if (!item) return;
+   item->data = data;
+}
+
+/**
+ * Returns a list of @p item's subitems.
+ *
+ * @param it The item
+ * @return An Eina_List* of @p item's subitems
+ *
+ * @ingroup Menu
+ */
+EAPI const Eina_List *
+elm_menu_item_subitems_get(Elm_Menu_Item *item)
+{
+   if (!item) return NULL;
+   return item->items;
+}
diff --git a/src/lib/elm_module.c b/src/lib/elm_module.c
new file mode 100644 (file)
index 0000000..0659044
--- /dev/null
@@ -0,0 +1,220 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/* what are moodules in elementary for? for modularising behavior and features
+ * so they can be plugged in and out where you dont want the core source to
+ * alwyas behave like that or do it that way. plug it at runtime!
+ * 
+ * they have module names (in config) and "slots" to plug that module into
+ * to server a purpose. eg you plug plugin "xx" into the "entry-copy-paste"
+ * slot so it would provide replacement copy & paste ui functionality and
+ * specific symbols
+ * 
+ * config is something like:
+ * 
+ * export ELM_MODULES="xx>slot1:yy>slot2"
+ * 
+ * where a module named xx is plugged into slot1 & yy is plugged into slot2
+ * 
+ * real examples:
+ * 
+ * export ELM_MODULES="my_module>entry/api"
+ * 
+ * this loads the module called "my_module" into the slot "entry/api" which
+ * is an api slot for entry modules to modify behavior and hook to
+ * creation/deletion of the entry as well as replace the longpress behavior.
+ */
+
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <dlfcn.h>      /* dlopen,dlclose,etc */
+
+static Eina_Hash *modules = NULL;
+static Eina_Hash *modules_as = NULL;
+
+void
+_elm_module_init(void)
+{
+   modules = eina_hash_string_small_new(NULL);
+   modules_as = eina_hash_string_small_new(NULL);
+}
+
+void
+_elm_module_shutdown(void)
+{
+   // FIXME: unload all modules
+   eina_hash_free(modules);
+   modules = NULL;
+   eina_hash_free(modules_as);
+   modules_as = NULL;
+}
+
+void
+_elm_module_parse(const char *s)
+{
+   const char *p, *pe;
+   
+   p = s;
+   pe = p;
+   for (;;)
+     {
+        if ((*pe == ':') || (*pe == 0))
+          { // p -> pe == 'name:'
+             if (pe > p)
+               {
+                  char *n = malloc(pe - p + 1);
+                  if (n)
+                    {
+                       char *nn;
+                       
+                       strncpy(n, p, pe - p);
+                       n[pe - p] = 0;
+                       nn = strchr(n, '>');
+                       if (nn)
+                         {
+                            *nn = 0;
+                            nn++;
+                            _elm_module_add(n, nn);
+                         }
+                       free(n);
+                    }
+               }
+             if (*pe == 0) break;
+             p = pe + 1;
+             pe = p;
+          }
+        else
+          pe++;
+     }
+}
+
+Elm_Module *
+_elm_module_find_as(const char *as)
+{
+   Elm_Module *m;
+   
+   m = eina_hash_find(modules_as, as);
+   return m;
+}
+
+Elm_Module *
+_elm_module_add(const char *name, const char *as)
+{
+   Elm_Module *m;
+   char buf[PATH_MAX];
+
+   m = eina_hash_find(modules, name);
+   if (m)
+     {
+        m->references++;
+        return m;
+     }
+   m = calloc(1, sizeof(Elm_Module));
+   if (!m) return NULL;
+   m->version = 1;
+   if (name[0] != '/')
+     {
+        const char *home = getenv("HOME");
+        
+        if (home)
+          {
+             snprintf(buf, sizeof(buf), "%s/.elementary/modules/%s/%s/module" EFL_SHARED_EXTENSION, home, name, MODULE_ARCH);
+             m->handle = dlopen(buf, RTLD_NOW | RTLD_GLOBAL);
+             if (m->handle)
+               {
+                  m->init_func = dlsym(m->handle, "elm_modapi_init");
+                  if (m->init_func)
+                    {
+                       m->shutdown_func = dlsym(m->handle, "elm_modapi_shutdown");
+                       m->so_path = eina_stringshare_add(buf);
+                       m->name = eina_stringshare_add(name);
+                       snprintf(buf, sizeof(buf), "%s/.elementary/modules/%s/%s", home, name, MODULE_ARCH);
+                       m->bin_dir = eina_stringshare_add(buf);
+                       snprintf(buf, sizeof(buf), "%s/.elementary/modules/%s", home, name);
+                       m->data_dir = eina_stringshare_add(buf);
+                    }
+                  else
+                    {
+                       dlclose(m->handle);
+                       free(m);
+                       return NULL;
+                    }
+               }
+          }
+        if (!m->handle)
+          {
+             snprintf(buf, sizeof(buf), "%s/elementary/modules/%s/%s/module" EFL_SHARED_EXTENSION, _elm_lib_dir, name, MODULE_ARCH);
+             m->handle = dlopen(buf, RTLD_NOW | RTLD_GLOBAL);
+             if (m->handle)
+               {
+                  m->init_func = dlsym(m->handle, "elm_modapi_init");
+                  if (m->init_func)
+                    {
+                       m->shutdown_func = dlsym(m->handle, "elm_modapi_shutdown");
+                       m->so_path = eina_stringshare_add(buf);
+                       m->name = eina_stringshare_add(name);
+                       snprintf(buf, sizeof(buf), "%s/elementary/modules/%s/%s", _elm_lib_dir, name, MODULE_ARCH);
+                       m->bin_dir = eina_stringshare_add(buf);
+                       snprintf(buf, sizeof(buf), "%s/elementary/modules/%s", _elm_lib_dir, name);
+                       m->data_dir = eina_stringshare_add(buf);
+                    }
+                  else
+                    {
+                       dlclose(m->handle);
+                       free(m);
+                       return NULL;
+                    }
+               }
+          }
+     }
+   if (!m->handle)
+     {
+        free(m);
+        return NULL;
+     }
+   if (!m->init_func(m))
+     {
+        dlclose(m->handle);
+        eina_stringshare_del(m->name);
+        eina_stringshare_del(m->so_path);
+        eina_stringshare_del(m->data_dir);
+        eina_stringshare_del(m->bin_dir);
+        free(m);
+        return NULL;
+     }
+   m->references = 1;
+   eina_hash_direct_add(modules, m->name, m);
+   m->as = eina_stringshare_add(as);
+   eina_hash_direct_add(modules_as, m->as, m);
+   return m;
+}
+
+void
+_elm_module_del(Elm_Module *m)
+{
+   m->references--;
+   if (m->references > 0) return;
+   if (m->shutdown_func) m->shutdown_func(m);
+   eina_hash_del(modules, m->name, m);
+   eina_hash_del(modules_as, m->as, m);
+   if (m->api) free(m->api);
+   eina_stringshare_del(m->name);
+   eina_stringshare_del(m->as);
+   eina_stringshare_del(m->so_path);
+   eina_stringshare_del(m->data_dir);
+   eina_stringshare_del(m->bin_dir);
+   dlclose(m->handle);
+   free(m);
+}
+
+const void *
+_elm_module_symbol_get(Elm_Module *m, const char *name)
+{
+   return dlsym(m->handle, name);
+}
diff --git a/src/lib/elm_notify.c b/src/lib/elm_notify.c
new file mode 100644 (file)
index 0000000..1232a90
--- /dev/null
@@ -0,0 +1,479 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include <Elementary.h>
+#include "elm_priv.h"
+
+
+/**
+ * @defgroup Notify notify
+ *
+ * Display a window in a particular region of the application (top, bottom ...).
+ * A timeout can be set to automatically close the window.
+ *
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *notify, *content, *parent;
+
+   Elm_Notify_Orient orient;
+   Eina_Bool repeat_events;
+   Evas_Object *block_events;
+
+   int timeout;
+   Ecore_Timer *timer;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+static void _signal_block_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _calc(Evas_Object *obj);
+static void _content_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _show(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _hide(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+static void
+_del_pre_hook(Evas_Object *obj)
+{
+   evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
+   evas_object_event_callback_del_full(obj, EVAS_CALLBACK_MOVE, _resize, obj);
+   evas_object_event_callback_del_full(obj, EVAS_CALLBACK_SHOW, _show, obj);
+   evas_object_event_callback_del_full(obj, EVAS_CALLBACK_HIDE, _hide, obj);
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_notify_content_set(obj, NULL);
+   elm_notify_parent_set(obj, NULL);
+   elm_notify_repeat_events_set(obj, EINA_TRUE);
+   if (wd->timer)
+     {
+       ecore_timer_del(wd->timer);
+       wd->timer = NULL;
+     }
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _elm_theme_object_set(obj, wd->notify, "notify", "base", "default");
+   if (wd->block_events)
+     _elm_theme_object_set(obj, wd->block_events, "notify", "block_events", "default");
+   edje_object_scale_set(wd->notify, elm_widget_scale_get(obj) *
+                         _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord x,y,w,h;
+   if (!wd) return;
+   if (!wd->parent) return;
+   evas_object_geometry_get(wd->parent, &x, &y, &w, &h);
+   evas_object_move(obj, x, y);
+   evas_object_resize(obj, w, h);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (event_info == wd->content) wd->content = NULL;
+}
+
+static void
+_signal_block_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   evas_object_smart_callback_call(data, "block,clicked", NULL);
+}
+
+static void
+_resize(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   _calc(obj);
+}
+
+static void
+_content_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _calc(data);
+}
+
+static void
+_calc(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1;
+   Evas_Coord x, y, w, h;
+   if (!wd) return;
+   evas_object_geometry_get(obj, &x, &y, &w, &h);
+   edje_object_size_min_calc(wd->notify, &minw, &minh);
+
+   if (wd->content)
+     {
+       int offx = (w - minw) / 2;
+       int offy = (h - minh) / 2;
+
+       switch (wd->orient)
+         {
+          case ELM_NOTIFY_ORIENT_TOP:
+             evas_object_move(wd->notify, x + offx, y);
+             break;
+          case ELM_NOTIFY_ORIENT_CENTER:
+             evas_object_move(wd->notify, x + offx, y + offy);
+             break;
+          case ELM_NOTIFY_ORIENT_BOTTOM:
+             evas_object_move(wd->notify, x + offx, y + h - minh);
+             break;
+          case ELM_NOTIFY_ORIENT_LEFT:
+             evas_object_move(wd->notify, x, y + offy);
+             break;
+          case ELM_NOTIFY_ORIENT_RIGHT:
+             evas_object_move(wd->notify, x + w - minw, y + offy);
+             break;
+          case ELM_NOTIFY_ORIENT_TOP_LEFT:
+             evas_object_move(wd->notify, x, y);
+             break;
+          case ELM_NOTIFY_ORIENT_TOP_RIGHT:
+             evas_object_move(wd->notify, x + w - minw, y);
+             break;
+          case ELM_NOTIFY_ORIENT_BOTTOM_LEFT:
+             evas_object_move(wd->notify, x, y + h - minh);
+             break;
+          case ELM_NOTIFY_ORIENT_BOTTOM_RIGHT:
+             evas_object_move(wd->notify, x + w - minw, y + h - minh);
+             break;
+         }
+        evas_object_resize(wd->notify, minw, minh);
+     }
+    _sizing_eval(obj);
+}
+
+static int
+_timer_cb(void *data)
+{
+   Evas_Object *obj = data;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   wd->timer = NULL;
+   evas_object_hide(obj);
+   return 0;
+}
+
+static void
+_show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   evas_object_show(wd->notify);
+   if (!wd->repeat_events)
+     evas_object_show(wd->block_events);
+   if (wd->timer)
+     {
+       ecore_timer_del(wd->timer);
+       wd->timer = NULL;
+     }
+   if (wd->timeout > 0)
+     wd->timer = ecore_timer_add(wd->timeout, _timer_cb, obj);
+}
+
+static void
+_hide(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   evas_object_hide(wd->notify);
+   if (!wd->repeat_events)
+     evas_object_hide(wd->block_events);
+   if (wd->timer)
+     {
+       ecore_timer_del(wd->timer);
+       wd->timer = NULL;
+     }
+}
+
+static void
+_parent_del(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->parent = NULL;
+   evas_object_hide(obj);
+}
+
+static void
+_parent_hide(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->parent = NULL;
+   evas_object_hide(obj);
+}
+
+/**
+ * Add a new notify to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Notify
+ */
+EAPI Evas_Object *
+elm_notify_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "notify");
+   elm_widget_type_set(obj, "notify");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_pre_hook_set(obj, _del_pre_hook);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   wd->repeat_events = EINA_TRUE;
+
+   wd->notify = edje_object_add(e);
+   elm_notify_orient_set(obj, ELM_NOTIFY_ORIENT_TOP);
+
+   elm_notify_parent_set(obj, parent);
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _resize, obj);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _show, obj);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _hide, obj);
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Set the notify content
+ *
+ * @param obj The notify object
+ * @param content The content will be filled in this notify object
+ *
+ * @ingroup Notify
+ */
+EAPI void
+elm_notify_content_set(Evas_Object *obj, Evas_Object *content)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->content)
+     {
+       evas_object_event_callback_del_full(wd->content,
+                                            EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                            _changed_size_hints, obj);
+        evas_object_event_callback_del_full(wd->content, EVAS_CALLBACK_RESIZE,
+                                            _content_resize, obj);
+       evas_object_del(wd->content);
+       wd->content = NULL;
+     }
+   
+   if (content)
+     {
+       elm_widget_sub_object_add(obj, content);
+       wd->content = content;
+       evas_object_event_callback_add(content,
+                                       EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                       _changed_size_hints, obj);
+       evas_object_event_callback_add(content, EVAS_CALLBACK_RESIZE,
+                                       _content_resize, obj);
+       edje_object_part_swallow(wd->notify, "elm.swallow.content", content);
+        
+       _sizing_eval(obj);
+     }
+   _calc(obj);
+}
+
+/**
+ * Set the notify parent
+ *
+ * @param obj The notify object
+ * @param content The new parent
+ *
+ * @ingroup Notify
+ */
+EAPI void
+elm_notify_parent_set(Evas_Object *obj, Evas_Object *parent)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->parent)
+     {
+       evas_object_event_callback_del_full(wd->parent,
+                                            EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                            _changed_size_hints, obj);
+       evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_RESIZE,
+                                            _changed_size_hints, obj);
+       evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_MOVE,
+                                            _changed_size_hints, obj);
+       evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_DEL,
+                                            _parent_del, obj);
+       evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_HIDE,
+                                            _parent_hide, obj);
+       wd->parent = NULL;
+     }
+   
+   if (parent)
+     {
+       wd->parent = parent;
+       evas_object_event_callback_add(parent,
+                                       EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                       _changed_size_hints, obj);
+       evas_object_event_callback_add(parent, EVAS_CALLBACK_RESIZE,
+                                       _changed_size_hints, obj);
+       evas_object_event_callback_add(parent, EVAS_CALLBACK_MOVE,
+                                       _changed_size_hints, obj);
+       evas_object_event_callback_add(parent, EVAS_CALLBACK_DEL,
+                                      _parent_del, obj);
+       evas_object_event_callback_add(parent, EVAS_CALLBACK_HIDE,
+                                       _parent_hide, obj);
+       edje_object_part_swallow(wd->notify, "elm.swallow.parent", parent);
+       _sizing_eval(obj);
+     }
+   _calc(obj);
+}
+
+/**
+ * Set the orientation
+ *
+ * @param obj The notify object
+ * @param orient The new orientation
+ */
+EAPI void
+elm_notify_orient_set(Evas_Object *obj, Elm_Notify_Orient orient)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->orient = orient;
+   switch (orient)
+     {
+     case ELM_NOTIFY_ORIENT_TOP:
+        _elm_theme_object_set(obj, wd->notify, "notify", "base", "default");
+        break;
+     case ELM_NOTIFY_ORIENT_CENTER:
+        _elm_theme_object_set(obj, wd->notify, "notify", "base", "center");
+        break;
+     case ELM_NOTIFY_ORIENT_BOTTOM:
+        _elm_theme_object_set(obj, wd->notify, "notify", "base", "bottom");
+        break;
+     case ELM_NOTIFY_ORIENT_LEFT:
+        _elm_theme_object_set(obj, wd->notify, "notify", "base", "left");
+        break;
+     case ELM_NOTIFY_ORIENT_RIGHT:
+        _elm_theme_object_set(obj, wd->notify, "notify", "base", "right");
+        break;
+     case ELM_NOTIFY_ORIENT_TOP_LEFT:
+        _elm_theme_object_set(obj, wd->notify, "notify", "base", "top_left");
+        break;
+     case ELM_NOTIFY_ORIENT_TOP_RIGHT:
+        _elm_theme_object_set(obj, wd->notify, "notify", "base", "top_right");
+        break;
+     case ELM_NOTIFY_ORIENT_BOTTOM_LEFT:
+        _elm_theme_object_set(obj, wd->notify, "notify", "base", "bottom_left");
+        break;
+     case ELM_NOTIFY_ORIENT_BOTTOM_RIGHT:
+        _elm_theme_object_set(obj, wd->notify, "notify", "base", "bottom_right");
+        break;
+     }
+   _resize(obj, NULL, obj, NULL);
+}
+
+/**
+ * Set the time before the notify window is hidden. <br>
+ * Set a value < 0 to disable the timer
+ *
+ * @param obj The notify object
+ * @param time the new timeout
+ */
+EAPI void
+elm_notify_timeout_set(Evas_Object *obj, int timeout)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->timeout = timeout;
+   elm_notify_timer_init(obj);
+}
+
+/**
+ * Re-init the timer
+ * @param obj The notify object
+ */
+EAPI void
+elm_notify_timer_init(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->timer) ecore_timer_del(wd->timer);
+   wd->timer = NULL;
+   if (wd->timeout > 0)
+     wd->timer = ecore_timer_add(wd->timeout, _timer_cb, obj);
+}
+
+/**
+ * When true if the user clicks outside the window the events will be
+ * catch by the others widgets, else the events are block and the signal
+ * dismiss will be sent when the user click outside the window.
+ *
+ * @note The default value is EINA_TRUE.
+ *
+ * @param obj The notify object
+ * @param repeats EINA_TRUE Events are repeats, else no
+ */
+EAPI void
+elm_notify_repeat_events_set(Evas_Object *obj, Eina_Bool repeat)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (repeat == wd->repeat_events) return;
+   wd->repeat_events = repeat;
+   if (!repeat)
+     {
+       wd->block_events = edje_object_add(evas_object_evas_get(obj));
+       _elm_theme_object_set(obj, wd->block_events, "notify", "block_events", "default");
+        elm_widget_resize_object_set(obj, wd->block_events);
+       edje_object_signal_callback_add(wd->block_events, "elm,action,clicked", "elm", _signal_block_clicked, obj);
+     }
+   else
+     evas_object_del(wd->block_events);
+}
+
diff --git a/src/lib/elm_pager.c b/src/lib/elm_pager.c
new file mode 100644 (file)
index 0000000..b1c0299
--- /dev/null
@@ -0,0 +1,404 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Pager Pager
+ *
+ * The pager is an object that allows flipping (with animation) between 1 or
+ * more “pages” of objects, much like a stack of windows within the window.
+ *
+ * Objects can be pushed or popped from he stack or deleted as normal.
+ * Pushes and pops will animate (and a pop will delete the object once the
+ * animation is finished). Any object in the pager can be promoted to the top
+ * (from its current stacking position) as well. Objects are pushed to the
+ * top with elm_pager_content_push() and when the top item is no longer
+ * wanted, simply pop it with elm_pager_content_pop() and it will also be
+ * deleted. Any object you wish to promote to the top that is already in the
+ * pager, simply use elm_pager_content_promote(). If an object is no longer
+ * needed and is not the top item, just delete it as normal. You can query
+ * which objects are the top and bottom with elm_pager_content_bottom_get()
+ * and elm_pager_content_top_get().
+ */
+
+typedef struct _Widget_Data Widget_Data;
+typedef struct _Item Item;
+
+struct _Widget_Data
+{
+   Eina_List *stack;
+   Item *top, *oldtop;
+   Evas_Object *rect, *clip;
+};
+
+struct _Item
+{
+   Evas_Object *obj, *base, *content;
+   Evas_Coord minw, minh;
+   Eina_Bool popme : 1;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Eina_List *l;
+   Item *it;
+   if (!wd) return;
+   EINA_LIST_FOREACH(wd->stack, l, it)
+     edje_object_scale_set(it->base, elm_widget_scale_get(obj) * 
+                           _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1;
+   Eina_List *l;
+   Item *it;
+   if (!wd) return;
+   EINA_LIST_FOREACH(wd->stack, l, it)
+     {
+       if (it->minw > minw) minw = it->minw;
+       if (it->minh > minh) minh = it->minh;
+     }
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Item *it = data;
+   Evas_Coord minw = -1, minh = -1;
+   evas_object_size_hint_min_get(it->content, &minw, &minh);
+   // FIXME: why is this needed? how does edje get this unswallowed or
+   // lose its callbacks to edje
+   edje_object_part_swallow(it->base, "elm.swallow.content", it->content);
+   edje_object_size_min_calc(it->base, &it->minw, &it->minh);
+   _sizing_eval(it->obj);
+}
+
+static void
+_eval_top(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Item *ittop;
+   if (!wd) return;
+   if (!wd->stack) return;
+   ittop = eina_list_last(wd->stack)->data;
+   if (ittop != wd->top)
+     {
+       Evas_Object *o;
+       const char *onshow, *onhide;
+
+       if (wd->top)
+         {
+            o = wd->top->base;
+            edje_object_signal_emit(o, "elm,action,hide", "elm");
+            onhide = edje_object_data_get(o, "onhide");
+            if (onhide)
+              {
+                 if (!strcmp(onhide, "raise")) evas_object_raise(o);
+                 else if (!strcmp(onhide, "lower")) evas_object_lower(o);
+              }
+         }
+       wd->top = ittop;
+       o = wd->top->base;
+       evas_object_show(o);
+       edje_object_signal_emit(o, "elm,action,show", "elm");
+       onshow = edje_object_data_get(o, "onshow");
+       if (onshow)
+         {
+            if (!strcmp(onshow, "raise")) evas_object_raise(o);
+            else if (!strcmp(onshow, "lower")) evas_object_lower(o);
+         }
+     }
+}
+
+static void
+_move(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Coord x, y;
+   Eina_List *l;
+   Item *it;
+   if (!wd) return;
+   evas_object_geometry_get(obj, &x, &y, NULL, NULL);
+   EINA_LIST_FOREACH(wd->stack, l, it)
+     evas_object_move(it->base, x, y);
+}
+
+static void
+_sub_del(void *data, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Object *sub = event_info;
+   Eina_List *l;
+   Item *it;
+   if (!wd) return;
+   EINA_LIST_FOREACH(wd->stack, l, it)
+     {
+       if (it->content == sub)
+         {
+            wd->stack = eina_list_remove_list(wd->stack, l);
+            evas_object_event_callback_del_full
+               (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, it);
+            evas_object_del(it->base);
+            _eval_top(it->obj);
+            free(it);
+            return;
+         }
+     }
+}
+
+static void
+_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{   
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Coord w, h;
+   Eina_List *l;
+   Item *it;
+   if (!wd) return;
+   evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+   EINA_LIST_FOREACH(wd->stack, l, it) evas_object_resize(it->base, w, h);
+}
+
+static void
+_signal_hide_finished(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Item *it = data;
+   Evas_Object *obj2 = it->obj;
+   evas_object_hide(it->base);
+   edje_object_signal_emit(it->base, "elm,action,reset", "elm");
+   evas_object_smart_callback_call(obj2, "hide,finished", it->content);
+   edje_object_message_signal_process(it->base);
+   if (it->popme) evas_object_del(it->content);
+   _sizing_eval(obj2);
+}
+
+/**
+ * Add a new pager to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Pager
+ */
+EAPI Evas_Object *
+elm_pager_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "pager");
+   elm_widget_type_set(obj, "pager");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   wd->clip = evas_object_rectangle_add(e);
+   elm_widget_resize_object_set(obj, wd->clip);
+   elm_widget_sub_object_add(obj, wd->clip);
+
+   wd->rect = evas_object_rectangle_add(e);
+   elm_widget_sub_object_add(obj, wd->rect);
+   evas_object_color_set(wd->rect, 255, 255, 255, 0); 
+   evas_object_clip_set(wd->rect, wd->clip);
+
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Push an object to the top of the pager stack (and show it)
+ *
+ * The object pushed becomes a child of the pager and will be controlled
+ * it and deleted when the pager is deleted.
+ *
+ * @param obj The pager object
+ * @param content The object to push
+ *
+ * @ingroup Pager
+ */
+EAPI void
+elm_pager_content_push(Evas_Object *obj, Evas_Object *content)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Item *it = ELM_NEW(Item);
+   Evas_Coord x, y, w, h;
+   if (!wd) return;
+   if (!it) return;
+   it->obj = obj;
+   it->content = content;
+   it->base = edje_object_add(evas_object_evas_get(obj));
+   evas_object_smart_member_add(it->base, obj);
+   evas_object_geometry_get(obj, &x, &y, &w, &h);
+   evas_object_move(it->base, x, y);
+   evas_object_resize(it->base, w, h);
+   evas_object_clip_set(it->base, wd->clip);
+   elm_widget_sub_object_add(obj, it->base);
+   elm_widget_sub_object_add(obj, it->content);
+   _elm_theme_object_set(obj, it->base,  "pager", "base", elm_widget_style_get(obj));
+   edje_object_signal_callback_add(it->base, "elm,action,hide,finished", "", 
+                                   _signal_hide_finished, it);
+   evas_object_event_callback_add(it->content,
+                                  EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                 _changed_size_hints, it);
+   edje_object_part_swallow(it->base, "elm.swallow.content", it->content);
+   edje_object_size_min_calc(it->base, &it->minw, &it->minh);
+   evas_object_show(it->content);
+   wd->stack = eina_list_append(wd->stack, it);
+   _eval_top(obj);
+   _sizing_eval(obj);
+}
+
+/**
+ * Pop the object that is on top of the stack
+ *
+ * This pops the object that is on top (visible) in the pager, makes it
+ * disappear, then deletes the object. The object that was underneath it
+ * on the stack will become visible.
+ *
+ * @param obj The pager object
+ *
+ * @ingroup Pager
+ */
+EAPI void
+elm_pager_content_pop(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Eina_List *ll;
+   Item *it;
+   if (!wd) return;
+   if (!wd->stack) return;
+   it = eina_list_last(wd->stack)->data;
+   it->popme = EINA_TRUE;
+   ll = eina_list_last(wd->stack);
+   if (ll)
+     {
+       ll = ll->prev;
+       if (!ll)
+         {
+            Evas_Object *o;
+            const char *onhide;
+
+            wd->top = it;
+            o = wd->top->base;
+            edje_object_signal_emit(o, "elm,action,hide", "elm");
+            onhide = edje_object_data_get(o, "onhide");
+            if (onhide)
+              {
+                 if (!strcmp(onhide, "raise")) evas_object_raise(o);
+                 else if (!strcmp(onhide, "lower")) evas_object_lower(o);
+              }
+            wd->top = NULL;
+         }
+       else
+         {
+            it = ll->data;
+            elm_pager_content_promote(obj, it->content);
+         }
+     }
+}
+
+/**
+ * Promote an object already in the pager stack to the top of the stack
+ *
+ * This will take the indicated object and promote it to the top of the stack
+ * as if it had been pushed there. The object must already be inside the
+ * pager stack to work.
+ *
+ * @param obj The pager object
+ * @param content The object to promote
+ *
+ * @ingroup Pager
+ */
+EAPI void
+elm_pager_content_promote(Evas_Object *obj, Evas_Object *content)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Eina_List *l;
+   Item *it;
+   if (!wd) return;
+   EINA_LIST_FOREACH(wd->stack, l, it)
+     {
+       if (it->content == content)
+         {
+            wd->stack = eina_list_remove_list(wd->stack, l);
+            wd->stack = eina_list_append(wd->stack, it);
+            _eval_top(obj);
+            return;
+         }
+     }
+}
+
+/**
+ * Return the object at the bottom of the pager stack
+ *
+ * @param obj The pager object
+ * @return The bottom object or NULL if none
+ *
+ * @ingroup Pager
+ */
+EAPI Evas_Object *
+elm_pager_content_bottom_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Item *it;
+   if (!wd) return NULL;
+   if (!wd->stack) return NULL;
+   it = wd->stack->data;
+   return it->content;
+}
+
+/**
+ * Return the object at the top of the pager stack
+ *
+ * @param obj The pager object
+ * @return The top object or NULL if none
+ *
+ * @ingroup Pager
+ */
+EAPI Evas_Object *
+elm_pager_content_top_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Item *it;
+   if (!wd) return NULL;
+   if (!wd->stack) return NULL;
+   it = eina_list_last(wd->stack)->data;
+   return it->content;
+}
+
diff --git a/src/lib/elm_panel.c b/src/lib/elm_panel.c
new file mode 100644 (file)
index 0000000..2c57c4c
--- /dev/null
@@ -0,0 +1,305 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Panel Panel
+ *
+ * A panel is a type of animated container that contains subobjects.  It
+ * can be expanded or contracted.
+ *
+ * Orientations are as follows:
+ * ELM_PANEL_ORIENT_TOP
+ * ELM_PANEL_ORIENT_BOTTOM
+ * ELM_PANEL_ORIENT_LEFT
+ * ELM_PANEL_ORIENT_RIGHT
+ * NOTE: Only LEFT orientation is implemented.
+ *
+ * THIS WIDGET IS UNDER CONSTRUCTION!
+ */
+
+typedef struct _Widget_Data Widget_Data;
+struct _Widget_Data 
+{
+   Evas_Object *scr, *bx;
+   Elm_Panel_Orient orient;
+   Eina_Bool hidden : 1;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _resize(void *data, Evas *evas, Evas_Object *obj, void *event);
+static void _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data);
+static void _toggle_panel(void *data, Evas_Object *obj, const char *emission, const char *source);
+
+static void 
+_del_hook(Evas_Object *obj) 
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   free(wd);
+}
+
+static void 
+_theme_hook(Evas_Object *obj) 
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "panel", "base", elm_widget_style_get(obj));
+//   scale = (elm_widget_scale_get(obj) * _elm_config->scale);
+//   edje_object_scale_set(wd->scr, scale);
+   _sizing_eval(obj);
+}
+
+static void 
+_sizing_eval(Evas_Object *obj) 
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord mw = -1, mh = -1;
+   Evas_Coord vw = 0, vh = 0;
+   Evas_Coord w, h;
+   if (!wd) return;
+   evas_object_smart_calculate(wd->bx);
+   edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr), 
+                             &mw, &mh);
+   evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+   if (w < mw) w = mw;
+   if (h < mh) h = mh;
+   evas_object_resize(wd->scr, w, h);
+
+   evas_object_size_hint_min_get(wd->bx, &mw, &mh);
+   if (w > mw) mw = w;
+   if (h > mh) mh = h;
+   evas_object_resize(wd->bx, mw, mh);
+
+   elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
+   mw = mw + (w - vw);
+   mh = mh + (h - vh);
+   evas_object_size_hint_min_set(obj, mw, mh);
+   evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+static void 
+_resize(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Coord mw, mh, vw, vh, w, h;
+   if (!wd) return;
+   elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
+   evas_object_size_hint_min_get(wd->bx, &mw, &mh);
+   evas_object_geometry_get(wd->bx, NULL, NULL, &w, &h);
+   if ((vw >= mw) || (vh >= mh))
+     {
+        if ((w != vw) || (h != vh)) evas_object_resize(wd->bx, vw, vh);
+     }
+}
+
+static void 
+_layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) 
+{
+   Widget_Data *wd = data;
+   if (!wd) return;
+   _els_box_layout(o, priv, EINA_TRUE, EINA_FALSE);
+}
+
+static void 
+_toggle_panel(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) 
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (wd->hidden) 
+     {
+        edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr), 
+                                "elm,action,show", "elm");
+        wd->hidden = EINA_FALSE;
+     }
+   else
+     {
+        edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr), 
+                                "elm,action,hide", "elm");
+        wd->hidden = EINA_TRUE;
+     }
+}
+
+/**
+ * Adds a panel object
+ *
+ * @param parent The parent object
+ *
+ * @return The panel object, or NULL on failure
+ *
+ * @ingroup Panel
+ */
+EAPI Evas_Object *
+elm_panel_add(Evas_Object *parent) 
+{
+   Evas_Object *obj;
+   Evas *evas;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   evas = evas_object_evas_get(parent);
+   obj = elm_widget_add(evas);
+   ELM_SET_WIDTYPE(widtype, "panel");
+   elm_widget_type_set(obj, "panel");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_can_focus_set(obj, 0);
+
+   wd->scr = elm_smart_scroller_add(evas);
+   elm_smart_scroller_widget_set(wd->scr, obj);
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "panel", "base", "left");
+   elm_smart_scroller_bounce_allow_set(wd->scr, 0, 0);
+   elm_widget_resize_object_set(obj, wd->scr);
+   elm_smart_scroller_policy_set(wd->scr, ELM_SMART_SCROLLER_POLICY_OFF, 
+                                 ELM_SMART_SCROLLER_POLICY_OFF);
+
+   wd->hidden = EINA_FALSE;
+   wd->orient = ELM_PANEL_ORIENT_LEFT;
+
+   wd->bx = evas_object_box_add(evas);
+   evas_object_size_hint_align_set(wd->bx, 0.5, 0.5);
+   evas_object_box_layout_set(wd->bx, _layout, wd, NULL);
+   elm_widget_sub_object_add(obj, wd->bx);
+   elm_smart_scroller_child_set(wd->scr, wd->bx);
+   evas_object_show(wd->bx);
+
+   edje_object_signal_callback_add(elm_smart_scroller_edje_object_get(wd->scr), 
+                                   "elm,action,panel,toggle", "*", 
+                                   _toggle_panel, obj);
+
+   evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_RESIZE, _resize, obj);
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Sets the orientation of the panel
+ *
+ * @param parent The parent object
+ * @param orient The panel orientation.  Can be one of the following:
+ * ELM_PANEL_ORIENT_TOP
+ * ELM_PANEL_ORIENT_BOTTOM
+ * ELM_PANEL_ORIENT_LEFT
+ * ELM_PANEL_ORIENT_RIGHT
+ *
+ * NOTE: Currently all orientations but LEFT are unimplemented.
+ *
+ * @ingroup Panel
+ */
+EAPI void 
+elm_panel_orient_set(Evas_Object *obj, Elm_Panel_Orient orient) 
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->orient = orient;
+   switch (orient) 
+     {
+     case ELM_PANEL_ORIENT_TOP:
+     case ELM_PANEL_ORIENT_BOTTOM:
+        break;
+     case ELM_PANEL_ORIENT_LEFT:
+        elm_smart_scroller_object_theme_set(obj, wd->scr, "panel", "base", "left");
+     case ELM_PANEL_ORIENT_RIGHT:
+        break;
+     default:
+        break;
+     }
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the orientation of the panel.
+ *
+ * @param obj The panel object
+ * @return The Elm_Panel_Orient, or ELM_PANEL_ORIENT_LEFT on failure.
+ *
+ * @ingroup Panel
+ */
+EAPI Elm_Panel_Orient
+elm_panel_orient_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) ELM_PANEL_ORIENT_LEFT;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return ELM_PANEL_ORIENT_LEFT;
+   return wd->orient;   
+}
+
+/**
+ * Set the content of the panel.
+ *
+ * @param obj The panel object
+ * @param content The panel content
+ *
+ * @ingroup Panel
+ */
+EAPI void 
+elm_panel_content_set(Evas_Object *obj, Evas_Object *content) 
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   evas_object_box_remove_all(wd->bx, EINA_TRUE);
+   if (!content) return;
+   evas_object_box_append(wd->bx, content);
+   evas_object_show(content);
+   _sizing_eval(obj);
+}
+
+/**
+ * Set the state of the panel.
+ *
+ * @param obj The panel object
+ * @param hidden If true, the panel will run the edje animation to contract
+ *
+ * @ingroup Panel
+ */
+EAPI void
+elm_panel_hidden_set(Evas_Object *obj, Eina_Bool hidden)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->hidden == hidden) return;
+   wd->hidden = hidden;
+   _toggle_panel(obj, NULL, "elm,action,panel,toggle", "*");
+}
+
+/**
+ * Get the state of the panel.
+ *
+ * @param obj The panel object
+ * @param hidden If true, the panel is in the "hide" state
+ *
+ * @ingroup Panel
+ */
+EAPI Eina_Bool
+elm_panel_hidden_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->hidden;
+}
+
+/**
+ * Toggle the state of the panel from code
+ *
+ * @param obj The panel object
+ *
+ * @ingroup Panel
+ */
+EAPI void
+elm_panel_toggle(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->hidden = !(wd->hidden);
+   _toggle_panel(obj, NULL, "elm,action,panel,toggle", "*");
+}
diff --git a/src/lib/elm_photo.c b/src/lib/elm_photo.c
new file mode 100644 (file)
index 0000000..5526ee6
--- /dev/null
@@ -0,0 +1,161 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Photo Photo
+ *
+ * For displaying the photo of a person (contact). Simple yet
+ * with a very specific purpose. 
+ * 
+ * Signals that you can add callbacks for are:
+ *
+ * clicked - This is called when a user has clicked the photo
+ *
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *frm;
+   Evas_Object *img;
+   int size;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   edje_object_scale_set(wd->frm, elm_widget_scale_get(obj) * _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   if (!wd) return;
+   evas_object_size_hint_min_set(wd->img,
+                                wd->size * elm_widget_scale_get(obj) * _elm_config->scale,
+                                wd->size * elm_widget_scale_get(obj) * _elm_config->scale);
+   edje_object_part_swallow(wd->frm, "elm.swallow.content", wd->img);
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   edje_object_size_min_restricted_calc(wd->frm, &minw, &minh, minw, minh);
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   maxw = minw;
+   maxh = minh;
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, "clicked", NULL);
+}
+
+/**
+ * Add a new photo to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Photo
+ */
+EAPI Evas_Object *
+elm_photo_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "photo");
+   elm_widget_type_set(obj, "photo");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_can_focus_set(obj, 0);
+
+   wd->frm = edje_object_add(e);
+   _elm_theme_object_set(obj, wd->frm, "photo", "base", "default");
+   elm_widget_resize_object_set(obj, wd->frm);
+
+   wd->img = _els_smart_icon_add(e);
+   _els_smart_icon_scale_up_set(wd->img, 1);
+   _els_smart_icon_scale_down_set(wd->img, 1);
+   _els_smart_icon_smooth_scale_set(wd->img, 1);
+   _els_smart_icon_fill_inside_set(wd->img, 0);
+   _els_smart_icon_scale_set(wd->img, elm_widget_scale_get(obj) * _elm_config->scale);
+   evas_object_event_callback_add(wd->img, EVAS_CALLBACK_MOUSE_UP,
+                                 _mouse_up, obj);
+   evas_object_repeat_events_set(wd->img, 1);
+   edje_object_part_swallow(wd->frm, "elm.swallow.content", wd->img);
+   evas_object_show(wd->img);
+   elm_widget_sub_object_add(obj, wd->img);
+
+   wd->size = 40;
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Set the file that will be used as photo
+ *
+ * @param obj The photo object
+ * @param file The path to file that will be used as photo
+ *
+ * @return (1 = sucess, 0 = error)
+ *
+ * @ingroup Photo
+ */
+EAPI Eina_Bool
+elm_photo_file_set(Evas_Object *obj, const char *file)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   if (!_els_smart_icon_file_key_set(wd->img, file, NULL))
+     return 0;
+   _sizing_eval(obj);
+   return 1;
+}
+
+/**
+ * Set the size that will be used on the photo
+ *
+ * @param obj The photo object
+ * @param size The size that the photo will be
+ *
+ * @ingroup Photo
+ */
+EAPI void
+elm_photo_size_set(Evas_Object *obj, int size)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (size < 0) size = 0;
+   wd->size = size;
+   _sizing_eval(obj);
+}
diff --git a/src/lib/elm_photocam.c b/src/lib/elm_photocam.c
new file mode 100644 (file)
index 0000000..426cd8a
--- /dev/null
@@ -0,0 +1,1631 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Photocam Photocam
+ *
+ * This is a widget specifically for displaying high-resolution digital
+ * camera photos giving speedy feedback (fast load), low memory footprint
+ * and zooming and panning as well as fitting logic. It is entirely focused
+ * on jpeg images, and takes advantage of properties of the jpeg format (via
+ * evas loader features in the jpeg loader).
+ * 
+ * Signals that you can add callbacks for are:
+ *
+ * clicked - This is called when a user has clicked the photo without dragging
+ * around.
+ * 
+ * press - This is called when a user has pressed down on the photo.
+ * 
+ * longpressed - This is called when a user has pressed down on the photo for
+ * a long time without dragging around.
+ * 
+ * clicked,double - This is called when a user has double-clicked the photo.
+ * 
+ * load - Photo load begins.
+ * 
+ * loaded - This is called when the image file load is complete for the first
+ * view (low resolution blurry version).
+ *
+ * load,details - Photo detailed data load begins.
+ * 
+ * loaded,details - This is called when the image file load is complete for the
+ * detailed image data (full resolution needed).
+ *
+ * zoom,start - Zoom animation started.
+ * 
+ * zoom,stop - Zoom animation stopped.
+ * 
+ * zoom,change - Zoom changed when using an auto zoom mode.
+ * 
+ * scroll - the content has been scrolled (moved)
+ *
+ * scroll,anim,start - scrolling animation has started
+ *
+ * scroll,anim,stop - scrolling animation has stopped
+ *
+ * scroll,drag,start - dragging the contents around has started
+ *
+ * scroll,drag,stop - dragging the contents around has stopped
+ * 
+ * ---
+ * 
+ * TODO (maybe - optional future stuff):
+ * 
+ * 1. wrap photo in theme edje so u can have styling around photo (like white
+ *    photo bordering).
+ * 2. exif handling
+ * 3. rotation flags in exif handling (nasty! should have rot in evas)
+ *
+ */
+typedef struct _Widget_Data Widget_Data;
+typedef struct _Pan Pan;
+typedef struct _Grid Grid;
+typedef struct _Grid_Item Grid_Item;
+
+struct _Grid_Item
+{
+   Widget_Data *wd;
+   Evas_Object *img;
+   struct 
+     {
+        int x, y, w, h;
+     } src, out;
+   Eina_Bool want : 1;
+   Eina_Bool have : 1;
+};
+
+struct _Grid
+{
+   int tsize; // size of tile (tsize x tsize pixels)
+   int zoom; // zoom level tiles want for optimal display (1, 2, 4, 8)
+   int iw, ih; // size of image in pixels
+   int w, h; // size of grid image in pixels (represented by grid)
+   int gw, gh; // size of grid in tiles
+   Grid_Item *grid; // the grid (gw * gh items)
+   Eina_Bool dead : 1; // old grid. will die as soon as anim is over
+};
+
+struct _Widget_Data
+{
+   Evas_Object *obj;
+   Evas_Object *scr;
+   Evas_Object *pan_smart;
+   Pan *pan;
+   Evas_Coord pan_x, pan_y, minw, minh;
+
+   double zoom;
+   Elm_Photocam_Zoom_Mode mode;
+   const char *file;
+   
+   Ecore_Job *calc_job;
+   Ecore_Timer *scr_timer;
+   Ecore_Timer *long_timer;
+   Ecore_Animator *zoom_animator;
+   double t_start, t_end;
+   struct 
+     {
+        int imw, imh;
+        int w, h;
+        int ow, oh, nw, nh;
+        struct 
+          {
+             double x, y;
+          } spos;
+     } size;
+   struct
+     {
+       Eina_Bool show : 1;
+       Evas_Coord x, y ,w ,h;
+     } show;
+   int tsize;
+   Evas_Object *img; // low res version of image (scale down == 8)
+   int nosmooth;
+   int preload_num;
+   Eina_List *grids;
+   Eina_Bool main_load_pending : 1;
+   Eina_Bool resized : 1;
+   Eina_Bool longpressed : 1;
+   Eina_Bool on_hold : 1;
+   Eina_Bool paused : 1;
+};
+
+struct _Pan
+{
+   Evas_Object_Smart_Clipped_Data __clipped_data;
+   Widget_Data *wd;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+//static void _show_region_hook(void *data, Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _calc_job(void *data);
+static void grid_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh);
+static void grid_clear(Evas_Object *obj, Grid *g);
+static Grid *grid_create(Evas_Object *obj);
+static void grid_load(Evas_Object *obj, Grid *g);
+
+static int
+nearest_pow2(int num)
+{
+   unsigned int n = num - 1;
+   n |= n >> 1;
+   n |= n >> 2;
+   n |= n >> 4;
+   n |= n >> 8;
+   n |= n >> 16;
+   return n + 1;
+}
+
+static void
+img_place(Evas_Object *obj, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord ax, ay, gw, gh;
+   if (!wd) return;
+   ax = 0;
+   ay = 0;
+   gw = wd->size.w;
+   gh = wd->size.h;
+   if (ow > gw) ax = (ow - gw) / 2;
+   if (oh > gh) ay = (oh - gh) / 2;
+   evas_object_move(wd->img, ox + 0 - px + ax, oy + 0 - py + ay);
+   evas_object_resize(wd->img, gw, gh);
+
+   if (wd->show.show)
+     {
+       wd->show.show = EINA_FALSE;
+       elm_smart_scroller_child_region_show(wd->scr, wd->show.x, wd->show.y, wd->show.w, wd->show.h);
+     }
+}
+
+static void
+grid_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord ax, ay, gw, gh, tx, ty;
+   int x, y;
+   if (!wd) return;
+   ax = 0;
+   ay = 0;
+   gw = wd->size.w;
+   gh = wd->size.h;
+   if (ow > gw) ax = (ow - gw) / 2;
+   if (oh > gh) ay = (oh - gh) / 2;
+   for (y = 0; y < g->gh; y++)
+     {
+        for (x = 0; x < g->gw; x++)
+          {
+             int tn, xx, yy, ww, hh;
+             
+             tn = (y * g->gw) + x;
+             xx = g->grid[tn].out.x;
+             yy = g->grid[tn].out.y;
+             ww = g->grid[tn].out.w;
+             hh = g->grid[tn].out.h;
+             if ((gw != g->w) && (g->w > 0))
+               {
+                  tx = xx;
+                  xx = (gw * xx) / g->w;
+                  ww = ((gw * (tx + ww)) / g->w) - xx;
+               }
+             if ((gh != g->h) && (g->h > 0))
+               {
+                  ty = yy;
+                  yy = (gh * yy) / g->h;
+                  hh = ((gh * (ty + hh)) / g->h) - yy;
+               }
+             evas_object_move(g->grid[tn].img,
+                              ox + xx - px + ax,
+                              oy + yy - py + ay);
+             evas_object_resize(g->grid[tn].img, ww, hh);
+          }
+     }
+}
+
+static void
+grid_clear(Evas_Object *obj, Grid *g)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   int x, y;
+   if (!wd) return;
+   if (!g->grid) return;
+   for (y = 0; y < g->gh; y++)
+     {
+        for (x = 0; x < g->gw; x++)
+          {
+             int tn;
+             
+             tn = (y * g->gw) + x;
+             evas_object_del(g->grid[tn].img);
+             if (g->grid[tn].want)
+               {
+                  wd->preload_num--;
+                  if (wd->preload_num == 0)
+                    {
+                       edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
+                                               "elm,state,busy,stop", "elm");
+                       evas_object_smart_callback_call(obj, "loaded,detail", NULL);
+                    }
+               }
+          }
+     }
+   free(g->grid);
+   g->grid = NULL;
+   g->gw = 0;
+   g->gh = 0;
+}
+
+static void
+_tile_preloaded(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info __UNUSED__)
+{
+   Grid_Item *git = data;
+
+   if (git->want)
+     {
+        git->want = 0;
+        evas_object_show(git->img);
+        git->have = 1;
+        git->wd->preload_num--;
+        if (git->wd->preload_num == 0)
+          {
+             edje_object_signal_emit(elm_smart_scroller_edje_object_get(git->wd->scr),
+                                     "elm,state,busy,stop", "elm");
+             evas_object_smart_callback_call(git->wd->obj, "loaded,detail", NULL);
+          }
+     }
+}
+
+static int
+grid_zoom_calc(double zoom)
+{
+   int z = zoom;
+   if (z < 1) z = 1;
+   return nearest_pow2(z);
+}
+
+static Grid *
+grid_create(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   int x, y;
+   Grid *g;
+   
+   if (!wd) return NULL;
+   g = calloc(1, sizeof(Grid));
+   
+   g->zoom = grid_zoom_calc(wd->zoom);
+   g->tsize = wd->tsize;
+   g->iw = wd->size.imw;
+   g->ih = wd->size.imh;
+   
+   g->w = g->iw / g->zoom;
+   g->h = g->ih / g->zoom;
+   if (g->zoom >= 8) return NULL;
+   g->gw = (g->w + g->tsize - 1) / g->tsize;
+   g->gh = (g->h + g->tsize - 1) / g->tsize;
+   g->grid = calloc(1, sizeof(Grid_Item) * g->gw * g->gh);
+   if (!g->grid)
+     {
+        g->gw = 0;
+        g->gh = 0;
+        return g;
+     }
+   for (y = 0; y < g->gh; y++)
+     {
+        for (x = 0; x < g->gw; x++)
+          {
+             int tn;
+             
+             tn = (y * g->gw) + x;
+             g->grid[tn].src.x = x * g->tsize;
+             if (x == (g->gw - 1))
+               g->grid[tn].src.w = g->w - ((g->gw - 1) * g->tsize);
+             else
+               g->grid[tn].src.w = g->tsize;
+             g->grid[tn].src.y = y * g->tsize;
+             if (y == (g->gh - 1))
+               g->grid[tn].src.h = g->h - ((g->gh - 1) * g->tsize);
+             else
+               g->grid[tn].src.h = g->tsize;
+             
+             g->grid[tn].out.x = g->grid[tn].src.x;
+             g->grid[tn].out.y = g->grid[tn].src.y;
+             g->grid[tn].out.w = g->grid[tn].src.w;
+             g->grid[tn].out.h = g->grid[tn].src.h;
+             
+             g->grid[tn].wd = wd;
+             g->grid[tn].img = 
+               evas_object_image_add(evas_object_evas_get(obj));
+             evas_object_image_scale_hint_set
+               (g->grid[tn].img, EVAS_IMAGE_SCALE_HINT_DYNAMIC);
+             evas_object_pass_events_set(g->grid[tn].img, 1);
+             evas_object_smart_member_add(g->grid[tn].img, 
+                                          wd->pan_smart);
+             elm_widget_sub_object_add(obj, g->grid[tn].img);
+             evas_object_image_filled_set(g->grid[tn].img, 1);
+             evas_object_event_callback_add(g->grid[tn].img, 
+                                            EVAS_CALLBACK_IMAGE_PRELOADED,
+                                            _tile_preloaded, 
+                                            &(g->grid[tn]));
+          }
+     }
+   return g;
+}
+
+static void
+grid_load(Evas_Object *obj, Grid *g)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   int x, y;
+   Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh, gw, gh, ax, ay, tx, ty;
+   if (!wd) return;
+   evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
+   evas_output_viewport_get(evas_object_evas_get(wd->obj), &cvx, &cvy, &cvw, &cvh);
+   ax = 0;
+   ay = 0;
+   gw = wd->size.w;
+   gh = wd->size.h;
+   if (ow > gw) ax = (ow - gw) / 2;
+   if (oh > gh) ay = (oh - gh) / 2;
+   for (y = 0; y < g->gh; y++)
+     {
+        for (x = 0; x < g->gw; x++)
+          {
+             int tn, xx, yy, ww, hh;
+             Eina_Bool visible = 0;
+             
+             tn = (y * g->gw) + x;
+             xx = g->grid[tn].out.x;
+             yy = g->grid[tn].out.y;
+             ww = g->grid[tn].out.w;
+             hh = g->grid[tn].out.h;
+             if ((gw != g->w) && (g->w > 0))
+               {
+                  tx = xx;
+                  xx = (gw * xx) / g->w;
+                  ww = ((gw * (tx + ww)) / g->w) - xx;
+               }
+             if ((gh != g->h) && (g->h > 0))
+               {
+                  ty = yy;
+                  yy = (gh * yy) / g->h;
+                  hh = ((gh * (ty + hh)) / g->h) - yy;
+               }
+//             xx += ax;
+//             yy += ay;
+             if (ELM_RECTS_INTERSECT(xx - wd->pan_x + ox, 
+                                     yy  - wd->pan_y + oy,
+                                     ww, hh,
+                                     cvx, cvy, cvw, cvh))
+               visible = 1;
+             if ((visible) && (!g->grid[tn].have) && (!g->grid[tn].want))
+               {
+                  g->grid[tn].want = 1;
+                  evas_object_hide(g->grid[tn].img);
+                  evas_object_image_file_set(g->grid[tn].img, NULL, NULL);
+                  evas_object_image_load_scale_down_set(g->grid[tn].img, g->zoom);
+                  evas_object_image_load_region_set(g->grid[tn].img,
+                                                    g->grid[tn].src.x,
+                                                    g->grid[tn].src.y,
+                                                    g->grid[tn].src.w,
+                                                    g->grid[tn].src.h);
+                  evas_object_image_file_set(g->grid[tn].img, wd->file, NULL); 
+                  evas_object_image_preload(g->grid[tn].img, 0);
+                  wd->preload_num++;
+                  if (wd->preload_num == 1)
+                    {
+                       edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
+                                               "elm,state,busy,start", "elm");
+                       evas_object_smart_callback_call(obj, "load,detail", NULL);
+                    }
+               }
+             else if ((g->grid[tn].want) && (!visible))
+               {
+                  wd->preload_num--;
+                  if (wd->preload_num == 0)
+                    {
+                       edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
+                                               "elm,state,busy,stop", "elm");
+                       evas_object_smart_callback_call(obj, "loaded,detail", NULL);
+                    }
+                  g->grid[tn].want = 0;
+                  evas_object_hide(g->grid[tn].img);
+                  evas_object_image_preload(g->grid[tn].img, 1);
+                  evas_object_image_file_set(g->grid[tn].img, NULL, NULL);
+               }
+             else if ((g->grid[tn].have) && (!visible))
+               {
+                  g->grid[tn].have = 0;
+                  evas_object_hide(g->grid[tn].img);
+                  evas_object_image_preload(g->grid[tn].img, 1);
+                  evas_object_image_file_set(g->grid[tn].img, NULL, NULL);
+               }
+          }
+     }
+}
+
+static void
+grid_clearall(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Grid *g;
+   if (!wd) return;
+   EINA_LIST_FREE(wd->grids, g)
+     {
+        grid_clear(obj, g);
+        free(g);
+     }
+}
+
+static void
+_smooth_update(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   int x, y;
+   Eina_List *l;
+   Grid *g;
+   if (!wd) return;
+   EINA_LIST_FOREACH(wd->grids, l, g)
+     {
+        for (y = 0; y < g->gh; y++)
+          {
+             for (x = 0; x < g->gw; x++)
+               {
+                  int tn;
+                  
+                  tn = (y * g->gw) + x;
+                  evas_object_image_smooth_scale_set(g->grid[tn].img, (wd->nosmooth == 0));
+               }
+          }
+     }
+   evas_object_image_smooth_scale_set(wd->img, (wd->nosmooth == 0));
+}
+
+static void
+_grid_raise(Grid *g)
+{
+   int x, y;
+   
+   for (y = 0; y < g->gh; y++)
+     {
+        for (x = 0; x < g->gw; x++)
+          {
+             int tn;
+             
+             tn = (y * g->gw) + x;
+             evas_object_raise(g->grid[tn].img);
+          }
+     }
+}
+
+static int
+_scr_timeout(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return 0;
+   wd->nosmooth--;
+   if (wd->nosmooth == 0) _smooth_update(data);
+   wd->scr_timer = NULL;
+   return 0;
+}
+
+static void
+_scr(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (!wd->scr_timer)
+     {
+        wd->nosmooth++;
+        if (wd->nosmooth == 1) _smooth_update(data);
+     }
+   if (wd->scr_timer) ecore_timer_del(wd->scr_timer);
+   wd->scr_timer = ecore_timer_add(0.5, _scr_timeout, data);
+}
+
+static void
+_main_preloaded(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info __UNUSED__)
+{
+   Evas_Object *obj = data;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Grid *g;
+   if (!wd) return;
+   evas_object_show(wd->img);
+   wd->main_load_pending = 0;
+   g = grid_create(obj);
+   if (g)
+     {
+        wd->grids = eina_list_prepend(wd->grids, g);
+        grid_load(wd->obj, g);
+     }
+   if (wd->calc_job) ecore_job_del(wd->calc_job);
+   wd->calc_job = ecore_job_add(_calc_job, wd);
+   evas_object_smart_callback_call(data, "loaded", NULL);
+   wd->preload_num--;
+   if (wd->preload_num == 0)
+     {
+        edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
+                                "elm,state,busy,stop", "elm");
+        evas_object_smart_callback_call(obj, "loaded,detail", NULL);
+     }
+}
+
+static int
+zoom_do(Evas_Object *obj, double t)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord xx, yy, ow, oh;
+   if (!wd) return 0;
+   wd->size.w = (wd->size.ow * (1.0 - t)) + (wd->size.nw * t);
+   wd->size.h = (wd->size.oh * (1.0 - t)) + (wd->size.nh * t);
+   elm_smart_scroller_child_viewport_size_get(wd->scr, &ow, &oh);
+   xx = (wd->size.spos.x * wd->size.w) - (ow / 2);
+   yy = (wd->size.spos.y * wd->size.h) - (oh / 2);
+   if (xx < 0) xx = 0;
+   else if (xx > (wd->size.w - ow)) xx = wd->size.w - ow;
+   if (yy < 0) yy = 0;
+   else if (yy > (wd->size.h - oh)) yy = wd->size.h - oh;
+
+   wd->show.show = EINA_TRUE;
+   wd->show.x = xx;
+   wd->show.y = yy;
+   wd->show.w = ow;
+   wd->show.h = oh;
+
+   if (wd->calc_job) ecore_job_del(wd->calc_job);
+   wd->calc_job = ecore_job_add(_calc_job, wd);
+   if (t >= 1.0)
+     {
+        Eina_List *l, *l_next;
+        Grid *g;
+        
+        EINA_LIST_FOREACH_SAFE(wd->grids, l, l_next, g)
+          {
+             if (g->dead)
+               {
+                  wd->grids = eina_list_remove_list(wd->grids, l);
+                  grid_clear(obj, g);
+                  free(g);
+               }
+          }
+        return 0;
+     }
+   return 1;
+}
+
+
+static int
+_zoom_anim(void *data)
+{
+   Evas_Object *obj = data;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   double t;
+   int go;
+   if (!wd) return 0;
+   t = ecore_loop_time_get();
+   if (t >= wd->t_end)
+     t = 1.0;
+   else if (wd->t_end > wd->t_start)
+     t = (t - wd->t_start) / (wd->t_end - wd->t_start);
+   else
+     t = 1.0;
+   t = 1.0 - t;
+   t = 1.0 - (t * t);
+   go = zoom_do(obj, t);
+   if (!go)
+     {
+        wd->nosmooth--;
+        if (wd->nosmooth == 0) _smooth_update(data);
+        wd->zoom_animator = NULL;
+        evas_object_smart_callback_call(obj, "zoom,stop", NULL);
+     }
+   return go;
+}
+
+static void
+_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+//   Evas_Event_Mouse_Move *ev = event_info;
+   if (!wd) return;
+}
+
+static int
+_long_press(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return 0;
+   wd->long_timer = NULL;
+   wd->longpressed = EINA_TRUE;
+   evas_object_smart_callback_call(data, "longpressed", NULL);
+   return 0;
+}
+
+static void
+_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Event_Mouse_Down *ev = event_info;
+   if (!wd) return;
+   if (ev->button != 1) return;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) wd->on_hold = EINA_TRUE;
+   else wd->on_hold = EINA_FALSE;
+   if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
+     evas_object_smart_callback_call(data, "clicked,double", NULL);
+   else
+     evas_object_smart_callback_call(data, "press", NULL);
+   wd->longpressed = EINA_FALSE;
+   if (wd->long_timer) ecore_timer_del(wd->long_timer);
+   wd->long_timer = ecore_timer_add(1.0, _long_press, data);
+}
+   
+static void
+_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Event_Mouse_Up *ev = event_info;
+   if (!wd) return;
+   if (ev->button != 1) return;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) wd->on_hold = EINA_TRUE;
+   else wd->on_hold = EINA_FALSE;
+   if (wd->long_timer)
+     {
+        ecore_timer_del(wd->long_timer);
+        wd->long_timer = NULL;
+     }
+   if (!wd->on_hold)
+     evas_object_smart_callback_call(data, "clicked", NULL);
+   wd->on_hold = EINA_FALSE;
+}
+   
+static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_NULL;
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Grid *g;
+   if (!wd) return;
+   EINA_LIST_FREE(wd->grids, g)
+     {
+        if (g->grid) free(g->grid);
+        free(g);
+     }
+   evas_object_del(wd->pan_smart);
+   wd->pan_smart = NULL;
+   if (wd->file) eina_stringshare_del(wd->file);
+   if (wd->calc_job) ecore_job_del(wd->calc_job);
+   if (wd->scr_timer) ecore_timer_del(wd->scr_timer);
+   if (wd->zoom_animator) ecore_animator_del(wd->zoom_animator);
+   if (wd->long_timer) ecore_timer_del(wd->long_timer);
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "photocam", "base", elm_widget_style_get(obj));
+//   edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+/*
+static void
+_show_region_hook(void *data, Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Coord x, y, w, h;
+   if (!wd) return;
+   elm_widget_show_region_get(obj, &x, &y, &w, &h);
+   elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
+}
+*/
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   if (!wd) return;
+//   evas_object_size_hint_min_get(wd->scr, &minw, &minh);
+   evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
+//   minw = -1;
+//   minh = -1;
+//   if (wd->mode != ELM_LIST_LIMIT) minw = -1;
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_calc_job(void *data)
+{
+   Widget_Data *wd = data;
+   Evas_Coord minw, minh;
+   if (!wd) return;
+   minw = wd->size.w;
+   minh = wd->size.h;
+   if (wd->resized)
+     {
+        wd->resized = 0;
+        if (wd->mode != ELM_PHOTOCAM_ZOOM_MODE_MANUAL)
+          {
+             double tz = wd->zoom;
+             wd->zoom = 0.0;
+             elm_photocam_zoom_set(wd->obj, tz);
+          }
+     }
+   if ((minw != wd->minw) || (minh != wd->minh))
+     {
+        wd->minw = minw;
+        wd->minh = minh;
+        evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
+        _sizing_eval(wd->obj);
+     }
+   wd->calc_job = NULL;
+   evas_object_smart_changed(wd->pan_smart);
+}
+
+static void
+_pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
+   sd->wd->pan_x = x;
+   sd->wd->pan_y = y;
+   evas_object_smart_changed(obj);
+}
+
+static void
+_pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (x) *x = sd->wd->pan_x;
+   if (y) *y = sd->wd->pan_y;
+}
+
+static void
+_pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   Evas_Coord ow, oh;
+   if (!sd) return;
+   evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
+   ow = sd->wd->minw - ow;
+   if (ow < 0) ow = 0;
+   oh = sd->wd->minh - oh;
+   if (oh < 0) oh = 0;
+   if (x) *x = ow;
+   if (y) *y = oh;
+}
+
+static void
+_pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (w) *w = sd->wd->minw;
+   if (h) *h = sd->wd->minh;
+}
+
+static void
+_pan_add(Evas_Object *obj)
+{
+   Pan *sd;
+   Evas_Object_Smart_Clipped_Data *cd;
+   _pan_sc.add(obj);
+   cd = evas_object_smart_data_get(obj);
+   if (!cd) return;
+   sd = calloc(1, sizeof(Pan));
+   if (!sd) return;
+   sd->__clipped_data = *cd;
+   free(cd);
+   evas_object_smart_data_set(obj, sd);
+}
+
+static void
+_pan_del(Evas_Object *obj)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   _pan_sc.del(obj);
+}
+
+static void
+_pan_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   Evas_Coord ow, oh;
+   if (!sd) return;
+   evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
+   if ((ow == w) && (oh == h)) return;
+   sd->wd->resized = 1;
+   if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
+   sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
+}
+
+static void
+_pan_calculate(Evas_Object *obj)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   Evas_Coord ox, oy, ow, oh;
+   Eina_List *l;
+   Grid *g;
+   if (!sd) return;
+   evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
+   img_place(sd->wd->obj, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
+   EINA_LIST_FOREACH(sd->wd->grids, l, g)
+     {
+        grid_load(sd->wd->obj, g);
+        grid_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
+     }
+}
+
+static void
+_pan_move(Evas_Object *obj, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
+   sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
+}
+
+static void
+_hold_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_hold_set(wd->scr, 1);
+}
+
+static void
+_hold_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_hold_set(wd->scr, 0);
+}
+
+static void
+_freeze_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_freeze_set(wd->scr, 1);
+}
+
+static void
+_freeze_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_freeze_set(wd->scr, 0);
+}
+
+static void
+_scr_anim_start(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, "scroll,anim,start", NULL);
+}
+
+static void
+_scr_anim_stop(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, "scroll,anim,stop", NULL);
+}
+
+static void
+_scr_drag_start(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, "scroll,drag,start", NULL);
+}
+
+static void
+_scr_drag_stop(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, "scroll,drag,stop", NULL);
+}
+
+static void
+_scr_scroll(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, "scroll", NULL);
+}
+
+/**
+ * Add a new Photocam object
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Photocam
+ */
+EAPI Evas_Object *
+elm_photocam_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+   Evas_Coord minw, minh;
+   static Evas_Smart *smart = NULL;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "photocam");
+   elm_widget_type_set(obj, "photocam");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   wd->scr = elm_smart_scroller_add(e);
+   elm_smart_scroller_widget_set(wd->scr, obj);
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "photocam", "base", "default");
+   evas_object_smart_callback_add(wd->scr, "scroll", _scr, obj);
+   evas_object_smart_callback_add(wd->scr, "drag", _scr, obj);
+   elm_widget_resize_object_set(obj, wd->scr);
+
+   evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
+   evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
+   evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
+   evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
+   evas_object_smart_callback_add(wd->scr, "scroll", _scr_scroll, obj);
+   
+   elm_smart_scroller_bounce_allow_set(wd->scr, 1, 1);
+
+   wd->obj = obj;
+
+   evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
+   evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
+   evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
+   evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
+   
+   if (!smart)
+     {
+       static Evas_Smart_Class sc;
+
+       evas_object_smart_clipped_smart_set(&_pan_sc);
+       sc = _pan_sc;
+       sc.name = "elm_photocam_pan";
+       sc.version = EVAS_SMART_CLASS_VERSION;
+       sc.add = _pan_add;
+       sc.del = _pan_del;
+       sc.resize = _pan_resize;
+       sc.move = _pan_move;
+       sc.calculate = _pan_calculate;
+       smart = evas_smart_class_new(&sc);
+     }
+   if (smart)
+     {
+       wd->pan_smart = evas_object_smart_add(e, smart);
+       wd->pan = evas_object_smart_data_get(wd->pan_smart);
+       wd->pan->wd = wd;
+     }
+
+   elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
+                                    _pan_set, _pan_get,
+                                    _pan_max_get, _pan_child_size_get);
+
+   wd->zoom = 1;
+   wd->mode = ELM_PHOTOCAM_ZOOM_MODE_MANUAL;
+   
+   wd->tsize = 512;
+   
+   wd->img = evas_object_image_add(e);
+   evas_object_image_scale_hint_set(wd->img, EVAS_IMAGE_SCALE_HINT_DYNAMIC);
+   evas_object_event_callback_add(wd->img, EVAS_CALLBACK_MOUSE_DOWN,
+                                  _mouse_down, obj);
+   evas_object_event_callback_add(wd->img, EVAS_CALLBACK_MOUSE_UP,
+                                  _mouse_up, obj);
+   evas_object_event_callback_add(wd->img, EVAS_CALLBACK_MOUSE_MOVE,
+                                  _mouse_move, obj);
+   evas_object_image_scale_hint_set(wd->img, EVAS_IMAGE_SCALE_HINT_STATIC);
+   evas_object_smart_member_add(wd->img, wd->pan_smart);
+   elm_widget_sub_object_add(obj, wd->img);
+   evas_object_image_filled_set(wd->img, 1);
+   evas_object_event_callback_add(wd->img, EVAS_CALLBACK_IMAGE_PRELOADED,
+                                  _main_preloaded, obj);
+   
+   edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr), 
+                             &minw, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Set the photo file to be shown
+ *
+ * This sets (and shows) the specified file (with a relative or absolute path)
+ * and will return a load error (same error that
+ * evas_object_image_load_error_get() will return). The image will change and
+ * adjust its size at this point and begin a background load process for this
+ * photo that at some time in the future will be displayed at the full quality
+ * needed.
+ *
+ * @param obj The photocam object
+ * @param file The photo file
+ * @return The return error (see EVAS_LOAD_ERROR_NONE, EVAS_LOAD_ERROR_GENERIC etc.)
+ *
+ * @ingroup Photocam
+ */
+EAPI int
+elm_photocam_file_set(Evas_Object *obj, const char *file)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   int w, h;
+   if (!wd) return EVAS_LOAD_ERROR_GENERIC;
+   if (!eina_stringshare_replace(&wd->file, file)) return EVAS_LOAD_ERROR_NONE;
+   evas_object_hide(wd->img);
+   evas_object_image_smooth_scale_set(wd->img, (wd->nosmooth == 0));
+   evas_object_image_file_set(wd->img, NULL, NULL);
+   evas_object_image_load_scale_down_set(wd->img, 0);
+   evas_object_image_file_set(wd->img, wd->file, NULL);
+   evas_object_image_size_get(wd->img, &w, &h);
+   wd->size.imw = w;
+   wd->size.imh = h;
+   wd->size.w = wd->size.imw / wd->zoom;
+   wd->size.h = wd->size.imh / wd->zoom;
+   if (wd->zoom_animator)
+     {
+        wd->nosmooth--;
+        if (wd->nosmooth == 0) _smooth_update(obj);
+        ecore_animator_del(wd->zoom_animator);
+        wd->zoom_animator = NULL;
+     }
+   evas_object_image_file_set(wd->img, NULL, NULL);
+   evas_object_image_load_scale_down_set(wd->img, 8);
+   evas_object_image_file_set(wd->img, wd->file, NULL);
+   evas_object_image_preload(wd->img, 0);
+   wd->main_load_pending = 1;
+   grid_clearall(obj);
+   if (wd->calc_job) ecore_job_del(wd->calc_job);
+   wd->calc_job = ecore_job_add(_calc_job, wd);
+   evas_object_smart_callback_call(obj, "load", NULL);
+   wd->preload_num++;
+   if (wd->preload_num == 1)
+     {
+        edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
+                                "elm,state,busy,start", "elm");
+        evas_object_smart_callback_call(obj, "load,detail", NULL);
+     }
+     {
+        double tz = wd->zoom;
+        wd->zoom = 0.0;
+        elm_photocam_zoom_set(wd->obj, tz);
+     }
+   return evas_object_image_load_error_get(wd->img);
+}
+
+/*
+ * Returns the path of the current image file
+ *
+ * @param obj The photocam object
+ * @return Returns the path 
+ *
+ * @ingroup Photocam
+ */
+EAPI const char *
+elm_photocam_file_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->file;
+}
+
+/**
+ * Set the zoom level of the photo
+ *
+ * This sets the zoom level. 1 will be 1:1 pixel for pixel. 2 will be 2:1
+ * (that is 2x2 photo pixels will display as 1 on-screen pixel). 4:1 will be
+ * 4x4 photo pixels as 1 screen pixel, and so on. The @p zoom parameter must
+ * be greater than 0. It is usggested to stick to powers of 2. (1, 2, 4, 8,
+ * 16, 32, etc.). 
+ *
+ * @param obj The photocam object
+ * @param zoom The zoom level to set
+ *
+ * @ingroup Photocam
+ */
+EAPI void
+elm_photocam_zoom_set(Evas_Object *obj, double zoom)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Eina_List *l;
+   Grid *g, *g_zoom = NULL;
+   Evas_Coord pw, ph, rx, ry, rw, rh;
+   int z;
+   int zoom_changed = 0, started = 0;
+   Ecore_Animator *an;
+   if (!wd) return;
+   if (zoom <= (1.0 / 256.0)) zoom = (1.0 / 256.0);
+   if (zoom == wd->zoom) return;
+   wd->zoom = zoom;
+   wd->size.ow = wd->size.w;
+   wd->size.oh = wd->size.h;
+   elm_smart_scroller_child_pos_get(wd->scr, &rx, &ry);
+   elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
+   if ((rw <= 0) || (rh <= 0)) return;
+
+   if (wd->mode == ELM_PHOTOCAM_ZOOM_MODE_MANUAL)
+     {
+        wd->size.nw = (double)wd->size.imw / wd->zoom;
+        wd->size.nh = (double)wd->size.imh / wd->zoom;
+     }
+   else if (wd->mode == ELM_PHOTOCAM_ZOOM_MODE_AUTO_FIT)
+     {
+        if ((wd->size.imw < 1) || (wd->size.imh < 1))
+          {
+             wd->size.nw = 0;
+             wd->size.nw = 0;
+          }
+        else
+          {
+             ph = (wd->size.imh * rw) / wd->size.imw;
+             if (ph > rh)
+               {
+                  pw = (wd->size.imw * rh) / wd->size.imh;
+                  ph = rh;
+               }
+             else
+               {
+                  pw = rw;
+               }
+             if (wd->size.imw > wd->size.imh)
+               z = wd->size.imw / pw;
+             else
+               z = wd->size.imh / ph;
+             if      (z >= 8) z = 8;
+             else if (z >= 4) z = 4;
+             else if (z >= 2) z = 2;
+             else             z = 1;
+             if (z != wd->zoom) zoom_changed = 1;
+             wd->zoom = z;
+             wd->size.nw = pw;
+             wd->size.nh = ph;
+          }
+     }
+   else if (wd->mode == ELM_PHOTOCAM_ZOOM_MODE_AUTO_FILL)
+     {
+        if ((wd->size.imw < 1) || (wd->size.imh < 1))
+          {
+             wd->size.nw = 0;
+             wd->size.nw = 0;
+          }
+        else
+          {
+             ph = (wd->size.imh * rw) / wd->size.imw;
+             if (ph < rh)
+               {
+                  pw = (wd->size.imw * rh) / wd->size.imh;
+                  ph = rh;
+               }
+             else
+               {
+                  pw = rw;
+               }
+             if (wd->size.imw > wd->size.imh)
+               z = wd->size.imw / pw;
+             else
+               z = wd->size.imh / ph;
+             if      (z >= 8) z = 8;
+             else if (z >= 4) z = 4;
+             else if (z >= 2) z = 2;
+             else             z = 1;
+             if (z != wd->zoom) zoom_changed = 1;
+             wd->zoom = z;
+             wd->size.nw = pw;
+             wd->size.nh = ph;
+          }
+     }
+   if (wd->main_load_pending)
+     {
+        wd->size.w = wd->size.nw;
+        wd->size.h = wd->size.nh;
+        goto done;
+     }
+   EINA_LIST_FOREACH(wd->grids, l, g)
+     {
+        if (g->zoom == grid_zoom_calc(wd->zoom))
+          {
+             wd->grids = eina_list_remove(wd->grids, g);
+             wd->grids = eina_list_prepend(wd->grids, g);
+             _grid_raise(g);
+             goto done;
+          }
+     }
+   g = grid_create(obj);
+   if (g)
+     {
+        if (eina_list_count(wd->grids) > 1)
+          {
+             g_zoom = eina_list_last(wd->grids)->data;
+             wd->grids = eina_list_remove(wd->grids, g_zoom);
+             grid_clear(obj, g_zoom);
+             free(g_zoom);
+             EINA_LIST_FOREACH(wd->grids, l, g_zoom)
+               {
+                  g_zoom->dead = 1;
+               }
+          }
+        wd->grids = eina_list_prepend(wd->grids, g);
+     }
+   else
+     {
+        EINA_LIST_FREE(wd->grids, g)
+          {
+             grid_clear(obj, g);
+             free(g);
+          }
+     }
+   done:
+   wd->t_start = ecore_loop_time_get();
+   wd->t_end = wd->t_start + _elm_config->zoom_friction;
+   if ((wd->size.w > 0) && (wd->size.h > 0))
+     {
+        wd->size.spos.x = (double)(rx + (rw / 2)) / (double)wd->size.w;
+        wd->size.spos.y = (double)(ry + (rh / 2)) / (double)wd->size.h;
+     }
+   else
+     {
+        wd->size.spos.x = 0.5;
+        wd->size.spos.y = 0.5;
+     }
+   if (rw > wd->size.w) wd->size.spos.x = 0.5;
+   if (rh > wd->size.h) wd->size.spos.y = 0.5;
+   if (wd->size.spos.x > 1.0) wd->size.spos.x = 1.0;
+   if (wd->size.spos.y > 1.0) wd->size.spos.y = 1.0;
+   if (wd->paused)
+     {
+        zoom_do(obj, 1.0);
+     }
+   else
+     {
+        if (!wd->zoom_animator)
+          {
+             wd->zoom_animator = ecore_animator_add(_zoom_anim, obj);
+             wd->nosmooth++;
+             if (wd->nosmooth == 1) _smooth_update(obj);
+             started = 1;
+          }
+     }
+   an = wd->zoom_animator;
+   if (an)
+     {
+        if (!_zoom_anim(obj))
+          {
+             ecore_animator_del(an);
+             an = NULL;
+          }
+     }
+   if (wd->calc_job) ecore_job_del(wd->calc_job);
+   wd->calc_job = ecore_job_add(_calc_job, wd);
+   if (!wd->paused)
+     {
+        if (started)
+          evas_object_smart_callback_call(obj, "zoom,start", NULL);
+        if (!an)
+          evas_object_smart_callback_call(obj, "zoom,stop", NULL);
+     }
+   if (zoom_changed)
+     evas_object_smart_callback_call(obj, "zoom,change", NULL);
+}
+
+/**
+ * Get the zoom level of the photo
+ *
+ * This returns the current zoom level of the photocam object. Note that if
+ * you set the fill mode to other than ELM_PHOTOCAM_ZOOM_MODE_MANUAL
+ * (which is the default), the zoom level may be changed at any time by the
+ * photocam object itself to account for photo size and photocam viewpoer size
+ *
+ * @param obj The photocam object
+ * @return The current zoom level
+ *
+ * @ingroup Photocam
+ */
+EAPI double
+elm_photocam_zoom_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 1.0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 1.0;
+   return wd->zoom;
+}
+
+/**
+ * Set the zoom mode
+ *
+ * This sets the zoom mode to manual or one of several automatic levels.
+ * Manual (ELM_PHOTOCAM_ZOOM_MODE_MANUAL) means that zoom is set manually by
+ * elm_photocam_zoom_set() and will stay at that level until changed by code
+ * or until zoom mode is changed. This is the default mode.
+ * The Automatic modes will allow the photocam object to automatically
+ * adjust zoom mode based on properties. ELM_PHOTOCAM_ZOOM_MODE_AUTO_FIT) will
+ * adjust zoom so the photo fits EXACTLY inside the scroll frame with no pixels
+ * outside this area. ELM_PHOTOCAM_ZOOM_MODE_AUTO_FILL will be similar but
+ * ensure no pixels within the frame are left unfilled.
+ *
+ * @param obj The photocam object
+ * @param mode The desired mode
+ *
+ * @ingroup Photocam
+ */
+EAPI void
+elm_photocam_zoom_mode_set(Evas_Object *obj, Elm_Photocam_Zoom_Mode mode)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->mode == mode) return;
+   wd->mode = mode;
+     {
+        double tz = wd->zoom;
+        wd->zoom = 0.0;
+        elm_photocam_zoom_set(wd->obj, tz);
+     }
+}
+
+/**
+ * Get the zoom mode
+ *
+ * This gets the current zoom mode of the photocam object
+ *
+ * @param obj The photocam object
+ * @return The current zoom mode
+ *
+ * @ingroup Photocam
+ */
+EAPI Elm_Photocam_Zoom_Mode
+elm_photocam_zoom_mode_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) ELM_PHOTOCAM_ZOOM_MODE_LAST;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return ELM_PHOTOCAM_ZOOM_MODE_LAST;
+   return wd->mode;
+}
+
+/**
+ * Get the current image pixel width and height
+ *
+ * This gets the current photo pixel width and height (for the original).
+ * The size will be returned in the integers @p w and @p h that are pointed
+ * to.
+ *
+ * @param obj The photocam object
+ * @param w A pointer to the width return
+ * @param h A pointer to the height return
+ *
+ * @ingroup Photocam
+ */
+EAPI void
+elm_photocam_image_size_get(const Evas_Object *obj, int *w, int *h)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (w) *w = wd->size.imw;
+   if (h) *h = wd->size.imh;
+}
+
+/**
+ * Get the current area of the image that is currently shown
+ * 
+ * This gets the region 
+ * 
+ */
+EAPI void
+elm_photocam_region_get(const Evas_Object *obj, int *x, int *y, int *w, int *h)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord sx, sy, sw, sh;
+   if (!wd) return;
+   elm_smart_scroller_child_pos_get(wd->scr, &sx, &sy);
+   elm_smart_scroller_child_viewport_size_get(wd->scr, &sw, &sh);
+   if (wd->size.w > 0)
+     {
+        if (x)
+          {
+             *x = (wd->size.imw * sx) / wd->size.w;
+             if (*x > wd->size.imw) *x = wd->size.imw;
+             else if (*x < 0) *x = 0;
+          }
+        if (w)
+          {
+             *w = (wd->size.imw * sw) / wd->size.w;
+             if (*w > wd->size.imw) *w = wd->size.imw;
+             else if (*w < 0) *w = 0;
+          }
+     }
+   else
+     {
+       if (x) *x = 0;
+       if (w) *w = 0;
+     }
+
+   if (wd->size.h > 0)
+     {
+        if (y)
+          {
+             *y = (wd->size.imh * sy) / wd->size.h;
+             if (*y > wd->size.imh) *y = wd->size.imh;
+             else if (*y < 0) *y = 0;
+          }
+        if (h)
+          {
+             *h = (wd->size.imh * sh) / wd->size.h;
+             if (*h > wd->size.imh) *h = wd->size.imh;
+             else if (*h < 0) *h = 0;
+          }
+     }
+   else
+     {
+       if (y) *y = 0;
+       if (h) *h = 0;
+     }
+}
+
+/**
+ * Set the viewed portion of the image
+ *
+ * This sets the region of the image to be viewed
+ *
+ * @param obj The photocam object
+ * @param x X-coordinate of region in image original pixels
+ * @param y Y-coordinate of region in image original pixels
+ * @param w Width of region in image original pixels
+ * @param h Height of region in image original pixels
+ *
+ * @ingroup Photocam
+ */
+EAPI void
+elm_photocam_image_region_show(Evas_Object *obj, int x, int y, int w, int h __UNUSED__)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   int rx, ry, rw, rh;
+   if (!wd) return;
+   if ((wd->size.imw < 1) || (wd->size.imh < 1)) return;
+   rx = (x * wd->size.w) / wd->size.imw;
+   ry = (y * wd->size.h) / wd->size.imh;
+   rw = (w * wd->size.w) / wd->size.imw;
+   rh = (w * wd->size.h) / wd->size.imh;
+   if (rw < 1) rw = 1;
+   if (rh < 1) rh = 1;
+   if ((rx + rw) > wd->size.w) rx = wd->size.w - rw; 
+   if ((ry + rh) > wd->size.h) ry = wd->size.h - rh;
+   if (wd->zoom_animator)
+     {
+        wd->nosmooth--;
+        ecore_animator_del(wd->zoom_animator);
+        wd->zoom_animator = NULL;
+        zoom_do(obj, 1.0);
+        evas_object_smart_callback_call(obj, "zoom,stop", NULL);
+     }
+   elm_smart_scroller_child_region_show(wd->scr, rx, ry, rw, rh);
+}
+
+/**
+ * Bring in the viewed portion of the image
+ *
+ * This brings in the region of the image over time
+ *
+ * @param obj The photocam object
+ * @param x X-coordinate of region in image original pixels
+ * @param y Y-coordinate of region in image original pixels
+ * @param w Width of region in image original pixels
+ * @param h Height of region in image original pixels
+ *
+ * @ingroup Photocam
+ */
+EAPI void
+elm_photocam_image_region_bring_in(Evas_Object *obj, int x, int y, int w, int h __UNUSED__)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   int rx, ry, rw, rh;
+   if (!wd) return;
+   if ((wd->size.imw < 1) || (wd->size.imh < 1)) return;
+   rx = (x * wd->size.w) / wd->size.imw;
+   ry = (y * wd->size.h) / wd->size.imh;
+   rw = (w * wd->size.w) / wd->size.imw;
+   rh = (w * wd->size.h) / wd->size.imh;
+   if (rw < 1) rw = 1;
+   if (rh < 1) rh = 1;
+   if ((rx + rw) > wd->size.w) rx = wd->size.w - rw; 
+   if ((ry + rh) > wd->size.h) ry = wd->size.h - rh;
+   if (wd->zoom_animator)
+     {
+        wd->nosmooth--;
+        if (wd->nosmooth == 0) _smooth_update(obj);
+        ecore_animator_del(wd->zoom_animator);
+        wd->zoom_animator = NULL;
+        zoom_do(obj, 1.0);
+        evas_object_smart_callback_call(obj, "zoom,stop", NULL);
+    }
+   elm_smart_scroller_region_bring_in(wd->scr, rx, ry, rw, rh);
+}
+
+/**
+ * Set the paused state for photocam
+ * 
+ * This sets the paused state to on (1) or off (0) for photocam. The default
+ * is on. This will stop zooming using animation ch change zoom levels and
+ * change instantly. This will stop any existing animations that are running.
+ * 
+ * @param obj The photocam object
+ * @param paused The pause state to set
+ *
+ * @ingroup Photocam
+ */
+EAPI void
+elm_photocam_paused_set(Evas_Object *obj, Eina_Bool paused)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->paused == !!paused) return;
+   wd->paused = paused;
+   if (wd->paused)
+     {
+        if (wd->zoom_animator)
+          {
+             ecore_animator_del(wd->zoom_animator);
+             wd->zoom_animator = NULL;
+             zoom_do(obj, 1.0);
+             evas_object_smart_callback_call(obj, "zoom,stop", NULL);
+          }
+     }
+}
+
+/**
+ * Get the paused state for photocam
+ * 
+ * This gets the current paused state for the photocam object.
+ * 
+ * @param obj The photocam object
+ * @return The current paused state
+ *
+ * @ingroup Photocam
+ */
+EAPI Eina_Bool
+elm_photocam_paused_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->paused;
+}
+
+/**
+ * Get ther internal low-res image used for photocam
+ * 
+ * This gets the internal image object inside photocam. Do not modify it. It
+ * is for inspection only, and hooking callbacks to. Nothing else. It may be
+ * deleted at any time as well.
+ *
+ * @param obj The photocam object
+ * @return The internal image object handle, or NULL if none exists
+ *
+ * @ingroup Photocam
+ */
+EAPI Evas_Object *
+elm_photocam_internal_image_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->img;
+}
diff --git a/src/lib/elm_priv.h b/src/lib/elm_priv.h
new file mode 100644 (file)
index 0000000..b1c7002
--- /dev/null
@@ -0,0 +1,206 @@
+#ifndef ELM_PRIV_H
+#define ELM_PRIV_H
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+#ifdef HAVE_ELEMENTARY_X
+# include <Ecore_X.h>
+#endif
+#ifdef HAVE_ELEMENTARY_FB
+# include <Ecore_Fb.h>
+#endif
+#ifdef HAVE_ELEMENTARY_WINCE
+# include <Ecore_WinCE.h>
+#endif
+
+#include "els_pan.h"
+#include "els_scroller.h"
+#include "els_box.h"
+#include "els_icon.h"
+
+// FIXME: totally disorganised. clean this up!
+// 
+// Why EAPI in a private header ?
+// EAPI is temporaty - that widget api will change, but makign it EAPI right now to indicate its bound for externalness
+
+struct _Elm_Theme
+{
+   Eina_List *overlay;
+   Eina_List *themes;
+   Eina_List *extension;
+   Eina_Hash *cache;
+   const char *theme;
+   int ref;
+};
+
+typedef enum _Elm_Engine
+{
+   ELM_SOFTWARE_X11,
+     ELM_SOFTWARE_FB,
+     ELM_SOFTWARE_DIRECTFB,
+     ELM_SOFTWARE_16_X11,
+     ELM_XRENDER_X11,
+     ELM_OPENGL_X11,
+     ELM_SOFTWARE_WIN32,
+     ELM_SOFTWARE_16_WINCE,
+     ELM_SOFTWARE_SDL,
+     ELM_SOFTWARE_16_SDL,
+     ELM_OPENGL_SDL
+} Elm_Engine;
+
+typedef struct _Elm_Config Elm_Config;
+
+struct _Elm_Config
+{
+   int engine;
+   int thumbscroll_enable;
+   int thumbscroll_threshhold;
+   double thumbscroll_momentum_threshhold;
+   double thumbscroll_friction;
+   double thumbscroll_bounce_friction;
+   double page_scroll_friction;
+   double bring_in_scroll_friction;
+   double zoom_friction;
+   int thumbscroll_bounce_enable;
+   double scale;
+   int bgpixmap;
+   int compositing;
+   Eina_List *font_dirs;
+   int font_hinting;
+   int image_cache;
+   int font_cache;
+   int finger_size;
+   double fps;
+   const char *theme;
+   const char *modules;
+};
+
+typedef struct _Elm_Module Elm_Module;
+
+struct _Elm_Module
+{
+   int version;
+   const char *name;
+   const char *as;
+   const char *so_path;
+   const char *data_dir;
+   const char *bin_dir;
+   void *handle;
+   void *data;
+   void *api;
+   int (*init_func) (Elm_Module *m);
+   int (*shutdown_func) (Elm_Module *m);
+   int references;
+};
+
+#define ELM_NEW(t) calloc(1, sizeof(t))
+
+void _elm_win_shutdown(void);
+void _elm_win_rescale(void);
+
+int _elm_theme_object_set(Evas_Object *parent, Evas_Object *o, const char *clas, const char *group, const char *style);
+int _elm_theme_object_icon_set(Evas_Object *parent, Evas_Object *o, const char *group, const char *style);
+int _elm_theme_set(Elm_Theme *th, Evas_Object *o, const char *clas, const char *group, const char *style);
+int _elm_theme_icon_set(Elm_Theme *th, Evas_Object *o, const char *group, const char *style);
+int _elm_theme_parse(Elm_Theme *th, const char *theme);
+void _elm_theme_shutdown(void);
+
+void _elm_module_init(void);
+void _elm_module_shutdown(void);
+void _elm_module_parse(const char *s);
+Elm_Module *_elm_module_find_as(const char *as);
+Elm_Module *_elm_module_add(const char *name, const char *as);
+void _elm_module_del(Elm_Module *m);
+const void *_elm_module_symbol_get(Elm_Module *m, const char *name);
+    
+/* FIXME: should this be public? for now - private (but public symbols) */
+EAPI Evas_Object *elm_widget_add(Evas *evas);
+EAPI void         elm_widget_del_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
+EAPI void         elm_widget_del_pre_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
+EAPI void         elm_widget_focus_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
+EAPI void         elm_widget_activate_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
+EAPI void         elm_widget_disable_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
+EAPI void         elm_widget_theme_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
+EAPI void         elm_widget_changed_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
+EAPI void         elm_widget_theme(Evas_Object *obj);
+EAPI void         elm_widget_on_focus_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data);
+EAPI void         elm_widget_on_change_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data);
+EAPI void         elm_widget_on_show_region_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data);
+EAPI void         elm_widget_data_set(Evas_Object *obj, void *data);
+EAPI void        *elm_widget_data_get(const Evas_Object *obj);
+EAPI void         elm_widget_sub_object_add(Evas_Object *obj, Evas_Object *sobj);
+EAPI void         elm_widget_sub_object_del(Evas_Object *obj, Evas_Object *sobj);
+EAPI void         elm_widget_resize_object_set(Evas_Object *obj, Evas_Object *sobj);
+EAPI void         elm_widget_hover_object_set(Evas_Object *obj, Evas_Object *sobj);
+EAPI void         elm_widget_can_focus_set(Evas_Object *obj, int can_focus);
+EAPI int          elm_widget_can_focus_get(const Evas_Object *obj);
+EAPI int          elm_widget_focus_get(const Evas_Object *obj);
+EAPI Evas_Object *elm_widget_focused_object_get(const Evas_Object *obj);
+EAPI Evas_Object *elm_widget_top_get(const Evas_Object *obj);
+EAPI int          elm_widget_focus_jump(Evas_Object *obj, int forward);
+EAPI void         elm_widget_focus_set(Evas_Object *obj, int first);
+EAPI void         elm_widget_focused_object_clear(Evas_Object *obj);
+EAPI Evas_Object *elm_widget_parent_get(const Evas_Object *obj);
+EAPI void         elm_widget_focus_steal(Evas_Object *obj);
+EAPI void         elm_widget_activate(Evas_Object *obj);
+EAPI void         elm_widget_change(Evas_Object *obj);
+EAPI void         elm_widget_disabled_set(Evas_Object *obj, int disabled);
+EAPI int          elm_widget_disabled_get(const Evas_Object *obj);
+EAPI void         elm_widget_show_region_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
+EAPI void         elm_widget_show_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
+EAPI void         elm_widget_scroll_hold_push(Evas_Object *obj);
+EAPI void         elm_widget_scroll_hold_pop(Evas_Object *obj);
+EAPI int          elm_widget_scroll_hold_get(const Evas_Object *obj);
+EAPI void         elm_widget_scroll_freeze_push(Evas_Object *obj);
+EAPI void         elm_widget_scroll_freeze_pop(Evas_Object *obj);
+EAPI int          elm_widget_scroll_freeze_get(const Evas_Object *obj);
+EAPI void         elm_widget_scale_set(Evas_Object *obj, double scale);
+EAPI double       elm_widget_scale_get(const Evas_Object *obj);
+EAPI void         elm_widget_theme_set(Evas_Object *obj, Elm_Theme *th);
+EAPI Elm_Theme   *elm_widget_theme_get(const Evas_Object *obj);
+EAPI void         elm_widget_style_set(Evas_Object *obj, const char *style);
+EAPI const char  *elm_widget_style_get(const Evas_Object *obj);
+EAPI void         elm_widget_type_set(Evas_Object *obj, const char *type);
+EAPI const char  *elm_widget_type_get(const Evas_Object *obj);
+EAPI void         elm_widget_drag_lock_x_set(Evas_Object *obj, Eina_Bool lock);
+EAPI void         elm_widget_drag_lock_y_set(Evas_Object *obj, Eina_Bool lock);
+EAPI Eina_Bool    elm_widget_drag_lock_x_get(Evas_Object *obj);
+EAPI Eina_Bool    elm_widget_drag_lock_y_get(Evas_Object *obj);
+EAPI int          elm_widget_drag_child_locked_x_get(Evas_Object *obj);
+EAPI int          elm_widget_drag_child_locked_y_get(Evas_Object *obj);
+    
+EAPI Eina_Bool    elm_widget_is(const Evas_Object *obj);
+EAPI Evas_Object *elm_widget_parent_widget_get(const Evas_Object *obj);
+
+EAPI Eina_List   *_elm_stringlist_get(const char *str);
+EAPI void         _elm_stringlist_free(Eina_List *list);
+
+Eina_Bool         _elm_widget_type_check(const Evas_Object *obj, const char *type);
+
+void             _elm_unneed_ethumb(void);
+
+void              _elm_rescale(void);
+
+void              _elm_config_init(void);
+void              _elm_config_sub_init(void);
+void              _elm_config_shutdown(void);
+
+#define ELM_SET_WIDTYPE(widtype, type) if (!widtype) widtype = eina_stringshare_add(type)
+//#define ELM_CHECK_WIDTYPE(obj, widtype) if (elm_widget_type_get(obj) != widtype) return
+#define ELM_CHECK_WIDTYPE(obj, widtype) if (!_elm_widget_type_check((obj), (widtype))) return
+
+extern char *_elm_appname;
+extern Elm_Config *_elm_config;
+extern const char *_elm_data_dir;
+extern const char *_elm_lib_dir;
+extern int _elm_log_dom;
+
+extern Eina_List *_elm_win_list;
+
+#define CRITICAL(...) EINA_LOG_DOM_CRIT(_elm_log_dom, __VA_ARGS__)
+#define ERR(...) EINA_LOG_DOM_ERR(_elm_log_dom, __VA_ARGS__)
+#define WRN(...) EINA_LOG_DOM_WARN(_elm_log_dom, __VA_ARGS__)
+#define INF(...) EINA_LOG_DOM_INFO(_elm_log_dom, __VA_ARGS__)
+#define DBG(...) EINA_LOG_DOM_DBG(_elm_log_dom, __VA_ARGS__)
+
+#endif
diff --git a/src/lib/elm_progressbar.c b/src/lib/elm_progressbar.c
new file mode 100644 (file)
index 0000000..d290f1d
--- /dev/null
@@ -0,0 +1,604 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Progressbar Progressbar
+ *
+ * The progressbar adds a widget for representing current progress
+ * of a job status
+ *
+ * A progressbar can be horizontal or vertical. It can contain an Icon and has a
+ * primary label as well as a units label (that is formatted with floating
+ * point values and thus accepts a printf-style format string, like
+ * “%1.2f units”.
+ *
+ *  Label, Icon and Unit strings/objects are optional.
+ *
+ * A progressbar may be inverted which means values invert, with high vales being
+ * on the left or top and low values on the right or bottom (as opposed to
+ * normally being low on the left or top and high on the bottom and right).
+ *
+ * The span of the progressbar is its length (horizontally or vertically).
+ * This will be scaled by the object or applications scaling factor. At any point
+ * code can query the progressbar for its value with elm_progressbar_value_get().
+ */
+
+#define MIN_RATIO_LVL 0.0
+#define MAX_RATIO_LVL 1.0
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *progressbar;
+   Evas_Object *spacer;
+   Evas_Object *icon;
+   Evas_Coord size;
+   Eina_Bool horizontal : 1;
+   Eina_Bool inverted : 1;
+   Eina_Bool pulse : 1;
+   Eina_Bool pulse_state : 1;
+   const char *units;
+   const char *label;
+   double val;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+static void _units_set(Evas_Object *obj);
+static void _val_set(Evas_Object *obj);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->label) eina_stringshare_del(wd->label);
+   if (wd->units) eina_stringshare_del(wd->units);
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   edje_object_part_unswallow(NULL, wd->spacer);
+   if (wd->horizontal)
+     _elm_theme_object_set(obj, wd->progressbar, "progressbar", "horizontal", elm_widget_style_get(obj));
+   else
+     _elm_theme_object_set(obj, wd->progressbar, "progressbar", "vertical", elm_widget_style_get(obj));
+   if (wd->inverted)
+     edje_object_signal_emit(wd->progressbar, "elm,state,inverted,on", "elm");
+   else
+     edje_object_signal_emit(wd->progressbar, "elm,state,inverted,off", "elm");
+   if (wd->icon)
+     edje_object_signal_emit(wd->progressbar, "elm,state,icon,visible", "elm");
+   else
+     edje_object_signal_emit(wd->progressbar, "elm,state,icon,hidden", "elm");
+   if (wd->label)
+     edje_object_signal_emit(wd->progressbar, "elm,state,text,visible", "elm");
+   else
+     edje_object_signal_emit(wd->progressbar, "elm,state,text,hidden", "elm");
+   edje_object_part_text_set(wd->progressbar, "elm.text", wd->label);
+   if (wd->pulse)
+     edje_object_signal_emit(wd->progressbar, "elm,state,pulse", "elm");
+   else
+     edje_object_signal_emit(wd->progressbar, "elm,state,fraction", "elm");
+   if (wd->units && !wd->pulse)
+     edje_object_signal_emit(wd->progressbar, "elm,state,units,visible", "elm");
+   else
+     edje_object_signal_emit(wd->progressbar, "elm,state,units,hidden", "elm");
+   if (wd->horizontal)
+     evas_object_size_hint_min_set(wd->spacer, (double)wd->size * elm_widget_scale_get(obj) * _elm_config->scale, 1);
+   else
+     evas_object_size_hint_min_set(wd->spacer, 1, (double)wd->size * elm_widget_scale_get(obj) * _elm_config->scale);
+
+   edje_object_part_swallow(wd->progressbar, "elm.swallow.bar", wd->spacer);
+
+   _units_set(obj);
+   edje_object_message_signal_process(wd->progressbar);
+   edje_object_scale_set(wd->progressbar, elm_widget_scale_get(obj) * _elm_config->scale);
+   _val_set(obj);
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1;
+   if (!wd) return;
+   edje_object_size_min_restricted_calc(wd->progressbar, &minw, &minh, minw, minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (obj != wd->icon) return;
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *sub = event_info;
+   if (!wd) return;
+   if (sub == wd->icon)
+     {
+       edje_object_signal_emit(wd->progressbar, "elm,state,icon,hidden", "elm");
+       evas_object_event_callback_del_full
+         (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
+       wd->icon = NULL;
+       _sizing_eval(obj);
+     }
+}
+
+static void
+_val_set(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   double pos;
+   if (!wd) return;
+   pos = wd->val;
+   if (wd->inverted) pos = MAX_RATIO_LVL - pos;
+   edje_object_part_drag_value_set(wd->progressbar, "elm.cur.progressbar", pos, pos);
+}
+
+static void
+_units_set(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->units)
+     {
+        char buf[1024];
+        snprintf(buf, sizeof(buf), wd->units, 100 * wd->val);
+        edje_object_part_text_set(wd->progressbar, "elm.text.status", buf);
+     }
+   else
+     edje_object_part_text_set(wd->progressbar, "elm.text.status", NULL);
+}
+
+/**
+ * Add a new progressbar to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Progressbar
+ */
+EAPI Evas_Object *
+elm_progressbar_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "progressbar");
+   elm_widget_type_set(obj, "progressbar");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   wd->horizontal = EINA_TRUE;
+   wd->inverted = EINA_FALSE;
+   wd->pulse = EINA_FALSE;
+   wd->pulse_state = EINA_FALSE;
+   wd->units = eina_stringshare_add("%.0f %%");
+   wd->val = MIN_RATIO_LVL;
+
+   wd->progressbar = edje_object_add(e);
+   _elm_theme_object_set(obj, wd->progressbar, "progressbar", "horizontal", "default");
+   elm_widget_resize_object_set(obj, wd->progressbar);
+
+   wd->spacer = evas_object_rectangle_add(e);
+   evas_object_color_set(wd->spacer, 0, 0, 0, 0);
+   evas_object_pass_events_set(wd->spacer, 1);
+   elm_widget_sub_object_add(obj, wd->spacer);
+   edje_object_part_swallow(wd->progressbar, "elm.swallow.bar", wd->spacer);
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+   _units_set(obj);
+   _val_set(obj);
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Normally the progressbar will display and interpret values from low to high.
+ * This display a progressbar for jobs with unknow state of progression,
+ * (the cursor pulse right to left and left to right, and loop) if pulse is set to 1.
+ *
+ * @param obj The progressbar object
+ * @param pulse The pulse flag. 1 == pulse, 0 == normal
+ *
+ * @ingroup Progressbar
+ */
+EAPI void
+elm_progressbar_pulse_set(Evas_Object *obj, Eina_Bool pulse)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   pulse = !!pulse;
+   if (wd->pulse == pulse) return;
+   wd->pulse = pulse;
+   _theme_hook(obj);
+}
+
+/**
+ * Normally the progressbar will display and interpret values from low to high.
+ * This display a progressbar for jobs with unknow state of progression,
+ * (the cursor pulse right to left and left to right, and loop) if pulse is set to 1.
+ *
+ * @param obj The progressbar object
+ * @return The pulse flag
+ * (1 == pulse, 0 == normal)
+ *
+ * @ingroup Progressbar
+ */
+EAPI Eina_Bool
+elm_progressbar_pulse_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->pulse;
+}
+
+/**
+ * Stat/Stop de pulse action
+ *
+ * @param obj The progressbar object
+ * @param state The pulse flag. 1 == start pulse, 0 == stop pulse
+ *
+ * @ingroup Progressbar
+ */
+EAPI void
+elm_progressbar_pulse(Evas_Object *obj, Eina_Bool state)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   state = !!state;
+   if (!wd->pulse && wd->pulse_state == state) return;
+   wd->pulse_state = state;
+   if (wd->pulse_state)
+     edje_object_signal_emit(wd->progressbar, "elm,state,pulse,start", "elm");
+   else
+     edje_object_signal_emit(wd->progressbar, "elm,state,pulse,stop", "elm");
+}
+
+/**
+ * Set the value the progressbar indicates
+ *
+ * @param obj The progressbar object
+ * @param val The fraction value (must be beween 0.0 and 1.0)
+ *
+ * @ingroup Progressbar
+ */
+EAPI void
+elm_progressbar_value_set(Evas_Object *obj, double val)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->val == val) return;
+   wd->val = val;
+   if (wd->val < MIN_RATIO_LVL) wd->val = MIN_RATIO_LVL;
+   if (wd->val > MAX_RATIO_LVL) wd->val = MAX_RATIO_LVL;
+   _val_set(obj);
+   _units_set(obj);
+}
+
+
+/**
+ * Get the value the progressbar has
+ *
+ * @param obj The progressbar object
+ * @return The value of the progressbar
+ *
+ * @ingroup Progressbar
+ */
+EAPI double
+elm_progressbar_value_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0.0;
+   return wd->val;
+}
+
+/**
+ * Set the label of the progressbar
+ *
+ * @param obj The progressbar object
+ * @param label The text label string in UTF-8
+ *
+ * @ingroup Progressbar
+ */
+EAPI void
+elm_progressbar_label_set(Evas_Object *obj, const char *label)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->label, label);
+   if (label)
+     {
+       edje_object_signal_emit(wd->progressbar, "elm,state,text,visible", "elm");
+       edje_object_message_signal_process(wd->progressbar);
+     }
+   else
+     {
+       edje_object_signal_emit(wd->progressbar, "elm,state,text,hidden", "elm");
+       edje_object_message_signal_process(wd->progressbar);
+     }
+   edje_object_part_text_set(wd->progressbar, "elm.text", label);
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the label of the progressbar
+ *
+ * @param obj The progressbar object
+ * @return The text label string in UTF-8
+ *
+ * @ingroup Progressbar
+ */
+EAPI const char *
+elm_progressbar_label_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->label;
+}
+
+/**
+ * Set the icon object of the progressbar object
+ *
+ * Once the icon object is set, it will become a child of the progressbar object and
+ * be deleted when the progressbar object is deleted. If another icon object is set
+ * then the previous one becomes orophaned and will no longer be deleted along
+ * with the progressbar.
+ *
+ * @param obj The progressbar object
+ * @param icon The icon object
+ *
+ * @ingroup Progressbar
+ */
+EAPI void
+elm_progressbar_icon_set(Evas_Object *obj, Evas_Object *icon)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if ((wd->icon != icon) && (wd->icon))
+     elm_widget_sub_object_del(obj, wd->icon);
+   wd->icon = icon;
+   if (icon)
+     {
+       elm_widget_sub_object_add(obj, icon);
+       evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                      _changed_size_hints, obj);
+       edje_object_part_swallow(wd->progressbar, "elm.swallow.content", icon);
+       edje_object_signal_emit(wd->progressbar, "elm,state,icon,visible", "elm");
+       _sizing_eval(obj);
+     }
+}
+
+/**
+ * Get the icon object of the progressbar object
+ *
+ * @param obj The progressbar object
+ * @return The icon object
+ *
+ * @ingroup Progressbar
+ */
+EAPI Evas_Object *
+elm_progressbar_icon_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->icon;
+}
+
+/**
+ * Set the length of the progression region of the progressbar
+ *
+ * This sets the minimum width or height (depending on orientation) of the
+ * area of the progressbar that allows the progressbar to be dragged around. This in
+ * turn affects the objects minimum size (along with icon label and unit
+ * text).
+ *
+ * @param obj The progressbar object
+ * @param size The length of the progressbar area
+ *
+ * @ingroup Progressbar
+ */
+EAPI void
+elm_progressbar_span_size_set(Evas_Object *obj, Evas_Coord size)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->size == size) return;
+   wd->size = size;
+   if (wd->horizontal)
+     evas_object_size_hint_min_set(wd->spacer, (double)wd->size * elm_widget_scale_get(obj) * _elm_config->scale, 1);
+   else
+     evas_object_size_hint_min_set(wd->spacer, 1, (double)wd->size * elm_widget_scale_get(obj) * _elm_config->scale);
+   edje_object_part_swallow(wd->progressbar, "elm.swallow.bar", wd->spacer);
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the length of the progression region of the progressbar
+ *
+ * @param obj The progressbar object
+ * @return The length of the progressbar area
+ *
+ * @ingroup Progressbar
+ */
+EAPI Evas_Coord
+elm_progressbar_span_size_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   return wd->size;
+}
+
+/**
+ * Set the format string of the unit area
+ *
+ * If NULL, this disabls the unit area display. If not it sets the format
+ * string for the unit text. The unit text is provided a floating point
+ * value, so the unit text can display up to 1 floating point falue. Note that
+ * this is optional. Use a format string such as "%1.2f meters" for example.
+ *
+ * @param obj The progressbar object
+ * @param units The format string for the units display
+ *
+ * @ingroup Progressbar
+ */
+EAPI void
+elm_progressbar_unit_format_set(Evas_Object *obj, const char *units)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->units, units);
+   if (units)
+     {
+       edje_object_signal_emit(wd->progressbar, "elm,state,units,visible", "elm");
+       edje_object_message_signal_process(wd->progressbar);
+     }
+   else
+     {
+       edje_object_signal_emit(wd->progressbar, "elm,state,units,hidden", "elm");
+       edje_object_message_signal_process(wd->progressbar);
+     }
+   _units_set(obj);
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the format string of the unit area
+ *
+ * @param obj The progressbar object
+ * @return The format string for the units display
+ *
+ * @ingroup Progressbar
+ */
+EAPI const char *
+elm_progressbar_unit_format_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->units;
+}
+
+/**
+ * Set orientation of the progressbar
+ *
+ * @param obj The progressbar object
+ * @param horizontal If set, the progressbar will be horizontal
+ *
+ * @ingroup Progressbar
+ */
+EAPI void
+elm_progressbar_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   horizontal = !!horizontal;
+   if (wd->horizontal == horizontal) return;
+   wd->horizontal = horizontal;
+   _theme_hook(obj);
+}
+
+/**
+ * Gets orientation of the progressbar
+ *
+ * @param obj The progressbar object
+ * @return The orientation
+ * (0 = vertical, 1 = horizontal)
+ *
+ * @ingroup Progressbar
+ */
+EAPI Eina_Bool
+elm_progressbar_horizontal_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->horizontal;
+}
+
+/**
+ * Invert the progressbar display
+ *
+ * Normally the progressbar will display and interpret values from low to high
+ * and when horizontal that is left to right. When vertical that is top
+ * to bottom. This inverts this (so from right to left or bottom to top) if
+ * inverted is set to 1.
+ *
+ * @param obj The progressbar object
+ * @param inverted The inverted flag. 1 == inverted, 0 == normal
+ *
+ * @ingroup Progressbar
+ */
+EAPI void
+elm_progressbar_inverted_set(Evas_Object *obj, Eina_Bool inverted)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   inverted = !!inverted;
+   if (wd->inverted == inverted) return;
+   wd->inverted = inverted;
+   if (wd->inverted)
+     edje_object_signal_emit(wd->progressbar, "elm,state,inverted,on", "elm");
+   else
+     edje_object_signal_emit(wd->progressbar, "elm,state,inverted,off", "elm");
+   edje_object_message_signal_process(wd->progressbar);
+   _val_set(obj);
+   _units_set(obj);
+}
+
+/**
+ * Gets if the progressbar will displayed inverted
+ *
+ * @param obj The progressbar object
+ * @return The inverted flag
+ * (1 == inverted, 0 == normal)
+ *
+ * @ingroup Progressbar
+ */
+EAPI Eina_Bool
+elm_progressbar_inverted_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->inverted;
+}
diff --git a/src/lib/elm_radio.c b/src/lib/elm_radio.c
new file mode 100644 (file)
index 0000000..bcc2dda
--- /dev/null
@@ -0,0 +1,481 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Radio Radio
+ *
+ * The radio button allows for 1 or more selectors to be created to select 1
+ * of a set of options.
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * changed - This is called whenever the user changes the state of one of the
+ * radio objects within the group of radio objects that work together.
+ *
+ * A radio object contains an indicator, an optional Label and an optional
+ * icon object. They work normally in groups of 2 or more. When you create a
+ * radio (if it is not the first member of the group), simply add it to the
+ * group by adding it to any other member of the group that already exists
+ * (or the first member) with elm_radio_group_add() with the second parameter
+ * being the existing group member. The radio object(s) will select from one
+ * of a set of integer values, so any value they are configuring needs to be
+ * mapped to a set of integers. To configure what value that radio object
+ * represents, use  elm_radio_state_value_set() to set the integer it
+ * represents. To set the value the whole group is to indicate use
+ * elm_radio_value_set() on any group member, and to get the groups value use
+ * elm_radio_value_get(). For convenience the radio objects are also able to
+ * directly set an integer (int) to the value that is selected. To specify
+ * the pointer to this integer to modify, use elm_radio_value_pointer_set().
+ * The radio objects will modify this directly. That implies the pointer must
+ * point to valid memory for as long as the radio objects exist.
+ */
+
+typedef struct _Widget_Data Widget_Data;
+typedef struct _Group Group;
+
+struct _Group
+{
+   int value;
+   int *valuep;
+   Eina_List *radios;
+};
+
+struct _Widget_Data
+{
+   Evas_Object *chk;
+   Evas_Object *icon;
+   int value;
+   const char *label;
+   Eina_Bool state;
+   Group *group;
+};
+
+static const char *widtype = NULL;
+static void _state_set(Evas_Object *obj, Eina_Bool state);
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _disable_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+static void _signal_radio_on(void *data, Evas_Object *obj, const char *emission, const char *source);
+
+static const char SIG_CHANGED[] = "changed";
+static const Evas_Smart_Cb_Description _signals[] = {
+  {SIG_CHANGED, ""},
+  {NULL, NULL}
+};
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->label) eina_stringshare_del(wd->label);
+   wd->group->radios = eina_list_remove(wd->group->radios, obj);
+   if (!wd->group->radios) free(wd->group);
+   wd->group = NULL;
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _elm_theme_object_set(obj, wd->chk, "radio", "base", elm_widget_style_get(obj));
+   if (wd->icon)
+     edje_object_signal_emit(wd->chk, "elm,state,icon,visible", "elm");
+   else
+     edje_object_signal_emit(wd->chk, "elm,state,icon,hidden", "elm");
+   if (wd->state)
+     edje_object_signal_emit(wd->chk, "elm,state,radio,on", "elm");
+   else
+     edje_object_signal_emit(wd->chk, "elm,state,radio,off", "elm");
+   if (wd->label)
+     edje_object_signal_emit(wd->chk, "elm,state,text,visible", "elm");
+   else
+     edje_object_signal_emit(wd->chk, "elm,state,text,hidden", "elm");
+   edje_object_part_text_set(wd->chk, "elm.text", wd->label);
+   edje_object_message_signal_process(wd->chk);
+   edje_object_scale_set(wd->chk, elm_widget_scale_get(obj) * _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+static void
+_disable_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (elm_widget_disabled_get(obj))
+     {
+        edje_object_signal_emit(wd->chk, "elm,state,disabled", "elm");
+        if (wd->state) _state_set(obj, 0);
+     }
+   else
+     edje_object_signal_emit(wd->chk, "elm,state,enabled", "elm");
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1;
+   if (!wd) return;
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   edje_object_size_min_restricted_calc(wd->chk, &minw, &minh, minw, minh);
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (obj != wd->icon) return;
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *sub = event_info;
+   if (!wd) return;
+   if (sub == wd->icon)
+     {
+       edje_object_signal_emit(wd->chk, "elm,state,icon,hidden", "elm");
+       evas_object_event_callback_del_full
+         (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
+       wd->icon = NULL;
+       _sizing_eval(obj);
+     }
+}
+
+static void
+_state_set(Evas_Object *obj, Eina_Bool state)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if ((state != wd->state) && (!elm_widget_disabled_get(obj)))
+     {
+       wd->state = state;
+       if (wd->state)
+         edje_object_signal_emit(wd->chk, "elm,state,radio,on", "elm");
+       else
+         edje_object_signal_emit(wd->chk, "elm,state,radio,off", "elm");
+     }
+}
+
+static void
+_state_set_all(Widget_Data *wd)
+{
+   const Eina_List *l;
+   Evas_Object *child, *selected = NULL;
+   Eina_Bool disabled = EINA_FALSE;
+   EINA_LIST_FOREACH(wd->group->radios, l, child)
+     {
+       Widget_Data *wd2 = elm_widget_data_get(child);
+        if (wd2->state) selected = child;
+       if (wd2->value == wd->group->value)
+          {
+             _state_set(child, 1);
+             if (!wd2->state) disabled = EINA_TRUE;
+          }
+       else _state_set(child, 0);
+     }
+   if (disabled && selected) _state_set(selected, 1);
+}
+
+static void
+_signal_radio_on(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (wd->group->value == wd->value) return;
+   wd->group->value = wd->value;
+   if (wd->group->valuep) *(wd->group->valuep) = wd->group->value;
+   _state_set_all(wd);
+   evas_object_smart_callback_call(data, SIG_CHANGED, NULL);
+}
+
+/**
+  * Add a new radio to the parent
+  *
+  * @param parent The parent object
+  * @return The new object or NULL if it cannot be created
+  *
+  * @ingroup Radio
+  */
+EAPI Evas_Object *
+elm_radio_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "radio");
+   elm_widget_type_set(obj, "radio");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_disable_hook_set(obj, _disable_hook);
+
+   wd->chk = edje_object_add(e);
+   _elm_theme_object_set(obj, wd->chk, "radio", "base", "default");
+   edje_object_signal_callback_add(wd->chk, "elm,action,radio,on", "", _signal_radio_on, obj);
+   edje_object_signal_callback_add(wd->chk, "elm,action,radio,toggle", "", _signal_radio_on, obj);
+   elm_widget_resize_object_set(obj, wd->chk);
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+
+   wd->group = calloc(1, sizeof(Group));
+   wd->group->radios = eina_list_append(wd->group->radios, obj);
+   wd->state = 0;
+
+   _sizing_eval(obj);
+
+   // TODO: convert Elementary to subclassing of Evas_Smart_Class
+   // TODO: and save some bytes, making descriptions per-class and not instance!
+   evas_object_smart_callbacks_descriptions_set(obj, _signals);
+   return obj;
+}
+
+/**
+ * Set the text label of the radio object
+ *
+ * @param obj The radio object
+ * @param label The text label string in UTF-8
+ *
+ * @ingroup Radio
+ */
+EAPI void
+elm_radio_label_set(Evas_Object *obj, const char *label)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->label, label);
+   if (label)
+     {
+       edje_object_signal_emit(wd->chk, "elm,state,text,visible", "elm");
+       edje_object_message_signal_process(wd->chk);
+     }
+   else
+     {
+       edje_object_signal_emit(wd->chk, "elm,state,text,hidden", "elm");
+       edje_object_message_signal_process(wd->chk);
+     }
+   edje_object_part_text_set(wd->chk, "elm.text", label);
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the text label of the radio object
+ *
+ * @param obj The radio object
+ * @return The text label string in UTF-8
+ *
+ * @ingroup Radio
+ */
+EAPI const char *
+elm_radio_label_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->label;
+}
+
+/**
+ * Set the icon object of the radio object
+ *
+ * Once the icon object is set, it will become a child of the radio object and
+ * be deleted when the radio object is deleted. If another icon object is set
+ * then the previous one becomes orophaned and will no longer be deleted along
+ * with the radio.
+ *
+ * @param obj The radio object
+ * @param icon The icon object
+ *
+ * @ingroup Radio
+ */
+EAPI void
+elm_radio_icon_set(Evas_Object *obj, Evas_Object *icon)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if ((wd->icon != icon) && (wd->icon))
+     elm_widget_sub_object_del(obj, wd->icon);
+   wd->icon = icon;
+   if (icon)
+     {
+       elm_widget_sub_object_add(obj, icon);
+       evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                      _changed_size_hints, obj);
+       edje_object_part_swallow(wd->chk, "elm.swallow.content", icon);
+       edje_object_signal_emit(wd->chk, "elm,state,icon,visible", "elm");
+       _sizing_eval(obj);
+     }
+}
+
+/**
+ * Get the icon object of the radio object
+ *
+ * @param obj The radio object
+ * @return The icon object
+ *
+ * @ingroup Radio
+ */
+EAPI Evas_Object *
+elm_radio_icon_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->icon;
+}
+
+/**
+ * Add this radio to a group of other radio objects
+ *
+ * Radio objects work in groups. Each member should have a different integer
+ * value assigned. In order ro have them work as a group, they need to know
+ * about eacthother. This adds the given radio object to the group of which
+ * the group object indicated is a member.
+ *
+ * @param obj The radio object
+ * @param group The object whose group the object is to join
+ *
+ * @ingroup Radio
+ */
+EAPI void
+elm_radio_group_add(Evas_Object *obj, Evas_Object *group)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Widget_Data *wd2 = elm_widget_data_get(group);
+   if (!wd) return;
+   if (!wd2)
+     {
+       if (eina_list_count(wd->group->radios) == 1)
+         return;
+       wd->group->radios = eina_list_remove(wd->group->radios, obj);
+       wd->group = calloc(1, sizeof(Group));
+       wd->group->radios = eina_list_append(wd->group->radios, obj);
+     }
+   else if (wd->group == wd2->group) return;
+   else
+     {
+       wd->group->radios = eina_list_remove(wd->group->radios, obj);
+       if (!wd->group->radios) free(wd->group);
+       wd->group = wd2->group;
+       wd->group->radios = eina_list_append(wd->group->radios, obj);
+     }
+   if (wd->value == wd->group->value) _state_set(obj, 1);
+   else _state_set(obj, 0);
+}
+
+/**
+ * Set the integer value that this radio object represents
+ *
+ * This sets the value of the radio.
+ *
+ * @param obj The radio object
+ * @param value The value to use if this radio object is selected
+ *
+ * @ingroup Radio
+ */
+EAPI void
+elm_radio_state_value_set(Evas_Object *obj, int value)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->value = value;
+   if (wd->value == wd->group->value) _state_set(obj, 1);
+   else _state_set(obj, 0);
+}
+
+/**
+ * Set the value of the radio.
+ *
+ * This sets the value of the radio group and will also set the value if
+ * pointed to, to the value supplied, but will not call any callbacks.
+ *
+ * @param obj The radio object
+ * @param value The value to use for the group
+ *
+ * @ingroup Radio
+ */
+EAPI void
+elm_radio_value_set(Evas_Object *obj, int value)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (value == wd->group->value) return;
+   wd->group->value = value;
+   if (wd->group->valuep) *(wd->group->valuep) = wd->group->value;
+   _state_set_all(wd);
+}
+
+/**
+ * Get the state of the radio object
+ *
+ * @param obj The radio object
+ * @return The integer state
+ *
+ * @ingroup Radio
+ */
+EAPI int
+elm_radio_value_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   return wd->group->value;
+}
+
+/**
+ * Set a convenience pointer to a integer to change
+ *
+ * This sets a pointer to a integer, that, in addition to the radio objects
+ * state will also be modified directly. To stop setting the object pointed
+ * to simply use NULL as the valuep parameter. If valuep is not NULL, then
+ * when this is called, the radio objects state will also be modified to
+ * reflect the value of the integer valuep points to, just like calling
+ * elm_radio_value_set().
+ *
+ * @param obj The radio object
+ * @param valuep Pointer to the integer to modify
+ *
+ * @ingroup Radio
+ */
+EAPI void
+elm_radio_value_pointer_set(Evas_Object *obj, int *valuep)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (valuep)
+     {
+       wd->group->valuep = valuep;
+       if (*(wd->group->valuep) != wd->group->value)
+         {
+            wd->group->value = *(wd->group->valuep);
+            _state_set_all(wd);
+         }
+     }
+   else
+     {
+       wd->group->valuep = NULL;
+     }
+}
diff --git a/src/lib/elm_scrolled_grid.c b/src/lib/elm_scrolled_grid.c
new file mode 100644 (file)
index 0000000..2c69c91
--- /dev/null
@@ -0,0 +1,1563 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Grid Scrolled Grid
+ *
+ * This widget aims to position objects in a grid layout while actually
+ * building only the visible ones, using the same idea as genlist: the user
+ * define a class for each cell, specifying functions that will be called at
+ * object creation and deletion.
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * clicked - The user has double-clicked a cell. The event_info parameter is
+ * the grid cell that was double-clicked.
+ *
+ * selected - The user has made an item selected. The event_info parameter is
+ * the grid cell that was selected.
+ *
+ * unselected - The user has made an item unselected. The event_info parameter
+ * is the grid cell that was unselected.
+ *
+ * realized - This is called when the cell in the grid is created as a real
+ * evas object. event_info is the grid cell that was created. The object may be
+ * deleted at any time, so it is up to the caller to not use the object pointer
+ * from elm_scrolled_grid_cell_object_get() in a way where it may point to
+ * freed objects.
+ *
+ * drag,start,up - Called when the cell in the grid has been dragged (not
+ * scrolled) up.
+ *
+ * drag,start,down - Called when the cell in the grid has been dragged (not
+ * scrolled) down.
+ *
+ * drag,start,left - Called when the cell in the grid has been dragged (not
+ * scrolled) left.
+ *
+ * drag,start,right - Called when the cell in the grid has been dragged (not
+ * scrolled) right.
+ *
+ * drag,stop - Called when the cell in the grid has stopped being dragged.
+ *
+ * drag - Called when the cell in the grid is being dragged.
+ *
+ * scroll - called when the content has been scrolled (moved).
+ *
+ * scroll,drag,start - called when dragging the content has started.
+ *
+ * scroll,drag,stop - called when dragging the content has stopped.
+ *
+ *
+ * A cell in the grid can have 0 or more text labels (they can be regular text
+ * or textblock - that's up to the style to determine), 0 or more icons (which
+ * are simply objects swallowed into the grid cell) and 0 or more boolean states
+ * that can be used for check, radio or other indicators by the edje theme style.
+ * A cell may be one of several styles (Elementary provides 1 by default -
+ * "default", but this can be extended by system or application custom
+ * themes/overlays/extensions).
+ *
+ * In order to implement the ability to add and delete cells on the fly, Grid
+ * implements a class/callback system where the application provides a structure
+ * with information about that type of cell (grid may contain multiple different
+ * cells with different classes, states and styles). Grid will call the functions
+ * in this struct (methods) when a cell is "realized" (that is created
+ * dynamically while scrolling). All objects will simply be deleted when no
+ * longer needed with evas_object_del(). The Elm_Genlist_Item_Class structure
+ * contains the following members:
+ *
+ * cell_style - This is a constant string and simply defines the name of the
+ * cell style. It must be specified and the default should be "default".
+ *
+ * func.label_get - This function is called when an actual cell object is
+ * created. The data parameter is the one passed to elm_scrolled_grid_cell_add()
+ * and related cell creation functions. The obj parameter is the grid object and
+ * the part parameter is the string name of the text part in the edje design that
+ * is listed as one of the possible labels that can be set. This function must
+ * return a strdup'()ed string as the caller will free() it when done.
+ *
+ * func.icon_get - This function is called when an actual item object is
+ * created. The data parameter is the one passed to elm_scrolled_grid_cell_add()
+ * and related cell creation functions. The obj parameter is the grid object and
+ * the part parameter is the string name of the icon part in the edje design that
+ * is listed as one of the possible icons that can be set. This must return NULL
+ * for no object or a valid object. The object will be deleted by grid on
+ * shutdown or when the cell is unrealized.
+ *
+ * func.state_get - This function is called when an actual cell object is
+ * created. The data parameter is the one passed to elm_scrolled_grid_cell_add()
+ * and related cell creation functions. The obj parameter is the grid object and
+ * the part parameter is the string name of th state part in the edje design that
+ * is listed as one of the possible states that can be set. Return 0 for false
+ * and 1 for true. Grid will emit a signal to the edje object with
+ * "elm,state,XXX,active" "elm" when true (the default is false), where XXX is
+ * the name of the part.
+ *
+ * func.del - This is called when elm_scrolled_grid_cell_del() is called on a
+ * cell or elm_scrolled_grid_clear() is called on the grid. This is intended for
+ * use when actual grid cells are deleted, so any backing data attached to the
+ * cell (e.g. its data parameter on creation) can be deleted.
+ *
+ * If the application wants multiple cells to be able to be selected,
+ * elm_scrolled_grid_multi_select_set() can enable this. If the grid is
+ * single-selection only (the default), then elm_scrolled_grid_select_cell_get()
+ * will return the selected cell, if any, or NULL if none is selected. If the
+ * grid is multi-select then elm_scrolled_grid_selected_cells_get() will return a
+ * list (that is only valid as long as no cells are modified (added, deleted,
+ * selected or unselected).
+ *
+ * If a cell changes (state of boolean changes, label or icons change), then use
+ * elm_scrolled_grid_cell_update() to have grid update the cell with the new
+ * state. Grid will re-realize the cell thus call the functions in the
+ * _Elm_Grid_Cell_Class for that cell.
+ *
+ * To programmatically (un)select a cell use elm_scrolled_grid_cell_selected_set().
+ * To get its selected state use elm_scrolled_grid_cell_selected_get(). To make a
+ * cell disabled (unable to be selected and appear differently) use
+ * elm_scrolled_grid_cell_disable_set() to set this and
+ * elm_scrolled_grid_cell_disable_get() to get the disabled state.
+ *
+ * Cells will only call their selection func and callback when first becoming
+ * selected. Any further clicks will do nothing, unless you enable always
+ * select with elm_scrolled_grid_always_select_mode_set(). This means event if
+ * selected, every click will make the selected callbacks be called.
+ * elm_scrolled_grid_no_select_mode_set() will turn off the ability to select
+ * items entirely and they will neither appear selected nor call selected
+ * callback function.
+ *
+ * Remember that you can create new styles and add your own theme augmentation
+ * per application with elm_theme_extension_add(). If you absolutely must have a
+ * specific style that overrides any theme the user or system sets up you can use
+ * elm_theme_overlay_add() to add such a file.
+ *
+ * --
+ * TODO:
+ *  * Handle non-homogeneous objects too.
+ */
+
+typedef struct _Widget_Data Widget_Data;
+typedef struct _Pan Pan;
+
+#define PRELOAD 1
+
+struct _Elm_Grid_Cell
+{
+   Evas_Object *base, *spacer;
+   const Elm_Grid_Cell_Class *gcc;
+   Ecore_Timer *long_timer;
+   Widget_Data *wd;
+   Eina_List *labels, *icons, *states, *icon_objs;
+   const void *data;
+   struct
+     {
+       Evas_Smart_Cb func;
+       const void *data;
+     } func;
+
+   Evas_Coord x, y, dx, dy;
+   int relcount;
+
+   Eina_Bool want_unrealize : 1;
+   Eina_Bool realized : 1;
+   Eina_Bool dragging : 1;
+   Eina_Bool down : 1;
+   Eina_Bool delete_me : 1;
+   Eina_Bool display_only : 1;
+   Eina_Bool disabled : 1;
+   Eina_Bool selected : 1;
+   Eina_Bool hilighted : 1;
+   Eina_Bool walking : 1;
+};
+
+struct _Widget_Data
+{
+   Evas_Object *self, *scr;
+   Evas_Object *pan_smart;
+   Pan *pan;
+   Eina_List *cells;
+   Ecore_Job *calc_job;
+   Eina_List *selected;
+   double align_x, align_y;
+
+   Evas_Coord pan_x, pan_y;
+   Evas_Coord cell_width, cell_height; /* Each cell size */
+   Evas_Coord minw, minh;              /* Total obj size */
+   unsigned int nmax;
+
+   Eina_Bool horizontal : 1;
+   Eina_Bool on_hold : 1;
+   Eina_Bool longpressed : 1;
+   Eina_Bool multi : 1;
+   Eina_Bool no_select : 1;
+   Eina_Bool wasselected : 1;
+   Eina_Bool always_select : 1;
+};
+
+struct _Pan
+{
+   Evas_Object_Smart_Clipped_Data __clipped_data;
+   Widget_Data *wd;
+};
+
+static const char *widtype = NULL;
+static void _sizing_eval(Evas_Object *obj);
+static void _cell_hilight(Elm_Grid_Cell *cell);
+static void _cell_unrealize(Elm_Grid_Cell *cell);
+static void _cell_select(Elm_Grid_Cell *cell);
+static void _cell_unselect(Elm_Grid_Cell *cell);
+
+static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "grid", "base",
+                                       elm_widget_style_get(obj));
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   if (!wd) return;
+   evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->calc_job) ecore_job_del(wd->calc_job);
+   evas_object_del(wd->pan_smart);
+   wd->pan_smart = NULL;
+   elm_scrolled_grid_clear(obj);
+   free(wd);
+}
+
+static void
+_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Elm_Grid_Cell *cell = data;
+   Evas_Event_Mouse_Move *ev = event_info;
+   Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
+
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
+     {
+       if (!cell->wd->on_hold) {
+            cell->wd->on_hold = EINA_TRUE;
+            _cell_unselect(cell);
+       }
+     }
+   if ((cell->dragging) && (cell->down))
+     {
+       if (cell->long_timer)
+         {
+            ecore_timer_del(cell->long_timer);
+            cell->long_timer = NULL;
+         }
+       evas_object_smart_callback_call(cell->wd->self, "drag", cell);
+       return;
+     }
+   if ((!cell->down) || (cell->wd->longpressed))
+     {
+       if (cell->long_timer)
+         {
+            ecore_timer_del(cell->long_timer);
+            cell->long_timer = NULL;
+         }
+       return;
+     }
+   if (!cell->display_only)
+     elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   evas_object_geometry_get(obj, &x, &y, NULL, NULL);
+   x = ev->cur.canvas.x - x;
+   y = ev->cur.canvas.y - y;
+   dx = x - cell->dx;
+   adx = dx;
+   if (adx < 0) adx = -dx;
+   dy = y - cell->dy;
+   ady = dy;
+   if (ady < 0) ady = -dy;
+   minw /= 2;
+   minh /= 2;
+   if ((adx > minw) || (ady > minh))
+     {
+       cell->dragging = 1;
+       if (cell->long_timer)
+         {
+            ecore_timer_del(cell->long_timer);
+            cell->long_timer = NULL;
+         }
+       if (cell->wd->wasselected)
+         _cell_unselect(cell);
+       cell->wd->wasselected = 0;
+       if (dy < 0)
+         {
+            if (ady > adx)
+              evas_object_smart_callback_call(cell->wd->self, "drag,start,up",
+                                              cell);
+            else
+              {
+                 if (dx < 0)
+                   evas_object_smart_callback_call(cell->wd->self,
+                                                   "drag,start,left", cell);
+              }
+         }
+       else
+         {
+            if (ady > adx)
+              evas_object_smart_callback_call(cell->wd->self,
+                                              "drag,start,down", cell);
+            else
+              {
+                 if (dx < 0)
+                   evas_object_smart_callback_call(cell->wd->self,
+                                                   "drag,start,left", cell);
+                 else
+                   evas_object_smart_callback_call(cell->wd->self,
+                                                   "drag,start,right", cell);
+              }
+         }
+     }
+}
+
+static int
+_long_press(void *data)
+{
+   Elm_Grid_Cell *cell = data;
+
+   cell->long_timer = NULL;
+   if ((cell->disabled) || (cell->dragging)) return 0;
+   cell->wd->longpressed = EINA_TRUE;
+   evas_object_smart_callback_call(cell->wd->self, "longpressed", cell);
+   return 0;
+}
+
+static void
+_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Elm_Grid_Cell *cell = data;
+   Evas_Event_Mouse_Down *ev = event_info;
+   Evas_Coord x, y;
+
+   if (ev->button != 1) return;
+   cell->down = 1;
+   cell->dragging = 0;
+   evas_object_geometry_get(obj, &x, &y, NULL, NULL);
+   cell->dx = ev->canvas.x - x;
+   cell->dy = ev->canvas.y - y;
+   cell->wd->longpressed = EINA_FALSE;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) cell->wd->on_hold = EINA_TRUE;
+   else cell->wd->on_hold = EINA_FALSE;
+   cell->wd->wasselected = cell->selected;
+   _cell_hilight(cell);
+   if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
+     evas_object_smart_callback_call(cell->wd->self, "clicked", cell);
+   if (cell->long_timer) ecore_timer_del(cell->long_timer);
+   if (cell->realized)
+     cell->long_timer = ecore_timer_add(1.0, _long_press, cell);
+   else
+     cell->long_timer = NULL;
+}
+
+static void
+_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Elm_Grid_Cell *cell = data;
+   Evas_Event_Mouse_Up *ev = event_info;
+   Eina_Bool dragged = EINA_FALSE;
+
+   if (ev->button != 1) return;
+   cell->down = EINA_FALSE;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) cell->wd->on_hold = EINA_TRUE;
+   else cell->wd->on_hold = EINA_FALSE;
+   if (cell->long_timer)
+     {
+       ecore_timer_del(cell->long_timer);
+       cell->long_timer = NULL;
+     }
+   if (cell->dragging)
+     {
+       cell->dragging = EINA_FALSE;
+       evas_object_smart_callback_call(cell->wd->self, "drag,stop", cell);
+       dragged = EINA_TRUE;
+     }
+   if (cell->wd->on_hold)
+     {
+       cell->wd->longpressed = EINA_FALSE;
+       cell->wd->on_hold = EINA_FALSE;
+       return;
+     }
+   if (cell->wd->longpressed)
+     {
+       cell->wd->longpressed = EINA_FALSE;
+       if (!cell->wd->wasselected)
+         _cell_unselect(cell);
+       cell->wd->wasselected = EINA_FALSE;
+       return;
+     }
+   if (dragged)
+     {
+       if (cell->want_unrealize)
+            _cell_unrealize(cell);
+     }
+   if ((cell->disabled) || dragged) return;
+   if (cell->wd->multi)
+     {
+       if (!cell->selected)
+         {
+            _cell_hilight(cell);
+            _cell_select(cell);
+         }
+       else _cell_unselect(cell);
+     }
+   else
+     {
+       if (!cell->selected)
+         {
+            while (cell->wd->selected) _cell_unselect(cell->wd->selected->data);
+         }
+       else
+         {
+            const Eina_List *l, *l_next;
+            Elm_Grid_Cell *cell2;
+
+            EINA_LIST_FOREACH_SAFE(cell->wd->selected, l, l_next, cell2)
+               if (cell2 != cell) _cell_unselect(cell2);
+         }
+       _cell_hilight(cell);
+       _cell_select(cell);
+     }
+}
+
+static void
+_cell_hilight(Elm_Grid_Cell *cell)
+{
+   if ((cell->wd->no_select) || (cell->delete_me) || (cell->hilighted)) return;
+   edje_object_signal_emit(cell->base, "elm,state,selected", "elm");
+   cell->hilighted = EINA_TRUE;
+}
+
+static void
+_cell_realize(Elm_Grid_Cell *cell)
+{
+   char buf[1024];
+
+   if ((cell->realized) || (cell->delete_me)) return;
+   cell->base = edje_object_add(evas_object_evas_get(cell->wd->self));
+   edje_object_scale_set(cell->base, elm_widget_scale_get(cell->wd->self) *
+                        _elm_config->scale);
+   evas_object_smart_member_add(cell->base, cell->wd->pan_smart);
+   elm_widget_sub_object_add(cell->wd->self, cell->base);
+   _elm_theme_object_set(cell->wd->self, cell->base, "grid", "cell/default",
+                         elm_widget_style_get(cell->wd->self));
+   cell->spacer = evas_object_rectangle_add(evas_object_evas_get(cell->wd->self));
+   evas_object_color_set(cell->spacer, 0, 0, 0, 0);
+   elm_widget_sub_object_add(cell->wd->self, cell->spacer);
+   evas_object_size_hint_min_set(cell->spacer, 2 * _elm_config->scale, 1);
+   edje_object_part_swallow(cell->base, "elm.swallow.pad", cell->spacer);
+
+   if (cell->gcc->func.label_get)
+     {
+       const Eina_List *l;
+       const char *key;
+
+       cell->labels = _elm_stringlist_get(edje_object_data_get(cell->base,
+                                                               "labels"));
+       EINA_LIST_FOREACH(cell->labels, l, key)
+         {
+            char *s = cell->gcc->func.label_get(cell->data, cell->wd->self,
+                                                l->data);
+            if (s)
+              {
+                 edje_object_part_text_set(cell->base, l->data, s);
+                 free(s);
+              }
+         }
+     }
+
+   if (cell->gcc->func.icon_get)
+     {
+       const Eina_List *l;
+       const char *key;
+
+       cell->icons = _elm_stringlist_get(edje_object_data_get(cell->base,
+                                                              "icons"));
+       EINA_LIST_FOREACH(cell->icons, l, key)
+         {
+            Evas_Object *ic = cell->gcc->func.icon_get(cell->data,
+                                                       cell->wd->self,
+                                                       l->data);
+            if (ic)
+              {
+                 cell->icon_objs = eina_list_append(cell->icon_objs, ic);
+                 edje_object_part_swallow(cell->base, key, ic);
+                 evas_object_show(ic);
+                 elm_widget_sub_object_add(cell->wd->self, ic);
+              }
+         }
+     }
+
+   if (cell->gcc->func.state_get)
+     {
+       const Eina_List *l;
+       const char *key;
+
+       cell->states = _elm_stringlist_get(edje_object_data_get(cell->base,
+                                                               "states"));
+       EINA_LIST_FOREACH(cell->states, l, key)
+         {
+            Eina_Bool on = cell->gcc->func.state_get(cell->data,
+                  cell->wd->self, l->data);
+            if (on)
+              {
+                 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
+                 edje_object_signal_emit(cell->base, buf, "elm");
+              }
+         }
+     }
+
+   if (!cell->wd->cell_width && !cell->wd->cell_height)
+     {
+       edje_object_size_min_restricted_calc(cell->base,
+             &cell->wd->cell_width, &cell->wd->cell_height,
+             cell->wd->cell_width, cell->wd->cell_height);
+       elm_coords_finger_size_adjust(1, &cell->wd->cell_width,
+                                     1, &cell->wd->cell_height);
+     }
+
+   evas_object_event_callback_add(cell->base, EVAS_CALLBACK_MOUSE_DOWN,
+                                 _mouse_down, cell);
+   evas_object_event_callback_add(cell->base, EVAS_CALLBACK_MOUSE_UP,
+                                 _mouse_up, cell);
+   evas_object_event_callback_add(cell->base, EVAS_CALLBACK_MOUSE_MOVE,
+                                 _mouse_move, cell);
+
+   if (cell->selected)
+     edje_object_signal_emit(cell->base, "elm,state,selected", "elm");
+   if (cell->disabled)
+     edje_object_signal_emit(cell->base, "elm,state,disabled", "elm");
+
+   evas_object_show(cell->base);
+   cell->realized = EINA_TRUE;
+   cell->want_unrealize = EINA_FALSE;
+}
+
+static void
+_cell_unrealize(Elm_Grid_Cell *cell)
+{
+   Evas_Object *icon;
+
+   if (!cell->realized) return;
+   if (cell->long_timer)
+     {
+       ecore_timer_del(cell->long_timer);
+       cell->long_timer = NULL;
+     }
+   evas_object_del(cell->base);
+   cell->base = NULL;
+   evas_object_del(cell->spacer);
+   cell->spacer = NULL;
+   _elm_stringlist_free(cell->labels);
+   cell->labels = NULL;
+   _elm_stringlist_free(cell->icons);
+   cell->icons = NULL;
+   _elm_stringlist_free(cell->states);
+
+   EINA_LIST_FREE(cell->icon_objs, icon)
+      evas_object_del(icon);
+
+   cell->states = NULL;
+   cell->realized = EINA_FALSE;
+   cell->want_unrealize = EINA_FALSE;
+}
+
+static void
+_cell_place(Elm_Grid_Cell *cell, Evas_Coord cx, Evas_Coord cy)
+{
+   Evas_Coord x, y, ox, oy, cvx, cvy, cvw, cvh;
+   Evas_Coord tch, tcw, alignw = 0, alignh = 0, vw, vh;
+
+   cell->x = cx;
+   cell->y = cy;
+   evas_object_geometry_get(cell->wd->self, &ox, &oy, &vw, &vh);
+   evas_output_viewport_get(evas_object_evas_get(cell->wd->self),
+                           &cvx, &cvy, &cvw, &cvh);
+
+   /* Preload rows/columns at each side of the Grid */
+   cvx -= PRELOAD * cell->wd->cell_width;
+   cvy -= PRELOAD * cell->wd->cell_height;
+   cvw += 2 * PRELOAD * cell->wd->cell_width;
+   cvh += 2 * PRELOAD * cell->wd->cell_height;
+
+   tch = ((vh/cell->wd->cell_height)*cell->wd->cell_height);
+   alignh = (vh - tch)*cell->wd->align_y;
+
+   tcw = ((vw/cell->wd->cell_width)*cell->wd->cell_width);
+   alignw = (vw - tcw)*cell->wd->align_x;
+
+   if (cell->wd->horizontal && cell->wd->minw < vw)
+     {
+        int columns;
+
+        columns = eina_list_count(cell->wd->cells)/(vh/cell->wd->cell_height);
+        if (eina_list_count(cell->wd->cells) % (vh/cell->wd->cell_height))
+             columns++;
+
+        tcw = cell->wd->cell_width * columns;
+       alignw = (vw - tcw)*cell->wd->align_x;
+     }
+   else if (cell->wd->horizontal && cell->wd->minw > vw)
+        alignw = 0;   
+   if (!cell->wd->horizontal && cell->wd->minh < vh)
+     {
+        int rows;
+
+        rows = eina_list_count(cell->wd->cells)/(vw/cell->wd->cell_width);
+        if (eina_list_count(cell->wd->cells) % (vw/cell->wd->cell_width))
+             rows++;
+
+        tch = cell->wd->cell_height * rows;
+        alignh = (vh - tch)*cell->wd->align_y;
+     }
+   else if (!cell->wd->horizontal && cell->wd->minh > vh)
+        alignh = 0;
+   x = cx * cell->wd->cell_width - cell->wd->pan_x + ox + alignw;
+   y = cy * cell->wd->cell_height - cell->wd->pan_y + oy + alignh;
+
+   if (ELM_RECTS_INTERSECT(x, y, cell->wd->cell_width, cell->wd->cell_height,
+                          cvx, cvy, cvw, cvh))
+     {
+       Eina_Bool was_realized = cell->realized;
+       _cell_realize(cell);
+       if (!was_realized)
+         evas_object_smart_callback_call(cell->wd->self, "realized", cell);
+       evas_object_move(cell->base, x, y);
+       evas_object_resize(cell->base, cell->wd->cell_width,
+                          cell->wd->cell_height);
+     }
+   else
+     _cell_unrealize(cell);
+}
+
+static Elm_Grid_Cell *
+_cell_create(Widget_Data *wd, const Elm_Grid_Cell_Class *gcc,
+      const void *data, Evas_Smart_Cb func, const void *func_data)
+{
+   Elm_Grid_Cell *cell;
+
+   cell = calloc(1, sizeof(*cell));
+   if (!cell) return NULL;
+   cell->wd = wd;
+   cell->gcc = gcc;
+   cell->data = data;
+   cell->func.func = func;
+   cell->func.data = func_data;
+   return cell;
+}
+
+static void
+_cell_del(Elm_Grid_Cell *cell)
+{
+   if (cell->selected)
+     cell->wd->selected = eina_list_remove(cell->wd->selected, cell);
+   if (cell->realized) _cell_unrealize(cell);
+   if ((!cell->delete_me) && (cell->gcc->func.del))
+     cell->gcc->func.del(cell->data, cell->wd->self);
+   cell->delete_me = EINA_TRUE;
+   cell->wd->cells = eina_list_remove(cell->wd->cells, cell);
+   if (cell->long_timer) ecore_timer_del(cell->long_timer);
+   free(cell);
+}
+
+static void
+_cell_select(Elm_Grid_Cell *cell)
+{
+   if ((cell->wd->no_select) || (cell->delete_me)) return;
+   if (cell->selected)
+     {
+       if (cell->wd->always_select) goto call;
+       return;
+     }
+   cell->selected = EINA_TRUE;
+   cell->wd->selected = eina_list_append(cell->wd->selected, cell);
+call:
+   cell->walking++;
+   if (cell->func.func) cell->func.func((void *)cell->func.data, cell->wd->self,
+                                       cell);
+   if (!cell->delete_me)
+     evas_object_smart_callback_call(cell->wd->self, "selected", cell);
+   cell->walking--;
+   if ((cell->walking == 0) && (cell->delete_me))
+     if (cell->relcount == 0) _cell_del(cell);
+}
+
+static void
+_cell_unselect(Elm_Grid_Cell *cell)
+{
+   if ((cell->delete_me) || (!cell->hilighted)) return;
+   edje_object_signal_emit(cell->base, "elm,state,unselected", "elm");
+   cell->hilighted = EINA_FALSE;
+   if (cell->selected)
+     {
+       cell->selected = EINA_FALSE;
+       cell->wd->selected = eina_list_remove(cell->wd->selected, cell);
+       evas_object_smart_callback_call(cell->wd->self, "unselected", cell);
+     }
+}
+
+static void
+_calc_job(void *data)
+{
+   Widget_Data *wd = data;
+   Evas_Coord minw = 0, minh = 0, nmax = 0, cvw, cvh;
+   int count;
+
+   evas_output_viewport_get(evas_object_evas_get(wd->self), NULL, NULL,
+                           &cvw, &cvh);
+   if (wd->horizontal && wd->cell_height)
+     nmax = cvh / wd->cell_height;
+   else if (wd->cell_width)
+     nmax = cvw / wd->cell_width;
+
+   if (nmax)
+     {
+       count = eina_list_count(wd->cells);
+       if (wd->horizontal)
+         {
+            minw = ceil(count  / (float)nmax) * wd->cell_width;
+            minh = nmax * wd->cell_height;
+         }
+       else
+         {
+            minw = nmax * wd->cell_width;
+            minh = ceil(count / (float)nmax) * wd->cell_height;
+         }
+     }
+
+   if ((minw != wd->minw) || (minh != wd->minh))
+     {
+       wd->minh = minh;
+       wd->minw = minw;
+       evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
+       _sizing_eval(wd->self);
+     }
+
+   wd->nmax = nmax;
+   wd->calc_job = NULL;
+   evas_object_smart_changed(wd->pan_smart);
+}
+
+static void
+_pan_add(Evas_Object *obj)
+{
+   Pan *sd;
+   Evas_Object_Smart_Clipped_Data *cd;
+
+   _pan_sc.add(obj);
+   cd = evas_object_smart_data_get(obj);
+   sd = ELM_NEW(Pan);
+   if (!sd) return;
+   sd->__clipped_data = *cd;
+   free(cd);
+   evas_object_smart_data_set(obj, sd);
+}
+
+static void
+_pan_del(Evas_Object *obj)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+
+   if (!sd) return;
+   _pan_sc.del(obj);
+}
+
+static void
+_pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
+   sd->wd->pan_x = x;
+   sd->wd->pan_y = y;
+   evas_object_smart_changed(obj);
+}
+
+static void
+_pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   if (x) *x = sd->wd->pan_x;
+   if (y) *y = sd->wd->pan_y;
+}
+
+static void
+_pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   if (w) *w = sd->wd->minw;
+   if (h) *h = sd->wd->minh;
+}
+
+static void
+_pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   Evas_Coord ow, oh;
+
+   if (!sd) return;
+   evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
+   if (x)
+     *x = (ow < sd->wd->minw) ? sd->wd->minw - ow : 0;
+   if (y)
+     *y = (oh < sd->wd->minh) ? sd->wd->minh - oh : 0;
+}
+
+static void
+_pan_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   Evas_Coord ow, oh;
+
+   evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
+   if ((ow == w) && (oh == h)) return;
+   if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
+   sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
+}
+
+static void
+_pan_calculate(Evas_Object *obj)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   Evas_Coord cx = 0, cy = 0;
+   Eina_List *l;
+   Elm_Grid_Cell *cell;
+
+   if (!sd) return;
+   if (!sd->wd->nmax) return;
+
+   EINA_LIST_FOREACH(sd->wd->cells, l, cell)
+     {
+       _cell_place(cell, cx, cy);
+       if (sd->wd->horizontal)
+         {
+            cy = (cy + 1) % sd->wd->nmax;
+            if (!cy) cx++;
+         }
+       else
+         {
+            cx = (cx + 1) % sd->wd->nmax;
+            if (!cx) cy++;
+         }
+     }
+}
+
+static void
+_pan_move(Evas_Object *obj, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__)
+{
+   Pan *sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
+   sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
+}
+
+static void
+_hold_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_hold_set(wd->scr, 1);
+}
+
+static void
+_hold_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_hold_set(wd->scr, 0);
+}
+
+static void
+_freeze_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_freeze_set(wd->scr, 1);
+}
+
+static void
+_freeze_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_freeze_set(wd->scr, 0);
+}
+
+static void
+_scr_drag_start(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, "scroll,drag,start", NULL);
+}
+
+static void
+_scr_drag_stop(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, "scroll,drag,stop", NULL);
+}
+
+static void
+_scr_scroll(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, "scroll", NULL);
+}
+
+/**
+ * Add a new Scrolled Grid object.
+ *
+ * @param parent The parent object.
+ * @return  The new object or NULL if it cannot be created.
+ *
+ * @see elm_scrolled_grid_cell_size_set()
+ * @see elm_scrolled_grid_horizontal_set()
+ * @see elm_scrolled_grid_cell_add()
+ * @see elm_scrolled_grid_cell_del()
+ * @see elm_scrolled_grid_clear()
+ *
+ * @ingroup Grid
+ */
+EAPI Evas_Object *
+elm_scrolled_grid_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Evas_Coord minw, minh;
+   Widget_Data *wd;
+   static Evas_Smart *smart = NULL;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "grid");
+   elm_widget_type_set(obj, "grid");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   wd->scr = elm_smart_scroller_add(e);
+   elm_smart_scroller_widget_set(wd->scr, obj);
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "grid", "base", "default");
+   elm_widget_resize_object_set(obj, wd->scr);
+
+   evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
+   evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
+   evas_object_smart_callback_add(wd->scr, "scroll", _scr_scroll, obj);
+
+   elm_smart_scroller_bounce_allow_set(wd->scr, 1, 1);
+
+   wd->self = obj;
+   wd->align_x = 0.5;
+   wd->align_y = 0.5;
+
+   evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
+   evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
+   evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
+   evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
+
+   if (!smart)
+     {
+       static Evas_Smart_Class sc;
+
+       evas_object_smart_clipped_smart_set(&_pan_sc);
+       sc = _pan_sc;
+       sc.name = "elm_scrolled_grid_pan";
+       sc.version = EVAS_SMART_CLASS_VERSION;
+       sc.add = _pan_add;
+       sc.del = _pan_del;
+       sc.resize = _pan_resize;
+       sc.move = _pan_move;
+       sc.calculate = _pan_calculate;
+       smart = evas_smart_class_new(&sc);
+     }
+   if (smart)
+     {
+       wd->pan_smart = evas_object_smart_add(e, smart);
+       wd->pan = evas_object_smart_data_get(wd->pan_smart);
+       wd->pan->wd = wd;
+     }
+
+   elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
+                                    _pan_set, _pan_get,
+                                    _pan_max_get, _pan_child_size_get);
+
+   _sizing_eval(obj);
+
+   return obj;
+}
+
+/**
+ * Set the size for the cell of the Grid.
+ *
+ * @param obj The Grid object.
+ * @param w The cell's width.
+ * @param h The cell's height;
+ *
+ * @see elm_scrolled_grid_cell_size_get()
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_cell_size_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->cell_width == w && wd->cell_height == h) return;
+   wd->cell_width = w;
+   wd->cell_height = h;
+   if (wd->calc_job) ecore_job_del(wd->calc_job);
+   wd->calc_job = ecore_job_add(_calc_job, wd);
+}
+
+/**
+ * Get the size of the cell of the Grid.
+ *
+ * @param obj The Grid object.
+ * @param w Pointer to the cell's width.
+ * @param h Pointer to the cell's height.
+ *
+ * @see elm_scrolled_grid_cell_size_get()
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_cell_size_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (w) *w = wd->cell_width;
+   if (h) *h = wd->cell_height;
+}
+
+/**
+ * Set cell's alignment within the scroller.
+ *
+ * @param obj The grid object.
+ * @param align_x The x alignment (0 <= x <= 1).
+ * @param align_y The y alignment (0 <= y <= 1).
+ *
+ * @see elm_scrolled_grid_align_get()
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_align_set(Evas_Object *obj, double align_x, double align_y)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (align_x > 1.0)
+     align_x = 1.0;
+   else if (align_x < 0.0)
+     align_x = 0.0;
+   wd->align_x = align_x;
+
+   if (align_y > 1.0)
+     align_y = 1.0;
+   else if (align_y < 0.0)
+     align_y = 0.0;
+   wd->align_y = align_y;
+}
+
+/**
+ * Get the alignenment set for the grid object.
+ *
+ * @param obj The grid object.
+ * @param align_x Pointer to x alignenment.
+ * @param align_y Pointer to y alignenment.
+ *
+ * @see elm_scrolled_grid_align_set()
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_align_get(const Evas_Object *obj, double *align_x, double *align_y)
+{
+    ELM_CHECK_WIDTYPE(obj, widtype);
+    Widget_Data *wd = elm_widget_data_get(obj);
+    if (align_x) *align_x = wd->align_x;
+    if (align_y) *align_y = wd->align_y;
+}
+
+/**
+ * Add cell to the end of the Grid.
+ *
+ * @param obj The Grid object.
+ * @param gcc The cell class for the cell.
+ * @param data The cell data.
+ * @param func Convenience function called when cell is selected.
+ * @param func_data Data passed to @p func above.
+ * @return A handle to the cell added or NULL if not possible.
+ *
+ * @see elm_scrolled_grid_cell_del()
+ *
+ * @ingroup Grid
+ */
+EAPI Elm_Grid_Cell *
+elm_scrolled_grid_cell_add(Evas_Object *obj, const Elm_Grid_Cell_Class *gcc,
+                          const void *data, Evas_Smart_Cb func,
+                          const void *func_data)
+{
+   Elm_Grid_Cell *cell;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+
+   cell = _cell_create(wd, gcc, data, func, func_data);
+   if (!cell) return NULL;
+
+   wd->cells = eina_list_append(wd->cells, cell);
+   wd->no_select = EINA_FALSE;
+
+   if (wd->calc_job) ecore_job_del(wd->calc_job);
+   wd->calc_job = ecore_job_add(_calc_job, wd);
+
+   return cell;
+}
+
+/**
+ * Remove a cell from the Grid.
+ *
+ * @param cell The cell to be removed.
+ * @return @c EINA_TRUE on success or @c EINA_FALSE otherwise.
+ *
+ * @see elm_scrolled_grid_clear() to remove all cells of the grid.
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_cell_del(Elm_Grid_Cell *cell)
+{
+   if (!cell) return;
+   if ((cell->relcount > 0) || (cell->walking > 0))
+     {
+       cell->delete_me = EINA_TRUE;
+       if (cell->selected)
+         cell->wd->selected = eina_list_remove(cell->wd->selected, cell);
+       if (cell->gcc->func.del) cell->gcc->func.del(cell->data, cell->wd->self);
+       return;
+     }
+
+   _cell_del(cell);
+
+   if (cell->wd->calc_job) ecore_job_del(cell->wd->calc_job);
+   cell->wd->calc_job = ecore_job_add(_calc_job, cell->wd);
+}
+
+/**
+ * Set for what direction the grid will expand.
+ *
+ * @param obj The Grid object.
+ * @param setting If @c EINA_TRUE the grid will expand horizontally or
+ * vertically if @c EINA_FALSE.
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_horizontal_set(Evas_Object *obj, Eina_Bool setting)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (setting == wd->horizontal) return;
+   wd->horizontal = setting;
+
+   /* Update the cells to conform to the new layout */
+   if (wd->calc_job) ecore_job_del(wd->calc_job);
+   wd->calc_job = ecore_job_add(_calc_job, wd);
+}
+
+/**
+ * Clear the Grid
+ *
+ * This clears all cells in the grid, leaving it empty.
+ *
+ * @param obj The Grid object.
+ *
+ * @see elm_scrolled_grid_cell_del() to remove just one cell.
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_clear(Evas_Object *obj)
+{
+   Eina_List *l, *l_next;
+   Elm_Grid_Cell *cell;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   if (wd->calc_job)
+     {
+       ecore_job_del(wd->calc_job);
+       wd->calc_job = NULL;
+     }
+
+   EINA_LIST_FOREACH_SAFE(wd->cells, l, l_next, cell)
+     {
+       if (cell->realized) _cell_unrealize(cell);
+       if (cell->gcc->func.del) cell->gcc->func.del(cell->data, wd->self);
+       if (cell->long_timer) ecore_timer_del(cell->long_timer);
+       free(cell);
+       wd->cells = eina_list_remove_list(wd->cells, l);
+     }
+
+   if (wd->selected)
+     {
+       eina_list_free(wd->selected);
+       wd->selected = NULL;
+     }
+
+   wd->pan_x = 0;
+   wd->pan_y = 0;
+   wd->minw = 0;
+   wd->minh = 0;
+   evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
+   evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the real evas object of the grid cell
+ *
+ * This returns the actual evas object used for the specified grid cell.
+ * This may be NULL as it may not be created, and may be deleted at any time
+ * by grid. Do not modify this object (move, resize, show, hide etc.) as grid
+ * is controlling it. This function is for querying, emitting custom signals
+ * or hooking lower level callbacks for events. Do not delete this object
+ * under any circumstances.
+ *
+ * @param cell The Grid cell.
+ * @return the evas object associated to this cell.
+ *
+ * @see elm_scrolled_grid_cell_data_get()
+ *
+ * @ingroup Grid
+ */
+EAPI const Evas_Object *
+elm_scrolled_grid_cell_object_get(Elm_Grid_Cell *cell)
+{
+   if (!cell) return NULL;
+   return cell->base;
+}
+
+/**
+ * Returns the data associated to a cell
+ *
+ * This returns the data value passed on the elm_scrolled_grid_cell_add() and
+ * related cell addition calls.
+ *
+ * @param cell The Grid cell.
+ * @return the data associated to this cell.
+ *
+ * @see elm_scrolled_grid_cell_add()
+ * @see elm_scrolled_grid_cell_object_get()
+ *
+ * @ingroup Grid
+ */
+EAPI void *
+elm_scrolled_grid_cell_data_get(Elm_Grid_Cell *cell)
+{
+   if (!cell) return NULL;
+   return (void *)cell->data;
+}
+
+/**
+ * Get the cell's coordinates.
+ *
+ * This returns the logical position of the cell whithin the Grid.
+ *
+ * @param cell The Grid cell.
+ * @param x The x-axis coordinate pointer.
+ * @param y The y-axis coordinate pointer.
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_cell_pos_get(const Elm_Grid_Cell *cell, unsigned int *x, unsigned int *y)
+{
+   if (!cell) return;
+   if (x) *x = cell->x;
+   if (y) *y = cell->y;
+}
+
+/**
+ * Enable or disable multi-select in the grid.
+ *
+ * This enables (EINA_TRUE) or disables (EINA_FALSE) multi-select in the grid.
+ * This allows more than 1 cell to be selected.
+ *
+ * @param obj The grid object.
+ * @param multi Multi-select enabled/disabled
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_multi_select_set(Evas_Object *obj, Eina_Bool multi)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->multi = multi;
+}
+
+/**
+ * Get if multi-select in grid is enabled or disabled
+ *
+ * @param obj The grid object
+ * @return Multi-select enable/disable
+ * (EINA_TRUE = enabled / EINA_FALSE = disabled)
+ *
+ * @ingroup Grid
+ */
+EAPI Eina_Bool
+elm_scrolled_grid_multi_select_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->multi;
+}
+
+/**
+ * Get the selected cell in the grid
+ *
+ * This gets the selected cell in the grid (if multi-select is enabled only
+ * the first cell in the list is selected - which is not very useful, so see
+ * elm_scrolled_grid_selected_cells_get() for when multi-select is used).
+ *
+ * If no cell is selected, NULL is returned.
+ *
+ * @param obj The grid object.
+ * @return The selected cell, or NULL if none.
+ *
+ * @ingroup Grid
+ */
+EAPI Elm_Grid_Cell *
+elm_scrolled_grid_selected_cell_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   if (wd->selected) return wd->selected->data;
+   return NULL;
+}
+
+/**
+ * Get a list of selected cells in the grid.
+ *
+ * This returns a list of the selected cells. This list pointer is only valid
+ * so long as no cells are selected or unselected (or unselected implictly by
+ * deletion). The list contains Elm_Grid_Cell pointers.
+ *
+ * @param obj The grid object.
+ * @return The list of selected cells, or NULL if none are selected.
+ *
+ * @ingroup Grid
+ */
+EAPI const Eina_List *
+elm_scrolled_grid_selected_cells_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->selected;
+}
+
+/**
+ * Get the selected state of a cell.
+ *
+ * This gets the selected state of a cell (1 selected, 0 not selected).
+ *
+ * @param cell The cell
+ * @return The selected state
+ *
+ * @ingroup Grid
+ */
+EAPI Eina_Bool
+elm_scrolled_grid_cell_selected_get(const Elm_Grid_Cell *cell)
+{
+   if (!cell) return EINA_FALSE;
+   return cell->selected;
+}
+
+/**
+ * Sets the disabled state of a cell.
+ *
+ * A disabled cell cannot be selected or unselected. It will also change
+ * appearance to disabled. This sets the disabled state (1 disabled, 0 not
+ * disabled).
+ *
+ * @param cell The cell
+ * @param disabled The disabled state
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_cell_disabled_set(Elm_Grid_Cell *cell, Eina_Bool disabled)
+{
+   if (!cell) return;
+   if (cell->disabled == disabled) return;
+   if (cell->delete_me) return;
+   cell->disabled = disabled;
+   if (cell->realized)
+     {
+       if (cell->disabled)
+         edje_object_signal_emit(cell->base, "elm,state,disabled", "elm");
+       else
+         edje_object_signal_emit(cell->base, "elm,state,enabled", "elm");
+     }
+}
+
+/**
+ * Get the disabled state of a cell.
+ *
+ * This gets the disabled state of the given cell.
+ *
+ * @param cell The cell
+ * @return The disabled state
+ *
+ * @ingroup Grid
+ */
+EAPI Eina_Bool
+elm_scrolled_grid_cell_disabled_get(const Elm_Grid_Cell *cell)
+{
+   if (!cell) return EINA_FALSE;
+   if (cell->delete_me) return EINA_FALSE;
+   return cell->disabled;
+}
+
+/**
+ * Set the always select mode.
+ *
+ * Cells will only call their selection func and callback when first becoming
+ * selected. Any further clicks will do nothing, unless you enable always select
+ * with elm_scrolled_grid_always_select_mode_set(). This means even if selected,
+ * every click will make the selected callbacks be called.
+ *
+ * @param obj The grid object
+ * @param always_select The always select mode (EINA_TRUE = on, EINA_FALSE = off)
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_always_select_mode_set(Evas_Object *obj, Eina_Bool always_select)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->always_select = always_select;
+}
+
+/**
+ * Get the always select mode.
+ *
+ * @param obj The grid object.
+ * @return The always select mode (EINA_TRUE = on, EINA_FALSE = off)
+ *
+ * @ingroup Grid
+ */
+EAPI Eina_Bool
+elm_scrolled_grid_always_select_mode_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->always_select;
+}
+
+/**
+ * Set no select mode.
+ *
+ * This will turn off the ability to select items entirely and they will
+ * neither appear selected nor call selected callback functions.
+ *
+ * @param obj The grid object
+ * @param no_select The no select mode (EINA_TRUE = on, EINA_FALSE = off)
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_no_select_mode_set(Evas_Object *obj, Eina_Bool no_select)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->no_select = no_select;
+}
+
+/**
+ * Gets no select mode.
+ *
+ * @param obj The grid object
+ * @return The no select mode (EINA_TRUE = on, EINA_FALSE = off)
+ *
+ * @ingroup Grid
+ */
+EAPI Eina_Bool
+elm_scrolled_grid_no_select_mode_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->no_select;
+}
+
+/**
+ * Set bounce mode.
+ *
+ * This will enable or disable the scroller bounce mode for the grid. See
+ * elm_scroller_bounce_set() for details.
+ *
+ * @param obj The grid object
+ * @param h_bounce Allow bounce horizontally
+ * @param v_bounce Allow bounce vertically
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce);
+}
+
+/**
+ * Get the bounce mode
+ *
+ * @param obj The grid object
+ * @param h_bounce Allow bounce horizontally
+ * @param v_bounce Allow bounce vertically
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_smart_scroller_bounce_allow_get(wd->scr, h_bounce, v_bounce);
+}
diff --git a/src/lib/elm_scroller.c b/src/lib/elm_scroller.c
new file mode 100644 (file)
index 0000000..2c365c8
--- /dev/null
@@ -0,0 +1,653 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Scroller Scroller
+ *
+ * A scroller holds a single object and "scrolls it around". This means that
+ * it allows the user to use a scrollbar (or a finger) to drag the viewable
+ * region around, allowing to move through a much larger object that is
+ * contained in the scroller. The scroiller will always have a small minimum
+ * size by default as it won't be limited by the contents of the scroller.
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * edge,left - the left edge of the content has been reached
+ *
+ * edge,right - the right edge of the content has been reached
+ *
+ * edge,top - the top edge of the content has been reached
+ *
+ * edge,bottom - the bottom edge of the content has been reached
+ *
+ * scroll - the content has been scrolled (moved)
+ *
+ * scroll,anim,start - scrolling animation has started
+ *
+ * scroll,anim,stop - scrolling animation has stopped
+ *
+ * scroll,drag,start - dragging the contents around has started
+ *
+ * scroll,drag,stop - dragging the contents around has stopped
+ */
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *scr;
+   Evas_Object *content;
+   const char *widget_name, *widget_base;
+   Eina_Bool min_w : 1;
+   Eina_Bool min_h : 1;
+   double pagerel_h, pagerel_v;
+   Evas_Coord pagesize_h, pagesize_v;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _show_region_hook(void *data, Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+
+static const char SIG_SCROLL[] = "scroll";
+static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
+static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
+static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
+static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
+static const char SIG_EDGE_LEFT[] = "edge,left";
+static const char SIG_EDGE_RIGHT[] = "edge,right";
+static const char SIG_EDGE_TOP[] = "edge,top";
+static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
+static const Evas_Smart_Cb_Description _signals[] = {
+  {SIG_SCROLL, ""},
+  {SIG_SCROLL_ANIM_START, ""},
+  {SIG_SCROLL_ANIM_STOP, ""},
+  {SIG_SCROLL_DRAG_START, ""},
+  {SIG_SCROLL_DRAG_STOP, ""},
+  {SIG_EDGE_LEFT, ""},
+  {SIG_EDGE_RIGHT, ""},
+  {SIG_EDGE_TOP, ""},
+  {SIG_EDGE_BOTTOM, ""},
+  {NULL, NULL}
+};
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->scr)
+     {
+        elm_smart_scroller_object_theme_set(obj, wd->scr, 
+                                            wd->widget_name, wd->widget_base,
+                                            elm_widget_style_get(obj));
+//        edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
+     }
+   _sizing_eval(obj);
+}
+
+static void
+_show_region_hook(void *data, Evas_Object *obj)
+{
+   
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Coord x, y, w, h;
+   if (!wd) return;
+   elm_widget_show_region_get(obj, &x, &y, &w, &h);
+   if (wd->scr)
+     elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord  vw, vh, minw, minh, maxw, maxh, w, h, vmw, vmh;
+   double xw, yw;
+
+   if (!wd) return;
+   evas_object_size_hint_min_get(wd->content, &minw, &minh);
+   evas_object_size_hint_max_get(wd->content, &maxw, &maxh);
+   evas_object_size_hint_weight_get(wd->content, &xw, &yw);
+   if (wd->scr)
+     {
+        elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
+        if (xw > 0.0)
+          {
+             if ((minw > 0) && (vw < minw)) vw = minw;
+             else if ((maxw > 0) && (vw > maxw)) vw = maxw;
+          }
+        else if (minw > 0) vw = minw;
+        if (yw > 0.0)
+          {
+             if ((minh > 0) && (vh < minh)) vh = minh;
+             else if ((maxh > 0) && (vh > maxh)) vh = maxh;
+          }
+        else if (minh > 0) vh = minh;
+        evas_object_resize(wd->content, vw, vh);
+        w = -1;
+        h = -1;
+        edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
+        if (wd->min_w) w = vmw + minw;
+        if (wd->min_h) h = vmh + minh;
+        evas_object_size_hint_min_set(obj, w, h);
+     }
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *sub = event_info;
+
+   if (!wd) return;
+   if (sub == wd->content)
+     {
+       elm_widget_on_show_region_hook_set(wd->content, NULL, NULL);
+       evas_object_event_callback_del_full (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+           _changed_size_hints, obj);
+       wd->content = NULL;
+       _sizing_eval(obj);
+     }
+   else if (sub == wd->scr)
+     wd->scr = NULL;
+}
+
+static void
+_hold_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   if (wd->scr)
+     elm_smart_scroller_hold_set(wd->scr, 1);
+}
+
+static void
+_hold_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   if (wd->scr)
+     elm_smart_scroller_hold_set(wd->scr, 0);
+}
+
+static void
+_freeze_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   if (wd->scr)
+     elm_smart_scroller_freeze_set(wd->scr, 1);
+}
+
+static void
+_freeze_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   if (wd->scr)
+     elm_smart_scroller_freeze_set(wd->scr, 0);
+}
+
+static void
+_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+}
+
+static void
+_edge_left(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_EDGE_LEFT, NULL);
+}
+
+static void
+_edge_right(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_EDGE_RIGHT, NULL);
+}
+
+static void
+_edge_top(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_EDGE_TOP, NULL);
+}
+
+static void
+_edge_bottom(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_EDGE_BOTTOM, NULL);
+}
+
+static void
+_scroll(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_SCROLL, NULL);
+}
+
+static void
+_scroll_anim_start(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
+}
+
+static void
+_scroll_anim_stop(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
+}
+
+static void
+_scroll_drag_start(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
+}
+
+static void
+_scroll_drag_stop(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
+}
+
+/**
+ * Add a new scroller to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Scroller
+ */
+EAPI Evas_Object *
+elm_scroller_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+   Evas_Coord minw, minh;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "scroller");
+   elm_widget_type_set(obj, "scroller");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   wd->widget_name = eina_stringshare_add("scroller");
+   wd->widget_base = eina_stringshare_add("base");
+   
+   wd->scr = elm_smart_scroller_add(e);
+   elm_smart_scroller_widget_set(wd->scr, obj);
+   elm_smart_scroller_object_theme_set(obj, wd->scr, 
+                                       wd->widget_name, wd->widget_base,
+                                       elm_widget_style_get(obj));
+   elm_widget_resize_object_set(obj, wd->scr);
+   evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                 _changed_size_hints, obj);
+
+   edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr), &minw, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+   evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
+   evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
+   evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
+   evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
+
+   evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
+   evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
+   evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
+   evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
+   evas_object_smart_callback_add(wd->scr, "scroll", _scroll, obj);
+   evas_object_smart_callback_add(wd->scr, "animate,start", _scroll_anim_start, obj);
+   evas_object_smart_callback_add(wd->scr, "animate,stop", _scroll_anim_stop, obj);
+   evas_object_smart_callback_add(wd->scr, "drag,start", _scroll_drag_start, obj);
+   evas_object_smart_callback_add(wd->scr, "drag,stop", _scroll_drag_stop, obj);
+
+   _sizing_eval(obj);
+
+   // TODO: convert Elementary to subclassing of Evas_Smart_Class
+   // TODO: and save some bytes, making descriptions per-class and not instance!
+   evas_object_smart_callbacks_descriptions_set(obj, _signals);
+   return obj;
+}
+
+
+/**
+ * Set the content object
+ *
+ * Sets the content of the scroller (the object to be scrolled around)
+ *
+ * @param obj The scroller object
+ * @param content The new content object
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+elm_scroller_content_set(Evas_Object *obj, Evas_Object *content)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if ((wd->content != content) && (wd->content))
+     elm_widget_sub_object_del(obj, wd->content);
+   wd->content = content;
+   if (content)
+     {
+       elm_widget_on_show_region_hook_set(content, _show_region_hook, obj);
+       elm_widget_sub_object_add(obj, content);
+        if (wd->scr)
+          elm_smart_scroller_child_set(wd->scr, content);
+       evas_object_event_callback_add(content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                      _changed_size_hints, obj);
+       _sizing_eval(obj);
+     }
+}
+
+/**
+ * Set custom theme elements for the scroller
+ * 
+ * @param obj The scroller object
+ * @param widget The widget name to use (default is "scroller")
+ * @param base The base name to use (default is "base")
+ */
+EAPI void
+elm_scroller_custom_widget_base_theme_set(Evas_Object *obj, const char *widget, const char *base)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if ((!widget) || (!base)) return;
+   if (eina_stringshare_replace(&wd->widget_name, widget) |
+       eina_stringshare_replace(&wd->widget_base, base))
+     _theme_hook(obj);
+}
+
+/**
+ * Make the scroller minimum size limited to the minimum size of the content
+ *
+ * By default the scroller will be as small as its design allows, irrespective
+ * of its content. This will make the scroller minimum size the right size
+ * horizontally and/or vertically to perfectly fit its content.
+ *
+ * @param obj The scroller object
+ * @param w Enable limiting minimum size horizontally
+ * @param h Enable limiting minimum size vertically
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+elm_scroller_content_min_limit(Evas_Object *obj, Eina_Bool w, Eina_Bool h)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->min_w = w;
+   wd->min_h = h;
+   _sizing_eval(obj);
+}
+
+/**
+ * Show a specific virtual region within the scroller content object
+ *
+ * This will ensure all (or part if it does not fit) of the designated
+ * region in the virtual content object (0, 0 starting at the top-left of the
+ * virtual content object) is shown within the scroller.
+ *
+ * @param obj The scroller object
+ * @param x X coordinate of the region
+ * @param y Y coordinate of the region
+ * @param w Width of the region
+ * @param h Height of the region
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+elm_scroller_region_show(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->scr)
+     elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
+}
+
+/**
+ * Set the scroller scrollbar policy
+ *
+ * This sets the scrollbar visibility policy for the given scroller.
+ * ELM_SMART_SCROLLER_POLICY_AUTO means the scrollber is made visible if it
+ * is needed, and otherwise kept hidden. ELM_SMART_SCROLLER_POLICY_ON turns
+ * it on all the time, and ELM_SMART_SCROLLER_POLICY_OFF always keeps it off.
+ * This applies respectively for the horizontal and vertical scrollbars.
+ *
+ * @param obj The scroller object
+ * @param policy_h Horizontal scrollbar policy
+ * @param policy_v Vertical scrollbar policy
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+elm_scroller_policy_set(Evas_Object *obj, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   const Elm_Scroller_Policy map[3] =
+     {
+       ELM_SMART_SCROLLER_POLICY_AUTO,
+         ELM_SMART_SCROLLER_POLICY_ON,
+         ELM_SMART_SCROLLER_POLICY_OFF
+     };
+   if (!wd) return;
+   if ((policy_h >= 3) || (policy_v >= 3)) return;
+   if (wd->scr)
+     elm_smart_scroller_policy_set(wd->scr, map[policy_h], map[policy_v]);
+}
+
+EAPI void
+elm_scroller_policy_get(const Evas_Object *obj, Elm_Scroller_Policy *policy_h, Elm_Scroller_Policy *policy_v)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
+   if (!wd) return;
+   if (wd->scr)
+     elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
+   *policy_h = (Elm_Scroller_Policy) s_policy_h;
+   *policy_v = (Elm_Scroller_Policy) s_policy_v;
+}
+
+/**
+ * Get the currently visible content region
+ *
+ * This gets the current region in the content object that is visible through
+ * the scroller. Also see elm_scroller_region_show(). The region co-ordinates
+ * are returned in the @p x, @p y, @p w, @p h values pointed to.
+ *
+ * @param obj The scroller object
+ * @param x X coordinate of the region
+ * @param y Y coordinate of the region
+ * @param w Width of the region
+ * @param h Height of the region
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+elm_scroller_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->scr)
+     {
+        if ((x) && (y)) elm_smart_scroller_child_pos_get(wd->scr, x, y);
+        if ((w) && (h)) elm_smart_scroller_child_viewport_size_get(wd->scr, w, h);
+     }
+}
+
+/**
+ * Get the size of the content child object
+ *
+ * This gets the size of the child object of the scroller. Actually the
+ * content of a scroller doesn't specifically need to be an actual object
+ * as it can be virtual and defined purely by callbacks.
+ *
+ * @param obj The scroller object
+ * @param w Width return
+ * @param h Height return
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+elm_scroller_child_size_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   evas_object_geometry_get(wd->content, NULL, NULL, w, h);
+}
+
+/**
+ * Set bouncing behavior
+ *
+ * When scrolling, the scroller may "bounce" when reaching an edge of the child
+ * object. This is a visual way to indicate the end has been reached. This is
+ * enabled by default for both axes. This will set if it is enabled for that
+ * axis with the boolean parameers for each axis.
+ *
+ * @param obj The scroller object
+ * @param h_bounce Will the scroller bounce horizontally or not
+ y Y coordinate of the region
+ w Width of the region
+ h Height of the region
+
+ EAPI void elm_scroller_region_show ( Evas_Object *  obj, * @param v_bounce Will the scroller bounce vertically or not
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+elm_scroller_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->scr)
+     elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce);
+}
+
+/**
+ * Set scroll page size relative to viewport size
+ *
+ * The scroller is sapale of limiting scrolling by the user to "pages". That
+ * is to jump by and only show a "whole page" at a time as if the continuous
+ * area of the scroller conent is split into page sized pieces. This sets
+ * the size of a page relative to the viewport of the scroller. 1.0 is "1
+ * viewport" is size (horizontally or vertically). 0.0 turns it off in that
+ * axis. This is mutually exclusive with page size
+ * (see elm_scroller_page_size_set()  for more information). likewise 0.5
+ * is "half a viewport". Sane usable valus are normally between 0.0 and 1.0
+ * including 1.0. If you only want 1 axis to be page "limited", use 0.0 for
+ * the other axis.
+ *
+ * @param obj The scroller object
+ * @param h_pagerel The horizontal page relative size
+ * @param v_pagerel The vertical page relative size
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+elm_scroller_page_relative_set(Evas_Object *obj, double h_pagerel, double v_pagerel)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->pagerel_h = h_pagerel;
+   wd->pagerel_v = v_pagerel;
+   if (wd->scr)
+     elm_smart_scroller_paging_set(wd->scr, wd->pagerel_h, wd->pagerel_v,
+                                   wd->pagesize_h, wd->pagesize_v);
+}
+
+/**
+ * Set scroll page size
+ *
+ * See also elm_scroller_page_relative_set(). This, instead of a page size
+ * being relaive to the viewport, sets it to an absolute fixed value, with
+ * 0 turning it off for that axis.
+ *
+ * @param obj The scroller object
+ * @param h_pagesize The horizontal page size
+ * @param v_pagesize The vertical page size
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+elm_scroller_page_size_set(Evas_Object *obj, Evas_Coord h_pagesize, Evas_Coord v_pagesize)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->pagesize_h = h_pagesize;
+   wd->pagesize_v = v_pagesize;
+   if (wd->scr)
+     elm_smart_scroller_paging_set(wd->scr, wd->pagerel_h, wd->pagerel_v,
+                                   wd->pagesize_h, wd->pagesize_v);
+}
+
+/**
+ * Show a specific virtual region within the scroller content object
+ *
+ * This will ensure all (or part if it does not fit) of the designated
+ * region in the virtual content object (0, 0 starting at the top-left of the
+ * virtual content object) is shown within the scroller. Unlike
+ * elm_scroller_region_show(), this allow the scroller to "smoothly slide"
+ * to this location (if configuration in general calls for transitions). It
+ * may not jump immediately to the new location and make take a while and
+ * show other content along the way.
+ *
+ * @param obj The scroller object
+ * @param x X coordinate of the region
+ * @param y Y coordinate of the region
+ * @param w Width of the region
+ * @param h Height of the region
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+elm_scroller_region_bring_in(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->scr)
+     elm_smart_scroller_region_bring_in(wd->scr, x, y, w, h);
+}
diff --git a/src/lib/elm_separator.c b/src/lib/elm_separator.c
new file mode 100644 (file)
index 0000000..5796fee
--- /dev/null
@@ -0,0 +1,127 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Separator Separator
+ *
+ * A separator is a widget that adds a very thin object to separate other objects.
+ * A separator can be vertical or horizontal.
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *sep;
+   Eina_Bool horizontal;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->horizontal)
+     _elm_theme_object_set(obj, wd->sep, "separator", "horizontal", elm_widget_style_get(obj));
+   else
+     _elm_theme_object_set(obj, wd->sep, "separator", "vertical", elm_widget_style_get(obj));
+   edje_object_scale_set(wd->sep, elm_widget_scale_get(obj) * _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   if (!wd) return;
+   edje_object_size_min_calc(wd->sep, &minw, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+   evas_object_size_hint_align_set(obj, maxw, maxh);
+}
+
+/**
+ * Add a separator object to @p parent
+ *
+ * @param parent The parent object
+ *
+ * @return The separator object, or NULL upon failure
+ *
+ * @ingroup Separator
+ */
+EAPI Evas_Object *
+elm_separator_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "separator");
+   wd->horizontal = EINA_FALSE;
+   elm_widget_type_set(obj, "separator");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_can_focus_set(obj, 0);
+
+   wd->sep = edje_object_add(e);
+   _elm_theme_object_set(obj, wd->sep, "separator", "vertical", "default");
+   elm_widget_resize_object_set(obj, wd->sep);
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Set the horizontal mode of a separator object
+ *
+ * @param obj The separator object
+ * @param horizontal If true, the separator is horizontal
+ *
+ * @ingroup Separator
+ */
+EAPI void
+elm_separator_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   horizontal = !!horizontal;
+   if (wd->horizontal == horizontal) return;
+   wd->horizontal = horizontal;
+   _theme_hook(obj);
+}
+
+/**
+ * Get the horizontal mode of a separator object
+ *
+ * @param obj The separator object
+ * @return If true, the separator is horizontal
+ *
+ * @ingroup Separator
+ */
+EAPI Eina_Bool
+elm_separator_horizontal_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->horizontal;
+}
diff --git a/src/lib/elm_slider.c b/src/lib/elm_slider.c
new file mode 100644 (file)
index 0000000..5b4693c
--- /dev/null
@@ -0,0 +1,792 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Slider Slider
+ *
+ * The slider adds a dragable “slider” widget for selecting the value of
+ * something within a range.
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * changed - Whenever the slider value is changed by the user.
+ *
+ * delay,changed - A short time after the value is changed by the user.
+ * This will be called only when the user stops dragging for a very short
+ * period or when they release their finger/mouse, so it avoids possibly
+ * expensive reactions to the value change.
+ *
+ * slider,drag,start - dragging the slider indicator around has started
+ *
+ * slider,drag,stop - dragging the slider indicator around has stopped
+ *
+ * A slider can be horizontal or vertical. It can contain an Icon and has a
+ * primary label as well as a units label (that is formatted with floating
+ * point values and thus accepts a printf-style format string, like
+ * “%1.2f units”. There is also an indicator string that may be somewhere
+ * else (like on the slider itself) that also accepts a format string like
+ * units. Label, Icon Unit and Indicator strings/objects are optional.
+ *
+ * A slider may be inverted which means values invert, with high vales being
+ * on the left or top and low values on the right or bottom (as opposed to
+ * normally being low on the left or top and high on the bottom and right).
+ *
+ * The slider should have its minimum and maximum values set by the
+ * application with  elm_slider_min_max_set() and value should also be set by
+ * the application before use with  elm_slider_value_set(). The span of the
+ * slider is its length (horizontally or vertically). This will be scaled by
+ * the object or applications scaling factor. At any point code can query the
+ * slider for its value with elm_slider_value_get().
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *slider;
+   Evas_Object *icon;
+   Evas_Object *spacer;
+   const char *label;
+   const char *units;
+   const char *indicator;
+   const char *(*indicator_format_func)(double val);
+   Eina_Bool horizontal : 1;
+   Eina_Bool inverted : 1;
+   double val, val_min, val_max;
+   Ecore_Timer *delay;
+   Evas_Coord size;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+static void _units_set(Evas_Object *obj);
+static void _indicator_set(Evas_Object *obj);
+
+static const char SIG_CHANGED[] = "changed";
+static const char SIG_DELAY_CHANGED[] = "delay,changed";
+static const char SIG_DRAG_START[] = "slider,drag,start";
+static const char SIG_DRAG_STOP[] = "slider,drag,stop";
+static const Evas_Smart_Cb_Description _signals[] = {
+  {SIG_CHANGED, ""},
+  {SIG_DELAY_CHANGED, ""},
+  {SIG_DRAG_START, ""},
+  {SIG_DRAG_STOP, ""},
+  {NULL, NULL}
+};
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->label) eina_stringshare_del(wd->label);
+   if (wd->indicator) eina_stringshare_del(wd->units);
+   if (wd->delay) ecore_timer_del(wd->delay);
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->horizontal)
+     _elm_theme_object_set(obj, wd->slider, "slider", "horizontal", elm_widget_style_get(obj));
+   else
+     _elm_theme_object_set(obj, wd->slider, "slider", "vertical", elm_widget_style_get(obj));
+   if (wd->inverted)
+     edje_object_signal_emit(wd->slider, "elm,state,inverted,on", "elm");
+   else
+     edje_object_signal_emit(wd->slider, "elm,state,inverted,off", "elm");
+   if (wd->icon)
+     edje_object_signal_emit(wd->slider, "elm,state,icon,visible", "elm");
+   else
+     edje_object_signal_emit(wd->slider, "elm,state,icon,hidden", "elm");
+   if (wd->label)
+     edje_object_signal_emit(wd->slider, "elm,state,text,visible", "elm");
+   else
+     edje_object_signal_emit(wd->slider, "elm,state,text,hidden", "elm");
+   edje_object_part_text_set(wd->slider, "elm.text", wd->label);
+   if (wd->units)
+     edje_object_signal_emit(wd->slider, "elm,state,units,visible", "elm");
+   else
+     edje_object_signal_emit(wd->slider, "elm,state,units,hidden", "elm");
+   if (wd->horizontal)
+     evas_object_size_hint_min_set(wd->spacer, (double)wd->size * elm_widget_scale_get(obj) * _elm_config->scale, 1);
+   else
+     evas_object_size_hint_min_set(wd->spacer, 1, (double)wd->size * elm_widget_scale_get(obj) * _elm_config->scale);
+   edje_object_part_swallow(wd->slider, "elm.swallow.bar", wd->spacer);
+   _units_set(obj);
+   edje_object_message_signal_process(wd->slider);
+   edje_object_scale_set(wd->slider, elm_widget_scale_get(obj) * _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{   
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   if (!wd) return;
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   edje_object_size_min_restricted_calc(wd->slider, &minw, &minh, minw, minh);
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (obj != wd->icon) return;
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *sub = event_info;
+   if (!wd) return;
+   if (sub == wd->icon)
+     {
+       edje_object_signal_emit(wd->slider, "elm,state,icon,hidden", "elm");
+       evas_object_event_callback_del_full
+         (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
+       wd->icon = NULL;
+       _sizing_eval(obj);
+     }
+}
+
+static int
+_delay_change(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return 0;
+   wd->delay = NULL;
+   evas_object_smart_callback_call(data, SIG_DELAY_CHANGED, NULL);
+   return 0;
+}
+
+static void
+_val_fetch(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   double posx = 0.0, posy = 0.0, pos = 0.0, val;
+   if (!wd) return;
+   edje_object_part_drag_value_get(wd->slider, "elm.dragable.slider",
+                                  &posx, &posy);
+   if (wd->horizontal) pos = posx;
+   else pos = posy;
+   if (wd->inverted) pos = 1.0 - pos;
+   val = (pos * (wd->val_max - wd->val_min)) + wd->val_min;
+   if (val != wd->val)
+     {
+       wd->val = val;
+       evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);
+       if (wd->delay) ecore_timer_del(wd->delay);
+       wd->delay = ecore_timer_add(0.2, _delay_change, obj);
+     }
+}
+
+static void
+_val_set(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   double pos;
+   if (!wd) return;
+   if (wd->val_max > wd->val_min)
+     pos = (wd->val - wd->val_min) / (wd->val_max - wd->val_min);
+   else
+     pos = 0.0;
+   if (pos < 0.0) pos = 0.0;
+   else if (pos > 1.0) pos = 1.0;
+   if (wd->inverted) pos = 1.0 - pos;
+   edje_object_part_drag_value_set(wd->slider, "elm.dragable.slider", pos, pos);
+}
+
+static void
+_units_set(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->units)
+     {
+       char buf[1024];
+
+       snprintf(buf, sizeof(buf), wd->units, wd->val);
+       edje_object_part_text_set(wd->slider, "elm.units", buf);
+     }
+   else
+     edje_object_part_text_set(wd->slider, "elm.units", NULL);
+}
+
+static void
+_indicator_set(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->indicator_format_func)
+     {
+       const char *buf;
+       buf = wd->indicator_format_func(wd->val);
+       edje_object_part_text_set(wd->slider, "elm.indicator", buf);
+     }
+   else if (wd->indicator)
+     {
+       char buf[1024];
+       snprintf(buf, sizeof(buf), wd->indicator, wd->val);
+       edje_object_part_text_set(wd->slider, "elm.indicator", buf);
+     }
+   else
+     edje_object_part_text_set(wd->slider, "elm.indicator", NULL);
+}
+
+static void
+_drag(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   _val_fetch(data);
+   _units_set(data);
+   _indicator_set(data);
+}
+
+static void
+_drag_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   _val_fetch(data);
+   evas_object_smart_callback_call(data, SIG_DRAG_START, NULL);
+   _units_set(data);
+   _indicator_set(data);
+}
+
+static void
+_drag_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   _val_fetch(data);
+   evas_object_smart_callback_call(data, SIG_DRAG_STOP, NULL);
+   _units_set(data);
+   _indicator_set(data);
+}
+
+static void
+_drag_up(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   edje_object_part_drag_step(wd->slider, "elm.dragable.slider", -0.05, -0.05);
+}
+
+static void
+_drag_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   edje_object_part_drag_step(wd->slider, "elm.dragable.slider", 0.05, 0.05);
+}
+
+/**
+ * Add a new slider to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Slider
+ */
+EAPI Evas_Object *
+elm_slider_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "slider");
+   elm_widget_type_set(obj, "slider");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   wd->horizontal = EINA_TRUE;
+   wd->val = 0.0;
+   wd->val_min = 0.0;
+   wd->val_max = 1.0;
+
+   wd->slider = edje_object_add(e);
+   _elm_theme_object_set(obj, wd->slider, "slider", "horizontal", "default");
+   elm_widget_resize_object_set(obj, wd->slider);
+   edje_object_signal_callback_add(wd->slider, "drag", "*", _drag, obj);
+   edje_object_signal_callback_add(wd->slider, "drag,start", "*", _drag_start, obj);
+   edje_object_signal_callback_add(wd->slider, "drag,stop", "*", _drag_stop, obj);
+   edje_object_signal_callback_add(wd->slider, "drag,step", "*", _drag_stop, obj);
+   edje_object_signal_callback_add(wd->slider, "drag,page", "*", _drag_stop, obj);
+//   edje_object_signal_callback_add(wd->slider, "drag,set", "*", _drag_stop, obj);
+   edje_object_signal_callback_add(wd->slider, "mouse,wheel,0,-1", "*", _drag_up, obj);
+   edje_object_signal_callback_add(wd->slider, "mouse,wheel,0,1", "*", _drag_down, obj);
+   edje_object_part_drag_value_set(wd->slider, "elm.dragable.slider", 0.0, 0.0);
+
+   wd->spacer = evas_object_rectangle_add(e);
+   evas_object_color_set(wd->spacer, 0, 0, 0, 0);
+   evas_object_pass_events_set(wd->spacer, 1);
+   elm_widget_sub_object_add(obj, wd->spacer);
+   edje_object_part_swallow(wd->slider, "elm.swallow.bar", wd->spacer);
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+
+   _sizing_eval(obj);
+
+   // TODO: convert Elementary to subclassing of Evas_Smart_Class
+   // TODO: and save some bytes, making descriptions per-class and not instance!
+   evas_object_smart_callbacks_descriptions_set(obj, _signals);
+   return obj;
+}
+
+/**
+ * Set the label of the slider
+ *
+ * @param obj The slider object
+ * @param label The text label string in UTF-8
+ *
+ * @ingroup Slider
+ */
+EAPI void
+elm_slider_label_set(Evas_Object *obj, const char *label)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->label, label);
+   if (label)
+     {
+       edje_object_signal_emit(wd->slider, "elm,state,text,visible", "elm");
+       edje_object_message_signal_process(wd->slider);
+     }
+   else
+     {
+       edje_object_signal_emit(wd->slider, "elm,state,text,hidden", "elm");
+       edje_object_message_signal_process(wd->slider);
+     }
+   edje_object_part_text_set(wd->slider, "elm.text", label);
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the label of the slider
+ *
+ * @param obj The slider object
+ * @return The text label string in UTF-8
+ *
+ * @ingroup Slider
+ */
+EAPI const char *
+elm_slider_label_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->label;
+}
+
+/**
+ * Set the icon object of the slider object
+ *
+ * Once the icon object is set, it will become a child of the slider object and
+ * be deleted when the slider object is deleted. If another icon object is set
+ * then the previous one becomes orophaned and will no longer be deleted along
+ * with the slider.
+ *
+ * @param obj The slider object
+ * @param icon The icon object
+ *
+ * @ingroup Slider
+ */
+EAPI void
+elm_slider_icon_set(Evas_Object *obj, Evas_Object *icon)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if ((wd->icon != icon) && (wd->icon))
+     elm_widget_sub_object_del(obj, wd->icon);
+   wd->icon = icon;
+   if (icon)
+     {
+       elm_widget_sub_object_add(obj, icon);
+       evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                      _changed_size_hints, obj);
+       edje_object_part_swallow(wd->slider, "elm.swallow.content", icon);
+       edje_object_signal_emit(wd->slider, "elm,state,icon,visible", "elm");
+       _sizing_eval(obj);
+     }
+}
+
+/**
+ * Get the icon object of the slider object
+ *
+ * @param obj The slider object
+ * @return The icon object
+ *
+ * @ingroup Slider
+ */
+EAPI Evas_Object *
+elm_slider_icon_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->icon;
+}
+
+/**
+ * Set the length of the dragable region of the slider
+ *
+ * This sets the minimum width or height (depending on orientation) of the
+ * area of the slider that allows the slider to be dragged around. This in
+ * turn affects the objects minimum size (along with icon label and unit
+ * text). Note that this will also get multiplied by the scale factor.
+ *
+ * @param obj The slider object
+ * @param size The length of the slider area
+ *
+ * @ingroup Slider
+ */
+EAPI void
+elm_slider_span_size_set(Evas_Object *obj, Evas_Coord size)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->size == size) return;
+   wd->size = size;
+   if (wd->horizontal)
+     evas_object_size_hint_min_set(wd->spacer, (double)wd->size * elm_widget_scale_get(obj) * _elm_config->scale, 1);
+   else
+     evas_object_size_hint_min_set(wd->spacer, 1, (double)wd->size * elm_widget_scale_get(obj) * _elm_config->scale);
+   edje_object_part_swallow(wd->slider, "elm.swallow.bar", wd->spacer);
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the length of the dragable region of the slider
+ *
+ * This gets the minimum width or height (depending on orientation) of
+ * the area of the slider that allows the slider to be dragged
+ * around. Note that this will also get multiplied by the scale
+ * factor.
+ *
+ * @param obj The slider object
+ * @return The length of the slider area
+ *
+ * @ingroup Slider
+ */
+EAPI Evas_Coord
+elm_slider_span_size_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   return wd->size;
+}
+
+/**
+ * Set the format string of the unit area
+ *
+ * If NULL, this disabls the unit area display. If not it sets the format
+ * string for the unit text. The unit text is provided a floating point
+ * value, so the unit text can display up to 1 floating point value. Note that
+ * this is optional. Use a format string such as "%1.2f meters" for example.
+ *
+ * @param obj The slider object
+ * @param units The format string for the units display
+ *
+ * @ingroup Slider
+ */
+EAPI void
+elm_slider_unit_format_set(Evas_Object *obj, const char *units)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->units, units);
+   if (units)
+     {
+       edje_object_signal_emit(wd->slider, "elm,state,units,visible", "elm");
+       edje_object_message_signal_process(wd->slider);
+     }
+   else
+     {
+       edje_object_signal_emit(wd->slider, "elm,state,units,hidden", "elm");
+       edje_object_message_signal_process(wd->slider);
+     }
+   _units_set(obj);
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the format string for the unit area
+ *
+ * The slider may also display a value (the value of the slider) somewhere
+ * (for example above the slider knob that is dragged around). This sets the
+ * format string for this. See elm_slider_unit_format_set() for more
+ * information on how this works.
+ *
+ * @param obj The slider object
+ * @return The format string for the unit display.
+ *
+ * @ingroup Slider
+ */
+EAPI const char *
+elm_slider_unit_format_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->units;
+}
+
+/**
+ * Set the format string for the indicator area
+ *
+ * The slider may also display a value (the value of the slider) somewhere
+ * (for example above the slider knob that is dragged around). This sets the
+ * format string for this. See elm_slider_unit_format_set() for more
+ * information on how this works.
+ *
+ * @param obj The slider object
+ * @param indicator The format string for the indicator display
+ *
+ * @ingroup Slider
+ */
+EAPI void
+elm_slider_indicator_format_set(Evas_Object *obj, const char *indicator)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->indicator, indicator);
+   _indicator_set(obj);
+}
+
+/**
+ * Get the format string for the indicator area
+ *
+ * The slider may also display a value (the value of the slider) somewhere
+ * (for example above the slider knob that is dragged around). This sets the
+ * format string for this. See elm_slider_indicator_format_set() for more
+ * information on how this works.
+ *
+ * @param obj The slider object
+ * @return The format string for the indicator display.
+ *
+ * @ingroup Slider
+ */
+EAPI const char *
+elm_slider_indicator_format_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->indicator;
+}
+
+/**
+ * Set orientation of the slider
+ *
+ * @param obj The slider object
+ * @param horizontal If set, the slider will be horizontal
+ *
+ * @ingroup Slider
+ */
+EAPI void
+elm_slider_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   horizontal = !!horizontal;
+   if (wd->horizontal == horizontal) return;
+   wd->horizontal = horizontal;
+   _theme_hook(obj);
+}
+
+/**
+ * Get orientation of the slider
+ *
+ * @param obj The slider object
+ * @return If @c EINA_TRUE the slider will be horizontal, else it is
+ *         vertical.
+ * @ingroup Slider
+ */
+EAPI Eina_Bool
+elm_slider_horizontal_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->horizontal;
+}
+
+/**
+ * Set the minimum and maximum values for the slider
+ *
+ * Maximum mut be greater than minimum.
+ *
+ * @param obj The slider object
+ * @param min The minimum value
+ * @param max The maximum value
+ *
+ * @ingroup Slider
+ */
+EAPI void
+elm_slider_min_max_set(Evas_Object *obj, double min, double max)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if ((wd->val_min == min) && (wd->val_max == max)) return;
+   wd->val_min = min;
+   wd->val_max = max;
+   if (wd->val < wd->val_min) wd->val = wd->val_min;
+   if (wd->val > wd->val_max) wd->val = wd->val_max;
+   _val_set(obj);
+   _units_set(obj);
+   _indicator_set(obj);
+}
+
+/**
+ * Get the minimum and maximum values for the slider
+ *
+ * @param obj The slider object
+ * @param min The pointer to store minimum value, may be @c NULL.
+ * @param max The pointer to store maximum value, may be @c NULL.
+ *
+ * @ingroup Slider
+ */
+EAPI void
+elm_slider_min_max_get(const Evas_Object *obj, double *min, double *max)
+{
+   if (min) *min = 0.0;
+   if (max) *max = 0.0;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (min) *min = wd->val_min;
+   if (max) *max = wd->val_max;
+}
+
+/**
+ * Set the value the slider indicates
+ *
+ * @param obj The slider object
+ * @param val The value (must be beween min and max for the slider)
+ *
+ * @ingroup Slider
+ */
+EAPI void
+elm_slider_value_set(Evas_Object *obj, double val)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->val == val) return;
+   wd->val = val;
+   if (wd->val < wd->val_min) wd->val = wd->val_min;
+   if (wd->val > wd->val_max) wd->val = wd->val_max;
+   _val_set(obj);
+   _units_set(obj);
+   _indicator_set(obj);
+}
+
+/**
+ * Get the value the slider has
+ *
+ * @param obj The slider object
+ * @return The value of the slider
+ *
+ * @ingroup Slider
+ */
+EAPI double
+elm_slider_value_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0.0;
+   return wd->val;
+}
+
+/**
+ * Invert the slider display
+ *
+ * Normally the slider will display and interpret values from low to high
+ * and when horizontal that is left to right. When vertical that is top
+ * to bottom. This inverts this (so from right to left or bottom to top) if
+ * inverted is set to 1.
+ *
+ * @param obj The slider object
+ * @param inverted The inverted flag. 1 == inverted, 0 == normal
+ *
+ * @ingroup Slider
+ */
+EAPI void
+elm_slider_inverted_set(Evas_Object *obj, Eina_Bool inverted)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   inverted = !!inverted;
+   if (wd->inverted == inverted) return;
+   wd->inverted = inverted;
+   if (wd->inverted)
+     edje_object_signal_emit(wd->slider, "elm,state,inverted,on", "elm");
+   else
+     edje_object_signal_emit(wd->slider, "elm,state,inverted,off", "elm");
+   edje_object_message_signal_process(wd->slider);
+   _val_set(obj);
+   _units_set(obj);
+   _indicator_set(obj);
+}
+
+/**
+ * Get if the slider display is inverted (backwards)
+ *
+ * @param obj The slider object
+ * @return If @c EINA_TRUE the slider will be inverted.
+ * @ingroup Slider
+ */
+EAPI Eina_Bool
+elm_slider_inverted_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->inverted;
+}
+
+/**
+ * Set the format function pointer for the inducator area
+ *
+ * Set the callback function to format the indicator string.
+ * See elm_slider_indicator_format_set() for more info on how this works.
+ *
+ * @param obj The slider object
+ * @param indicator The format string for the indicator display
+ * @param func The indicator format function
+ *
+ * @ingroup Slider
+ */
+EAPI void
+elm_slider_indicator_format_function_set(Evas_Object *obj, const char *(*func)(double val))
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->indicator_format_func = func;
+   _indicator_set(obj);
+}
+
diff --git a/src/lib/elm_slideshow.c b/src/lib/elm_slideshow.c
new file mode 100644 (file)
index 0000000..ec734b3
--- /dev/null
@@ -0,0 +1,650 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Slideshow slideshow
+ *
+ * This object display a list of object (generally a list of images) and some actions like
+ * next/previous are used to navigate. The animations are defined in the theme,
+ * consequently new animations can be added without having to update the
+ * applications.
+ *
+ * The slideshow use 2 callbacks to create and delete the objects displayed. When an item
+ * is displayed the function itc->func.get() is called. This function should create the object,
+ * for example the object can be an evas_object_image or a photocam. When a object is no more
+ * displayed the function itc->func.del() is called, the user can delete or hide the object here.
+ * If itc->func.del is NULL the slideshow delete the object with evas_object_del().
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Elm_Slideshow_Item
+{
+   Evas_Object *obj;
+
+   Eina_List *l, *l_built;
+
+   const void *data;
+   const Elm_Slideshow_Item_Class *itc;
+
+   Evas_Object *o;
+};
+
+struct _Widget_Data
+{
+   Evas_Object *slideshow;
+
+   // list of Elm_Slideshow_Item*
+   Eina_List *items;
+   Eina_List *items_built;
+   Elm_Slideshow_Item *current;
+   Elm_Slideshow_Item *previous;
+
+   Eina_List *transitions;
+   const char *transition;
+
+   Ecore_Timer *timer;
+   int timeout;
+   Eina_Bool loop:1;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static int _timer_cb(void *data);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_slideshow_clear(obj);
+   _elm_stringlist_free(wd->transitions);
+   if (wd->timer) ecore_timer_del(wd->timer);
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _elm_theme_object_set(obj, wd->slideshow, "slideshow", "base", "default");
+   edje_object_scale_set(wd->slideshow, elm_widget_scale_get(obj) *
+                         _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1;
+   if (!wd) return;
+   edje_object_size_min_calc(wd->slideshow, &minw, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, minw, minh);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   ;
+}
+
+static void
+_end(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Elm_Slideshow_Item *item;
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   item = wd->previous;
+   if (item && item->o)
+     {
+       edje_object_part_unswallow(NULL, item->o);
+       evas_object_hide(item->o);
+     }
+   wd->previous = NULL;
+
+   item = wd->current;
+   if (!item || !item->o) return;
+
+   edje_object_part_unswallow(NULL, item->o);
+   edje_object_part_swallow(wd->slideshow, "elm.swallow.1", item->o);
+   evas_object_show(item->o);
+}
+
+
+static int
+_timer_cb(void *data)
+{
+   Evas_Object *obj = data;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   wd->timer = NULL;
+   elm_slideshow_next(obj);
+   return 0;
+}
+
+static void
+_item_realize(Elm_Slideshow_Item *item)
+{
+   Elm_Slideshow_Item *_item;
+   Evas_Object *obj = item->obj;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord w, h;
+
+   if (!wd) return;
+   if (!item->o && item->itc->func.get)
+     {
+        item->o = item->itc->func.get((void*)item->data, obj);
+        evas_object_smart_member_add(item->o, obj);
+        item->l_built = eina_list_append(NULL, item);
+        wd->items_built = eina_list_merge(wd->items_built, item->l_built);
+     }
+   else if (item->l_built)
+     wd->items_built = eina_list_demote_list(wd->items_built, item->l_built);
+   
+   //we pre built the next and the previous item
+   evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+   
+   _item = eina_list_data_get(eina_list_prev(item->l));
+   if (!_item && wd->loop)
+     _item = eina_list_data_get(eina_list_last(item->l));
+   if (_item && !_item->o && _item->itc->func.get)
+     {
+       _item->o = _item->itc->func.get((void*)_item->data, obj);
+       evas_object_hide(_item->o);
+       evas_object_resize(_item->o, w, h);
+       evas_object_smart_member_add(_item->o, obj);
+       _item->l_built = eina_list_append(NULL, _item);
+        wd->items_built = eina_list_merge(wd->items_built, _item->l_built);
+     }
+   else if (_item  && _item->l_built)
+     wd->items_built = eina_list_demote_list(wd->items_built, _item->l_built);
+   
+   
+   _item = eina_list_data_get(eina_list_next(item->l));
+   if ( !_item && wd->loop)
+     _item = eina_list_data_get(wd->items);
+   if (_item && !_item->o && _item->itc->func.get)
+     {
+        _item->o = _item->itc->func.get((void*)_item->data, obj);
+        evas_object_hide(_item->o);
+        evas_object_resize(_item->o, w, h);
+        evas_object_smart_member_add(_item->o, obj);
+        _item->l_built = eina_list_append(NULL, _item);
+        wd->items_built = eina_list_merge(wd->items_built, _item->l_built);
+     }
+   else if (_item && _item->l_built)
+     wd->items_built = eina_list_demote_list(wd->items_built, _item->l_built);
+
+   //only the three last items are keep
+   while (eina_list_count(wd->items_built) > 3)
+     {
+       _item = eina_list_data_get(wd->items_built);
+       wd->items_built = eina_list_remove_list(wd->items_built, wd->items_built);
+       if(item->itc->func.del)
+         item->itc->func.del((void*)item->data, _item->o);
+       else
+         evas_object_del(_item->o);
+       _item->o = NULL;
+     }
+}
+
+/**
+ * Add a new slideshow to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Slideshow
+ */
+EAPI Evas_Object *
+elm_slideshow_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "slideshow");
+   elm_widget_type_set(obj, "slideshow");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   wd->current = NULL;
+   wd->previous = NULL;
+
+   wd->slideshow = edje_object_add(e);
+   _elm_theme_object_set(obj, wd->slideshow, "slideshow", "base", "default");
+   elm_widget_resize_object_set(obj, wd->slideshow);
+   evas_object_show(wd->slideshow);
+
+   wd->transitions = _elm_stringlist_get(edje_object_data_get(wd->slideshow, "transitions"));
+   if (eina_list_count(wd->transitions) > 0)
+     wd->transition = eina_stringshare_add(eina_list_data_get(wd->transitions));
+
+   edje_object_signal_callback_add(wd->slideshow, "end", "slideshow", _end, obj);
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Add a object in the list. The object can be a evas object image or a elm photo for example.
+ *
+ * @param obj The slideshow object
+ * @aram itc Callbacks used to create/delete the object. If itc->del.del is NULL, the object will be destroyed with evas_object_del()
+ * @param data Data used by the user to identified the item
+ * @return Returns The slideshow item
+ *
+ * @ingroup Slideshow
+ */
+EAPI Elm_Slideshow_Item*
+elm_slideshow_item_add(Evas_Object *obj, const Elm_Slideshow_Item_Class *itc, const void *data)
+{
+   Elm_Slideshow_Item *item;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return NULL;
+   item = calloc(1, sizeof(Elm_Slideshow_Item));
+   item->data = data;
+   item->itc = itc;
+   item->obj = obj;
+   item->l = eina_list_append(item->l, item);
+
+   wd->items = eina_list_merge(wd->items, item->l);
+
+   if (!wd->current) elm_slideshow_show(item);
+
+   return item;
+}
+
+/**
+ * Go to the item
+ *
+ * @param obj The slideshow object
+ * @param item The item
+ *
+ * @ingroup Slideshow
+ */
+EAPI void
+elm_slideshow_show(Elm_Slideshow_Item *item)
+{
+   Widget_Data *wd = elm_widget_data_get(item->obj);
+   if (!wd) return;
+   if (item == wd->current) return;
+
+   _end(item->obj, item->obj, NULL, NULL);
+
+   wd->previous = wd->current;
+   wd->current = item;
+   _item_realize(item);
+
+   _end(item->obj, item->obj, NULL, NULL);
+}
+
+/**
+ * Go to the next item
+ *
+ * @param obj The slideshow object
+ *
+ * @ingroup Slideshow
+ */
+EAPI void
+elm_slideshow_next(Evas_Object *obj)
+{
+   char buf[1024];
+   Elm_Slideshow_Item *next = NULL;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   
+   if (wd->current)
+     next = eina_list_data_get(eina_list_next(wd->current->l));
+   else
+     next = NULL;
+   
+   if (wd->current && !next && wd->loop)
+     next = eina_list_data_get(wd->items);
+
+   if (!next || next == wd->current) return;
+   
+   _end(obj, obj, NULL, NULL);
+   
+   if (wd->timer) ecore_timer_del(wd->timer);
+   if (wd->timeout > 0)
+     wd->timer = ecore_timer_add(wd->timeout, _timer_cb, obj);
+   
+   _item_realize(next);
+
+   edje_object_part_swallow(wd->slideshow, "elm.swallow.2", next->o);
+   evas_object_show(next->o);
+   
+   snprintf(buf, 1024, "%s,next", wd->transition);
+   edje_object_signal_emit(wd->slideshow, buf, "slideshow");
+
+   wd->previous = wd->current;
+   wd->current = next;
+}
+
+/**
+ * Go to the previous item
+ *
+ * @param obj The slideshow object
+ *
+ * @ingroup Slideshow
+ */
+EAPI void
+elm_slideshow_previous(Evas_Object *obj)
+{
+   char buf[1024];
+   Elm_Slideshow_Item *prev;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+
+   if (wd->current)
+     prev = eina_list_data_get(eina_list_prev(wd->current->l));
+   else
+     prev = NULL;
+
+   if (wd->current && !prev && wd->loop)
+     prev = eina_list_data_get(eina_list_last(wd->items));
+
+   if (!prev ||  prev == wd->current) return;
+
+   _end(obj, obj, NULL, NULL);
+
+   if (wd->timer) ecore_timer_del(wd->timer);
+   if (wd->timeout > 0)
+     wd->timer = ecore_timer_add(wd->timeout, _timer_cb, obj);
+
+   _item_realize(prev);
+   
+   edje_object_part_swallow(wd->slideshow, "elm.swallow.2", prev->o);
+   evas_object_show(prev->o);
+
+   snprintf(buf, 1024, "%s,previous", wd->transition);
+   edje_object_signal_emit(wd->slideshow, buf, "slideshow");
+
+   wd->previous = wd->current;
+   wd->current = prev;
+}
+
+/**
+ * Returns the list of transitions available.
+ *
+ * @param obj The slideshow object
+ * @return Returns the list of transitions (list of char*)
+ *
+ * @ingroup Slideshow
+ */
+const Eina_List *
+elm_slideshow_transitions_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->transitions;
+}
+
+/**
+ * Set the transition to use
+ *
+ * @param obj The slideshow object
+ * @param transition the new transition
+ *
+ * @ingroup Slideshow
+ */
+EAPI void
+elm_slideshow_transition_set(Evas_Object *obj, const char *transition)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->transition, transition);
+}
+
+/**
+ * Returns the transition to use
+ *
+ * @param obj The slideshow object
+ * @return the transition set
+ *
+ * @ingroup Slideshow
+ */
+EAPI const char *
+elm_slideshow_transition_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->transition;
+}
+
+/**
+ * The slideshow can go to the next item automatically after a few seconds.
+ * This method set the timeout to use. A timeout <=0 disable the timer.
+ *
+ * @param obj The slideshow object
+ * @param timeout The new timeout
+ *
+ * @ingroup Slideshow
+ */
+EAPI void
+elm_slideshow_timeout_set(Evas_Object *obj ,int timeout)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->timeout = timeout;
+   if (wd->timer) ecore_timer_del(wd->timer);
+   wd->timer = NULL;
+   if (timeout > 0)
+     wd->timer = ecore_timer_add(timeout, _timer_cb, obj);
+}
+
+/**
+ * Returns the timeout value
+ *
+ * @param obj The slideshow object
+ * @return Returns the timeout
+ *
+ * @ingroup Slideshow
+ */
+EAPI int
+elm_slideshow_timeout_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) -1;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return -1;
+   return wd->timeout;
+}
+
+/**
+ * Set if the first item should follow the last and vice versa
+ *
+ * @param obj The slideshow object
+ * @param loop if EINA_TRUE, the first item will follow the last and vice versa
+ *
+ * @ingroup Slideshow
+ */
+EAPI void
+elm_slideshow_loop_set(Evas_Object *obj, Eina_Bool loop)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->loop = loop;
+}
+
+/**
+ * Return if the first item should follow the last and vice versa
+ *
+ * @param obj The slideshow object
+ * @returns Returns the loop flag
+ *
+ * @ingroup Slideshow
+ */
+EAPI Eina_Bool
+elm_slideshow_loop_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->loop;
+}
+
+/**
+ * Delete all the items
+ *
+ * @param obj The slideshow object
+ *
+ * @ingroup Slideshow
+ */
+EAPI void
+elm_slideshow_clear(Evas_Object *obj)
+{
+   Elm_Slideshow_Item *item;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->previous = NULL;
+   wd->current = NULL;
+   EINA_LIST_FREE(wd->items_built, item)
+     {
+       if (item->itc->func.del)
+         item->itc->func.del((void*)item->data, item->o);
+       else
+         evas_object_del(item->o);
+     }
+
+   EINA_LIST_FREE(wd->items, item)
+     {
+       free(item);
+     }
+}
+
+
+/**
+ * Delete the item
+ *
+ * @param item The slideshow item
+ *
+ * @ingroup Slideshow
+ */
+EAPI void
+elm_slideshow_item_del(Elm_Slideshow_Item *item)
+{
+   if (!item) return;
+   Widget_Data *wd = elm_widget_data_get(item->obj);
+   if (!wd) return;
+   if (wd->previous == item) wd->previous = NULL;
+   if (wd->current == item)
+     {
+       Eina_List *l = eina_list_data_find_list(wd->items, item);
+       Eina_List *l2 = eina_list_next(l);
+       wd->current = NULL;
+       if (!l2)
+         l2 = eina_list_nth_list(wd->items, eina_list_count(wd->items) - 1);
+       if (l2)
+         elm_slideshow_show(eina_list_data_get(l2));
+     }
+   
+   wd->items = eina_list_remove_list(wd->items, item->l);
+   wd->items_built = eina_list_remove_list(wd->items_built, item->l_built);
+
+   if (item->o && item->itc->func.del)
+     item->itc->func.del((void*)item->data, wd->previous->o);
+   else if (item->o)
+     evas_object_del(item->o);
+   free(item);
+}
+
+/**
+ * Returns the list of items
+ * @param obj The slideshow object
+ * @return Returns the list of items (list of Elm_Slideshow_Item).
+ *
+ * @ingroup Slideshow
+ */
+EAPI const Eina_List *
+elm_slideshow_items_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->items;
+}
+
+
+/**
+ * Returns the current item displayed
+ *
+ * @param obj The slideshow object
+ * @return Returns the current item displayed
+ *
+ * @ingroup Slideshow
+ */
+EAPI Elm_Slideshow_Item *
+elm_slideshow_item_current_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->current;
+}
+
+/**
+ * Returns the evas object associated to an item
+ *
+ * @param item The slideshow item
+ * @return Returns the evas object associated to this item
+ *
+ * @ingroup Slideshow
+ */
+EAPI Evas_Object *
+elm_slideshow_item_object_get(Elm_Slideshow_Item * item)
+{
+   if (!item) return NULL;
+   return item->o;
+}
+
+/**
+ * Returns the data associated to an item
+ *
+ * @param item The slideshow item
+ * @return Returns the data associated to this item
+ *
+ * @ingroup Slideshow
+ */
+EAPI void *
+elm_slideshow_item_data_get(Elm_Slideshow_Item * item)
+{
+   if (!item) return NULL;
+   return (void *)item->data;
+}
+
diff --git a/src/lib/elm_spinner.c b/src/lib/elm_spinner.c
new file mode 100644 (file)
index 0000000..564f14a
--- /dev/null
@@ -0,0 +1,814 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+#include <ctype.h>
+
+/**
+ * @defgroup Spinner
+ *
+ * A spinner is a widget which allows the user to increase or decrease
+ * numeric values. By default the spinner will not wrap and has a label
+ * of "%.0f" (just showing the integer value of the double).
+ *
+ * A spinner has a label that is formatted with floating
+ * point values and thus accepts a printf-style format string, like
+ * “%1.2f units”.
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * changed - Whenever the spinner value is changed by the user.
+ *
+ * delay,changed - A short time after the value is changed by the user.
+ * This will be called only when the user stops dragging for a very short
+ * period or when they release their finger/mouse, so it avoids possibly
+ * expensive reactions to the value change.
+ */
+typedef struct _Widget_Data Widget_Data;
+typedef struct _Elm_Spinner_Special_Value Elm_Spinner_Special_Value;
+
+struct _Widget_Data
+{
+   Evas_Object *spinner, *ent;
+   const char *label;
+   double val, val_min, val_max, orig_val, step;
+   double drag_start_pos, spin_speed, interval;
+   Ecore_Timer *delay, *spin;
+   Eina_List *special_values;
+   Eina_Bool wrap : 1;
+   Eina_Bool entry_visible : 1;
+   Eina_Bool dragging : 1;
+   Eina_Bool editable : 1;
+};
+
+struct _Elm_Spinner_Special_Value {
+     double value;
+     const char *label;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _disable_hook(Evas_Object *obj);
+static void _write_label(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+//static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static Eina_Bool _value_set(Evas_Object *obj, double delta);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Elm_Spinner_Special_Value *sv;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->label) eina_stringshare_del(wd->label);
+   if (wd->delay) ecore_timer_del(wd->delay);
+   if (wd->special_values)
+       EINA_LIST_FREE(wd->special_values, sv)
+       {
+           eina_stringshare_del(sv->label);
+           free(sv);
+       }
+   free(wd);
+}
+
+static void
+_disable_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (elm_widget_disabled_get(obj))
+     edje_object_signal_emit(wd->spinner, "elm,state,disabled", "elm");
+   else
+     edje_object_signal_emit(wd->spinner, "elm,state,enabled", "elm");
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _elm_theme_object_set(obj, wd->spinner, "spinner", "base", elm_widget_style_get(obj));
+   edje_object_part_swallow(wd->spinner, "elm.swallow.entry", wd->ent);
+   _write_label(obj);
+   edje_object_message_signal_process(wd->spinner);
+   edje_object_scale_set(wd->spinner, elm_widget_scale_get(obj) * _elm_config->scale);
+   if (elm_widget_focus_get(obj))
+     edje_object_signal_emit(wd->spinner, "elm,action,focus", "elm");
+   else
+     edje_object_signal_emit(wd->spinner, "elm,action,unfocus", "elm");
+   _sizing_eval(obj);
+}
+
+static void
+_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (elm_widget_focus_get(obj))
+     edje_object_signal_emit(wd->spinner, "elm,action,focus", "elm");
+   else
+     edje_object_signal_emit(wd->spinner, "elm,action,unfocus", "elm");
+}
+
+static int
+_delay_change(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return 0;
+   wd->delay = NULL;
+   evas_object_smart_callback_call(data, "delay,changed", NULL);
+   return 0;
+}
+
+static void
+_entry_show(Widget_Data *wd)
+{
+   char buf[32], fmt[32] = "%0.f";
+
+   /* try to construct just the format from given label
+    * completely ignoring pre/post words
+    */
+   if (wd->label)
+     {
+        const char *start = strchr(wd->label, '%');
+        while (start)
+          {
+            /* handle %% */
+            if (start[1] != '%')
+              break;
+            else
+              start = strchr(start + 2, '%');
+          }
+
+        if (start)
+          {
+            const char *itr, *end = NULL;
+            for (itr = start + 1; *itr != '\0'; itr++)
+              {
+                 /* allowing '%d' is quite dangerous, remove it? */
+                 if ((*itr == 'd') || (*itr == 'f'))
+                   {
+                      end = itr + 1;
+                      break;
+                   }
+              }
+
+            if ((end) && ((size_t)(end - start + 1) < sizeof(fmt)))
+              {
+                 memcpy(fmt, start, end - start);
+                 fmt[end - start] = '\0';
+              }
+          }
+     }
+   snprintf(buf, sizeof(buf), fmt, wd->val);
+   elm_entry_entry_set(wd->ent, buf);
+}
+
+static void
+_write_label(Evas_Object *obj)
+{
+   Eina_List *l;
+   Elm_Spinner_Special_Value *sv;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   char buf[1024];
+   if (!wd) return;
+   EINA_LIST_FOREACH(wd->special_values, l, sv)
+      if (sv->value == wd->val)
+       {
+          snprintf(buf, sizeof(buf), "%s", sv->label);
+          goto apply;
+       }
+   if (wd->label)
+     snprintf(buf, sizeof(buf), wd->label, wd->val);
+   else
+     snprintf(buf, sizeof(buf), "%.0f", wd->val);
+
+apply:
+   edje_object_part_text_set(wd->spinner, "elm.text", buf);
+   if (wd->entry_visible) _entry_show(wd);
+}
+
+static Eina_Bool 
+_value_set(Evas_Object *obj, double delta)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   double new_val;
+   if (!wd) return EINA_FALSE;
+   new_val = wd->val + delta;
+   if (wd->wrap)
+     {
+        while (new_val < wd->val_min)
+          new_val = wd->val_max + new_val + 1 - wd->val_min;
+        while (new_val > wd->val_max)
+          new_val = wd->val_min + new_val - wd->val_max;
+     }
+   else
+     {
+        if (new_val < wd->val_min)
+          new_val = wd->val_min;
+        else if (new_val > wd->val_max)
+          new_val = wd->val_max;
+     }
+
+   if (new_val == wd->val) return 0;
+   wd->val = new_val;
+
+   evas_object_smart_callback_call(obj, "changed", NULL);
+   if (wd->delay) ecore_timer_del(wd->delay);
+   wd->delay = ecore_timer_add(0.2, _delay_change, obj);
+
+   return 1;
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1;
+   if (!wd) return;
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   edje_object_size_min_restricted_calc(wd->spinner, &minw, &minh, minw, minh);
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+/*
+static void
+_changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+   _sizing_eval(data);
+}
+*/
+
+static void
+_val_set(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   double pos = 0.0;
+   if (!wd) return;
+   if (wd->val_max > wd->val_min)
+     pos = ((wd->val - wd->val_min) / (wd->val_max - wd->val_min));
+   if (pos < 0.0) pos = 0.0;
+   else if (pos > 1.0) pos = 1.0;
+   edje_object_part_drag_value_set(wd->spinner, "elm.dragable.slider", 
+                                   pos, pos);
+}
+
+static void
+_drag(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   double pos = 0.0, offset, delta;
+   if (!wd) return;
+   if (wd->entry_visible) return;
+   edje_object_part_drag_value_get(wd->spinner, "elm.dragable.slider",
+                                  &pos, NULL);
+   offset = wd->step;
+   delta = (pos - wd->drag_start_pos) * offset;
+   if (_value_set(data, delta)) _write_label(data);
+   wd->drag_start_pos = pos;
+   wd->dragging = 1;
+}
+
+static void
+_drag_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   double pos;
+   if (!wd) return;
+   edje_object_part_drag_value_get(wd->spinner, "elm.dragable.slider",
+                                  &pos, NULL);
+   wd->drag_start_pos = pos;
+}
+
+static void
+_drag_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   wd->drag_start_pos = 0;
+   edje_object_part_drag_value_set(wd->spinner, "elm.dragable.slider", 0.0, 0.0);
+}
+
+static void
+_hide_entry(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   edje_object_signal_emit(wd->spinner, "elm,state,inactive", "elm");
+   wd->entry_visible = 0;
+}
+
+static void
+_reset_value(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _hide_entry(obj);
+   elm_spinner_value_set(obj, wd->orig_val);
+}
+
+static void
+_apply_entry_value(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   const char *str;
+   char *end;
+   double val;
+   
+   if (!wd) return;
+   _hide_entry(obj);
+   str = elm_entry_entry_get(wd->ent);
+   if (!str) return;
+   val = strtod(str, &end);
+   if ((*end != '\0') && (!isspace(*end))) return;
+   elm_spinner_value_set(obj, val);
+}
+
+static void
+_toggle_entry(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (wd->dragging)
+     {
+        wd->dragging = 0;
+        return;
+     }
+   if (elm_widget_disabled_get(data)) return;
+   if (!wd->editable) return;
+   if (wd->entry_visible) _apply_entry_value(data);
+   else
+     {
+        wd->orig_val = wd->val;
+       edje_object_signal_emit(wd->spinner, "elm,state,active", "elm");
+        _entry_show(wd);
+        elm_entry_select_all(wd->ent);
+       elm_widget_focus_set(wd->ent, 1);
+        wd->entry_visible = 1;
+     }
+}
+
+static int
+_spin_value(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return ECORE_CALLBACK_CANCEL;
+   if (_value_set(data, wd->spin_speed)) _write_label(data);
+   wd->interval = wd->interval / 1.05;
+   ecore_timer_interval_set(wd->spin, wd->interval);
+   return ECORE_CALLBACK_RENEW;
+}
+
+static void
+_val_inc_start(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->interval = 0.85;
+   wd->spin_speed = wd->step;
+   if (wd->spin) ecore_timer_del(wd->spin);
+   wd->spin = ecore_timer_add(wd->interval, _spin_value, obj);
+   _spin_value(obj);
+}
+
+static void
+_val_inc_stop(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->interval = 0.85;
+   wd->spin_speed = 0;
+   if (wd->spin) ecore_timer_del(wd->spin);
+   wd->spin = NULL;
+}
+
+static void
+_val_dec_start(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->interval = 0.85;
+   wd->spin_speed = -wd->step;
+   if (wd->spin) ecore_timer_del(wd->spin);
+   wd->spin = ecore_timer_add(wd->interval, _spin_value, obj);
+   _spin_value(obj);
+}
+
+static void
+_val_dec_stop(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->interval = 0.85;
+   wd->spin_speed = 0;
+   if (wd->spin) ecore_timer_del(wd->spin);
+   wd->spin = NULL;
+}
+
+static void
+_button_inc_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (wd->entry_visible)
+     {
+        _reset_value(data);
+        return;
+     }
+   _val_inc_start(data);
+}
+
+static void
+_button_inc_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   _val_inc_stop(data);
+}
+
+static void
+_button_dec_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (wd->entry_visible)
+     {
+        _reset_value(data);
+        return;
+     }
+   _val_dec_start(data);
+}
+
+static void
+_button_dec_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   _val_dec_stop(data);
+}
+
+static void
+_entry_activated(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   _apply_entry_value(data);
+   evas_object_smart_callback_call(data, "changed", NULL);
+   if (wd->delay) ecore_timer_del(wd->delay);
+   wd->delay = ecore_timer_add(0.2, _delay_change, data);
+}
+
+static void
+_entry_event_key_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Evas_Event_Key_Down *ev = event_info;
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
+   if (!strcmp(ev->keyname, "Up")) _val_inc_start(data);
+   else if (!strcmp(ev->keyname, "Down")) _val_dec_start(data);
+}
+
+static void
+_entry_event_key_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Evas_Event_Key_Down *ev = event_info;
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
+   if (!strcmp(ev->keyname, "Up")) _val_inc_stop(data);
+   else if (!strcmp(ev->keyname, "Down")) _val_dec_stop(data);
+   else if (!strcmp(ev->keyname, "Escape")) _reset_value(data);
+}
+
+/**
+ * Add a new spinner to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Spinner
+ */
+EAPI Evas_Object *
+elm_spinner_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "spinner");
+   elm_widget_type_set(obj, "spinner");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_disable_hook_set(obj, _disable_hook);
+
+   wd->val = 0.0;
+   wd->val_min = 0.0;
+   wd->val_max = 100.0;
+   wd->wrap = 0;
+   wd->step = 1.0;
+   wd->entry_visible = 0;
+   wd->editable = EINA_TRUE;
+
+   wd->spinner = edje_object_add(e);
+   _elm_theme_object_set(obj, wd->spinner, "spinner", "base", "default");
+   elm_widget_resize_object_set(obj, wd->spinner);
+   edje_object_signal_callback_add(wd->spinner, "drag", "*", _drag, obj);
+   edje_object_signal_callback_add(wd->spinner, "drag,start", "*", 
+                                   _drag_start, obj);
+   edje_object_signal_callback_add(wd->spinner, "drag,stop", "*", 
+                                   _drag_stop, obj);
+   edje_object_signal_callback_add(wd->spinner, "drag,step", "*", 
+                                   _drag_stop, obj);
+   edje_object_signal_callback_add(wd->spinner, "drag,page", "*", 
+                                   _drag_stop, obj);
+
+   edje_object_signal_callback_add(wd->spinner, "elm,action,increment,start", 
+                                   "*", _button_inc_start, obj);
+   edje_object_signal_callback_add(wd->spinner, "elm,action,increment,stop", 
+                                   "*", _button_inc_stop, obj);
+   edje_object_signal_callback_add(wd->spinner, "elm,action,decrement,start", 
+                                   "*", _button_dec_start, obj);
+   edje_object_signal_callback_add(wd->spinner, "elm,action,decrement,stop", 
+                                   "*", _button_dec_stop, obj);
+   edje_object_part_drag_value_set(wd->spinner, "elm.dragable.slider", 
+                                   0.0, 0.0);
+
+   evas_object_event_callback_add(wd->spinner, EVAS_CALLBACK_KEY_DOWN, 
+                                  _entry_event_key_down, obj);
+   evas_object_event_callback_add(wd->spinner, EVAS_CALLBACK_KEY_UP, 
+                                  _entry_event_key_up, obj);
+
+   wd->ent = elm_entry_add(obj);
+   elm_entry_single_line_set(wd->ent, 1);
+   evas_object_smart_callback_add(wd->ent, "activated", _entry_activated, obj);
+   edje_object_part_swallow(wd->spinner, "elm.swallow.entry", wd->ent);
+   edje_object_signal_callback_add(wd->spinner, "elm,action,entry,toggle", 
+                                   "*", _toggle_entry, obj);
+
+   _write_label(obj);
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Set the format string of the label area
+ *
+ * If NULL, this sets the format to "%.0f". If not it sets the format
+ * string for the label text. The label text is provided a floating point
+ * value, so the label text can display up to 1 floating point value. Note that
+ * this is optional. Use a format string such as "%1.2f meters" for example.
+ *
+ * @param obj The spinner object
+ * @param fmt The format string for the label display
+ *
+ * @ingroup Spinner
+ */
+EAPI void
+elm_spinner_label_format_set(Evas_Object *obj, const char *fmt)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->label, fmt);
+   _write_label(obj);
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the label format of the spinner
+ *
+ * @param obj The spinner object
+ * @return The text label format string in UTF-8
+ *
+ * @ingroup Spinner
+ */
+EAPI const char *
+elm_spinner_label_format_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->label;
+}
+
+/**
+ * Set the minimum and maximum values for the spinner
+ *
+ * Maximum must be greater than minimum.
+ *
+ * @param obj The spinner object
+ * @param min The minimum value
+ * @param max The maximum value
+ *
+ * @ingroup Spinner
+ */
+EAPI void
+elm_spinner_min_max_set(Evas_Object *obj, double min, double max)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if ((wd->val_min == min) && (wd->val_max == max)) return;
+   wd->val_min = min;
+   wd->val_max = max;
+   if (wd->val < wd->val_min) wd->val = wd->val_min;
+   if (wd->val > wd->val_max) wd->val = wd->val_max;
+   _val_set(obj);
+   _write_label(obj);
+}
+
+/**
+ * Get the minimum and maximum values of the spinner
+ *
+ * @param obj The spinner object
+ * @param min The minimum value
+ * @param max The maximum value
+ *
+ * @ingroup Spinner
+ */
+EAPI void
+elm_spinner_min_max_get(const Evas_Object *obj, double *min, double *max)
+{
+   if (min) *min = 0.0;
+   if (max) *max = 0.0;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (min) *min = wd->val_min;
+   if (max) *max = wd->val_max;
+}
+
+/**
+ * Set the step for the spinner
+ *
+ * @param obj The spinner object
+ * @param step The step value
+ *
+ * @ingroup Spinner
+ */
+EAPI void
+elm_spinner_step_set(Evas_Object *obj, double step)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->step = step;
+}
+
+/**
+ * Get the step of the spinner
+ *
+ * @param obj The spinner object
+ * @return The step value
+ *
+ * @ingroup Spinner
+ */
+EAPI double
+elm_spinner_step_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0.0;
+   return wd->step;
+}
+/**
+ * Set the value the spinner indicates
+ *
+ * @param obj The spinner object
+ * @param val The value (must be beween min and max for the spinner)
+ *
+ * @ingroup Spinner
+ */
+EAPI void
+elm_spinner_value_set(Evas_Object *obj, double val)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->val == val) return;
+   wd->val = val;
+   if (wd->val < wd->val_min) wd->val = wd->val_min;
+   if (wd->val > wd->val_max) wd->val = wd->val_max;
+   _val_set(obj);
+   _write_label(obj);
+}
+
+/**
+ * Get the value the spinner has
+ *
+ * @param obj The spinner object
+ * @return The value of the spinner
+ *
+ * @ingroup Spinner
+ */
+EAPI double
+elm_spinner_value_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0.0;
+   return wd->val;
+}
+
+/**
+ * Sets whether the spinner should wrap when it reaches its
+ * minimum/maximum value
+ *
+ * @param obj The spinner object
+ * @param wrap True if it should wrap, false otherwise
+ *
+ * @ingroup Spinner
+ */
+EAPI void
+elm_spinner_wrap_set(Evas_Object *obj, Eina_Bool wrap)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->wrap = wrap;
+}
+
+/**
+ * Gets whether the spinner should wrap when it reaches its
+ * minimum/maximum value
+ *
+ * @param obj The spinner object
+ * @return Bool value of wrap option
+ * (0 = disabled, 1 = enabled)
+ *
+ * @ingroup Spinner
+ */
+EAPI Eina_Bool
+elm_spinner_wrap_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->wrap;
+}
+
+/**
+ * Set a special value to display in the place of the numerical one.
+ *
+ * @param obj The spinner object
+ * @param value The value to be replaced
+ * @param label The label to be used
+ *
+ * @ingroup Spinner
+ */
+EAPI void
+elm_spinner_special_value_add(Evas_Object *obj, double value, const char *label)
+{
+    Elm_Spinner_Special_Value *sv;
+    ELM_CHECK_WIDTYPE(obj, widtype);
+    Widget_Data *wd = elm_widget_data_get(obj);
+    if (!wd) return;
+
+    sv = calloc(1, sizeof(*sv));
+    if (!sv) return;
+    sv->value = value;
+    sv->label = eina_stringshare_add(label);
+
+    wd->special_values = eina_list_append(wd->special_values, sv);
+    _write_label(obj);
+}
+
+/**
+ * Set whether the spinner can be directly edited by the user or not.
+ * Default is editable.
+ *
+ * @param obj The spinner object
+ * @param editable Bool value of the edit option
+ * (EINA_FALSE = not editable, EINA_TRUE = editable)
+ */
+EAPI void
+elm_spinner_editable_set(Evas_Object *obj, Eina_Bool editable)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->editable = editable;
+}
+
+/**
+ * Gets whether the spinner is editable.
+ *
+ * @param obj The spinner object
+ * @return Bool value of edit option
+ * (EINA_FALSE = not editable, EINA_TRUE = editable)
+ */
+EAPI Eina_Bool
+elm_spinner_editable_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->editable;
+}
diff --git a/src/lib/elm_table.c b/src/lib/elm_table.c
new file mode 100644 (file)
index 0000000..45c3d44
--- /dev/null
@@ -0,0 +1,209 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Table Table
+ *
+ * Arranges widgets in a table where items can also span multiple
+ * columns or rows - even overlap (and then be raised or lowered
+ * accordingly to adjust stacking if they do overlap).
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *tbl;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+
+static void
+_del_pre_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   evas_object_event_callback_del_full
+     (wd->tbl, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
+   evas_object_del(wd->tbl);
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   free(wd);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+   Evas_Coord w, h;
+   if (!wd) return;
+   evas_object_size_hint_min_get(wd->tbl, &minw, &minh);
+   evas_object_size_hint_max_get(wd->tbl, &maxw, &maxh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+   evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+   if (w < minw) w = minw;
+   if (h < minh) h = minh;
+   if ((maxw >= 0) && (w > maxw)) w = maxw;
+   if ((maxh >= 0) && (h > maxh)) h = maxh;
+   evas_object_resize(obj, w, h);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   /* We do not add this callback, consequently we do not need to delete it
+   
+   Widget_Data *wd = elm_widget_data_get(obj);
+   evas_Object *sub = event_info;
+
+   evas_object_event_callback_del_full
+     (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
+     */
+   _sizing_eval(obj);
+}
+
+/**
+ * Add a new table to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Table
+ */
+EAPI Evas_Object *
+elm_table_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "table");
+   elm_widget_type_set(obj, "table");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_del_pre_hook_set(obj, _del_pre_hook);
+
+   wd->tbl = evas_object_table_add(e);
+   evas_object_event_callback_add(wd->tbl, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                 _changed_size_hints, obj);
+   elm_widget_resize_object_set(obj, wd->tbl);
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+
+   return obj;
+}
+
+/**
+ * Set the homogenous layout in the table
+ *
+ * @param obj The layout object
+ * @param homogenous A boolean to set (or no) layout homogenous
+ * in the table
+ * (1 = homogenous,  0 = no homogenous)
+ *
+ * @ingroup Table
+ */
+EAPI void
+elm_table_homogenous_set(Evas_Object *obj, Eina_Bool homogenous)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   evas_object_table_homogeneous_set(wd->tbl, homogenous);
+}
+
+/**
+ * Set padding between cells.
+ *
+ * @param obj The layout object.
+ * @param horizontal set the horizontal padding. 
+ * @param vertical set the vertical padding.
+ *
+ * @ingroup Table
+ */
+EAPI void
+elm_table_padding_set(Evas_Object *obj, Evas_Coord horizontal, Evas_Coord vertical)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   evas_object_table_padding_set(wd->tbl, horizontal, vertical);
+}
+
+/**
+ * Add a subobject on the table with the coordinates passed
+ *
+ * @param obj The table object
+ * @param subobj The subobject to be added to the table
+ * @param x Coordinate to X axis
+ * @param y Coordinate to Y axis
+ * @param w Horizontal length
+ * @param h Vertical length
+ *
+ * @ingroup Table
+ */
+EAPI void
+elm_table_pack(Evas_Object *obj, Evas_Object *subobj, int x, int y, int w, int h)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_widget_sub_object_add(obj, subobj);
+   evas_object_table_pack(wd->tbl, subobj, x, y, w, h);
+}
+
+/**
+ * Remove child from table.
+ *
+ * @param obj The table object
+ * @param subobj The subobject
+ *
+ * @ingroup Table
+ */
+EAPI void
+elm_table_unpack(Evas_Object *obj, Evas_Object *subobj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   elm_widget_sub_object_del(obj, subobj);
+   evas_object_table_unpack(wd->tbl, subobj);
+}
+
+/**
+ * Faster way to remove all child objects from a table object.
+ *
+ * @param obj The table object
+ * @param clear If true, it will delete just removed children
+ *
+ * @ingroup Table
+ */
+EAPI void
+elm_table_clear(Evas_Object *obj, Eina_Bool clear)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   evas_object_table_clear(wd->tbl, clear);
+}
diff --git a/src/lib/elm_theme.c b/src/lib/elm_theme.c
new file mode 100644 (file)
index 0000000..ada77f7
--- /dev/null
@@ -0,0 +1,564 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Theme
+ *
+ * Functions to modify the theme in the currently running app.
+ */
+
+static Elm_Theme theme_default =
+{
+   NULL, NULL, NULL, NULL,
+     NULL, 1
+};
+
+static Eina_List *themes = NULL;
+
+static void
+_elm_theme_clear(Elm_Theme *th)
+{
+   const char *p;
+   EINA_LIST_FREE(th->themes, p)
+      eina_stringshare_del(p);
+   EINA_LIST_FREE(th->overlay, p)
+      eina_stringshare_del(p);
+   EINA_LIST_FREE(th->extension, p)
+      eina_stringshare_del(p);
+   if (th->cache)
+     {
+       eina_hash_free(th->cache);
+       th->cache = NULL;
+     }
+   if (th->theme)
+     {
+        eina_stringshare_del(th->theme);
+        th->theme = NULL;
+     }
+}
+
+static const char *
+_elm_theme_find_try(Elm_Theme *th, const char *f, const char *group)
+{
+   const char *file;
+
+   if (edje_file_group_exists(f, group))
+     {
+       file = eina_stringshare_add(f);
+       if (file)
+         {
+            eina_hash_add(th->cache, group, file);
+            return file;
+         }
+     }
+   return NULL;
+}
+
+static const char *
+_elm_theme_theme_element_try(Elm_Theme *th, const char *home, const char *f, const char *group)
+{
+   char buf[PATH_MAX];
+   const char *file = NULL;
+
+   if ((f[0] == '/') || ((f[0] == '.') && (f[1] == '/')) ||
+       ((f[0] == '.') && (f[1] == '.') && (f[2] == '/')) ||
+       (isalpha(f[0]) && f[1] == ':'))
+     return _elm_theme_find_try(th, f, group);
+   else if (((f[0] == '~') && (f[1] == '/')))
+     {
+       snprintf(buf, sizeof(buf), "%s/%s", home, f + 2);
+       return _elm_theme_find_try(th, buf, group);
+     }
+   snprintf(buf, sizeof(buf), "%s/.elementary/themes/%s.edj", home, f);
+   file = _elm_theme_find_try(th, buf, group);
+   if (file) return file;
+   snprintf(buf, sizeof(buf), "%s/themes/%s.edj", _elm_data_dir, f);
+   file = _elm_theme_find_try(th, buf, group);
+   return file;
+}
+
+static const char *
+_elm_theme_group_file_find(Elm_Theme *th, const char *group)
+{
+   const Eina_List *l;
+   const char *f;
+   static const char *home = NULL;
+   const char *file = eina_hash_find(th->cache, group);
+
+   if (file) return file;
+   if (!home)
+     {
+       home = getenv("HOME");
+       if (!home) home = "";
+     }
+   EINA_LIST_FOREACH(th->overlay, l, f)
+     {
+       file = _elm_theme_theme_element_try(th, home, f, group);
+       if (file) return file;
+     }
+   EINA_LIST_FOREACH(th->themes, l, f)
+     {
+       file = _elm_theme_theme_element_try(th, home, f, group);
+       if (file) return file;
+     }
+   EINA_LIST_FOREACH(th->extension, l, f)
+     {
+       file = _elm_theme_theme_element_try(th, home, f, group);
+       if (file) return file;
+     }
+   return NULL;
+}
+
+int
+_elm_theme_object_set(Evas_Object *parent, Evas_Object *o, const char *clas, const char *group, const char *style)
+{
+   Elm_Theme *th = NULL;
+   if (parent) th = elm_widget_theme_get(parent);
+   return _elm_theme_set(th, o, clas, group, style);
+}
+
+int
+_elm_theme_object_icon_set(Evas_Object *parent, Evas_Object *o, const char *group, const char *style)
+{
+   Elm_Theme *th = NULL;
+   if (parent) th = elm_widget_theme_get(parent);
+   return _elm_theme_icon_set(th, o, group, style);
+}
+
+int
+_elm_theme_set(Elm_Theme *th, Evas_Object *o, const char *clas, const char *group, const char *style)
+{
+   const char *file;
+   char buf2[1024];
+   int ok;
+
+   if (!th) th = &(theme_default);
+   snprintf(buf2, sizeof(buf2), "elm/%s/%s/%s", clas, group, style);
+   file = _elm_theme_group_file_find(th, buf2);
+   if (file)
+     {
+       ok = edje_object_file_set(o, file, buf2);
+       if (ok) return 1;
+     }
+   snprintf(buf2, sizeof(buf2), "elm/%s/%s/default", clas, group);
+   file = _elm_theme_group_file_find(th, buf2);
+   if (!file) return 0;
+   ok = edje_object_file_set(o, file, buf2);
+   return ok;
+}
+
+int
+_elm_theme_icon_set(Elm_Theme *th, Evas_Object *o, const char *group, const char *style)
+{
+   const char *file;
+   char buf2[1024];
+   int w, h;
+
+   if (!th) th = &(theme_default);
+   snprintf(buf2, sizeof(buf2), "elm/icon/%s/%s", group, style);
+   file = _elm_theme_group_file_find(th, buf2);
+   if (file)
+     {
+       _els_smart_icon_file_edje_set(o, file, buf2);
+       _els_smart_icon_size_get(o, &w, &h);
+       if (w > 0) return 1;
+     }
+   snprintf(buf2, sizeof(buf2), "elm/icon/%s/default", group);
+   file = _elm_theme_group_file_find(th, buf2);
+   if (!file) return 0;
+   _els_smart_icon_file_edje_set(o, file, buf2);
+   _els_smart_icon_size_get(o, &w, &h);
+   return (w > 0);
+}
+
+int
+_elm_theme_parse(Elm_Theme *th, const char *theme)
+{
+   Eina_List *names = NULL;
+   const char *p, *pe;
+
+   if (!th) th = &(theme_default);
+   if (theme)
+     {
+        p = theme;
+        pe = p;
+        for (;;)
+          {
+             if ((*pe == ':') || (*pe == 0))
+               { // p -> pe == 'name:'
+                  if (pe > p)
+                    {
+                       char *n = malloc(pe - p + 1);
+                       if (n)
+                         {
+                            const char *nn;
+                            
+                            strncpy(n, p, pe - p);
+                            n[pe - p] = 0;
+                            nn = eina_stringshare_add(n);
+                            if (nn) names = eina_list_append(names, nn);
+                            free(n);
+                         }
+                    }
+                  if (*pe == 0) break;
+                  p = pe + 1;
+                  pe = p;
+               }
+             else
+               pe++;
+          }
+     }
+   p = eina_list_data_get(eina_list_last(names));
+   if ((!p) || ((p) && (strcmp(p, "default"))))
+     {
+       p = eina_stringshare_add("default");
+       if (p) names = eina_list_append(names, p);
+     }
+   if (th->cache) eina_hash_free(th->cache);
+   th->cache = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
+
+   EINA_LIST_FREE(th->themes, p) eina_stringshare_del(p);
+
+   th->themes = names;
+   return 1;
+}
+
+void
+_elm_theme_shutdown(void)
+{
+   _elm_theme_clear(&(theme_default));
+}
+
+/**
+ * Create a new specific theme
+ * 
+ * This creates an empty specific theme that only uses the default theme. A
+ * specific theme has its own private set of extensions and overlays too
+ * (which are empty by default). Specific themes do not fall back to themes
+ * of parent objects. They are not intended for this use. Use styles, overlays
+ * and extensions when needed, but avoid specific themes unless there is no
+ * other way (example: you want to have a preview of a new theme you are
+ * selecting in a "theme selector" window. The preview is inside a scroller
+ * and should display what the theme you selected will look like, but not
+ * actually apply it yet. The child of the scroller will have a specific
+ * theme set to show this preview before the user decides to apply it to all
+ * applications).
+ * 
+ * @ingroup Theme
+ */
+EAPI Elm_Theme *
+elm_theme_new(void)
+{
+   Elm_Theme *th = calloc(1, sizeof(Elm_Theme));
+   if (!th) return NULL;
+   th->ref = 1;
+   th->themes = eina_list_append(th->themes, eina_stringshare_add("default"));
+   themes = eina_list_append(themes, th);
+   return th;
+}
+
+/**
+ * Free a specific theme
+ * 
+ * @param th The theme to free
+ * 
+ * This frees a theme created with elm_theme_new().
+ * 
+ * @ingroup Theme
+ */
+EAPI void
+elm_theme_free(Elm_Theme *th)
+{
+   th->ref--;
+   if (th->ref < 1)
+     {
+        _elm_theme_clear(th);
+        themes = eina_list_remove(themes, th);
+        free(th);
+     }
+}
+
+/**
+ * Prepends a theme overlay to the list of overlays
+ *
+ * @param th The theme to add to, or if NULL, the default theme
+ * @param item The Edje file path to be used
+ * 
+ * Use this if your application needs to provide some custom overlay theme
+ * (An Edje file that replaces some default styles of widgets) where adding
+ * new styles, or changing system theme configuration is not possible. Do
+ * NOT use this instead of a proper system theme configuration. Use proper
+ * configuration files, profiles, environment variables etc. to set a theme
+ * so that the theme can be altered by simple confiugration by a user. Using
+ * this call to achieve that effect is abusing the API and will create lots
+ * of trouble.
+ *
+ * @ingroup Theme
+ */
+EAPI void
+elm_theme_overlay_add(Elm_Theme *th, const char *item)
+{
+   const char *f = eina_stringshare_add(item);
+
+   if (!th) th = &(theme_default);
+   if (f) th->overlay = eina_list_prepend(th->overlay, f);
+   elm_theme_flush(th);
+}
+
+/**
+ * Delete a theme overlay from the list of overlays
+ *
+ * @param th The theme to delete from, or if NULL, the default theme
+ * @param item The name of the theme overlay
+ *
+ * See elm_theme_overlay_add().
+ * 
+ * @ingroup Theme
+ */
+EAPI void
+elm_theme_overlay_del(Elm_Theme *th, const char *item)
+{
+   const Eina_List *l;
+   const char *f, *s;
+
+   if (!th) th = &(theme_default);
+   s = eina_stringshare_add(item);
+   EINA_LIST_FOREACH(th->overlay, l, f)
+     if (f == s)
+       {
+         eina_stringshare_del(f);
+         th->overlay = eina_list_remove_list(th->overlay, (Eina_List *)l);
+         break;
+       }
+   eina_stringshare_del(s);
+   elm_theme_flush(th);
+}
+
+/**
+ * Prepends a theme extension to the list of extensions.
+ *
+ * @param th The theme to add to, or if NULL, the default theme
+ * @param item The Edje file path to be used
+ *
+ * This is intended when an application needs more styles of widgets or new
+ * widget themes that the default does not provide (or may not provide). The
+ * application has "extended" usage by coming up with new custom style names
+ * for widgets for specific uses, but as these are not "standard", they are
+ * not guaranteed to be provided by a default theme. This means the
+ * application is required to provide these extra elements itself in specific
+ * Edje files. This call adds one of those Edje files to the theme search
+ * path to be search after the default theme. The use of this call is
+ * encouraged when default styles do not meet the needs of the application.
+ * Use this call instead of elm_theme_overlay_add() for almost all cases.
+ * 
+ * @ingroup Theme
+ */
+EAPI void
+elm_theme_extension_add(Elm_Theme *th, const char *item)
+{
+   const char *f = eina_stringshare_add(item);
+
+   if (!th) th = &(theme_default);
+   if (f) th->extension = eina_list_append(th->extension, f);
+   elm_theme_flush(th);
+}
+
+/**
+ * Deletes a theme extension from the list of extensions.
+ *
+ * @param th The theme to delete from, or if NULL, the default theme
+ * @param item The name of the theme extension
+ * 
+ * See elm_theme_extension_add().
+ *
+ * @ingroup Theme
+ */
+EAPI void
+elm_theme_extension_del(Elm_Theme *th, const char *item)
+{
+   const Eina_List *l;
+   const char *f, *s;
+
+   if (!th) th = &(theme_default);
+   s = eina_stringshare_add(item);
+   EINA_LIST_FOREACH(th->extension, l, f)
+     if (f == s)
+       {
+         eina_stringshare_del(f);
+         th->extension = eina_list_remove_list(th->extension, (Eina_List *)l);
+         break;
+       }
+   eina_stringshare_del(s);
+   elm_theme_flush(th);
+}
+
+/**
+ * Set the theme search order for the given theme
+ * 
+ * @param th The theme to set the search order, or if NULL, the default theme
+ * @param theme Theme search string
+ * 
+ * This sets the search string for the theme in path-notation from first
+ * theme to search, to last, delimited by the : character. Example:
+ * 
+ * "shiny:/path/to/file.edj:default"
+ * 
+ * See the ELM_THEME environment variable for more information.
+ * 
+ * @ingroup Theme
+ */
+EAPI void
+elm_theme_set(Elm_Theme *th, const char *theme)
+{
+   if (!th) th = &(theme_default);
+   _elm_theme_parse(th, theme);
+   if (th->theme)
+     {
+        eina_stringshare_del(th->theme);
+        th->theme = NULL;
+     }
+   elm_theme_flush(th);
+}
+
+/**
+ * Return the theme search order
+ * 
+ * @param th The theme to get the search order, or if NULL, the default theme
+ * @return The internal search order path
+ * 
+ * See elm_theme_set() for more information.
+ * 
+ * @ingroup Theme
+ */
+EAPI const char *
+elm_theme_get(Elm_Theme *th)
+{
+   if (!th->theme)
+     {
+        Eina_List *l;
+        const char *f;
+        char *tmp;
+        int len;
+        
+        len = 0;
+        EINA_LIST_FOREACH(th->themes, l, f)
+          {
+             len + strlen(f);
+             if (l->next) len += 1;
+          }
+        tmp = alloca(len + 1);
+        tmp[0] = 0;
+        EINA_LIST_FOREACH(th->themes, l, f)
+          {
+             strcat(tmp, f);
+             if (l->next) strcat(tmp, ":");
+          }
+        th->theme = eina_stringshare_add(tmp);
+     }
+   return th->theme;
+}
+
+/**
+ * Flush the current theme.
+ * 
+ * @param th Theme to flush
+ * 
+ * This flushes caches that let elementary know where to find theme elements
+ * in the given theme. If @p th is NULL, then the default theme is flushed.
+ * Call this call if source theme data has changed in such a way as to
+ * make any caches Elementary kept invalid.
+ *
+ * @ingroup Theme
+ */
+EAPI void
+elm_theme_flush(Elm_Theme *th)
+{
+   if (!th) th = &(theme_default);
+   if (th->cache) eina_hash_free(th->cache);
+   th->cache = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
+   _elm_win_rescale();
+}
+
+/**
+ * This flushes all themems (default and specific ones).
+ * 
+ * This will flush all themes in the current application context, by calling
+ * elm_theme_flush() on each of them.
+ * 
+ * @ingroup Theme
+ */
+EAPI void
+elm_theme_full_flush(void)
+{
+   Eina_List *l;
+   Elm_Theme *th;
+   
+   EINA_LIST_FOREACH(themes, l, th)
+     {
+        elm_theme_flush(th);
+     }
+   elm_theme_flush(&(theme_default));
+}
+
+/**
+ * Set the theme for all elementary using applications on the current display
+ *
+ * @param theme The name of the theme to use. Format same as the ELM_THEME
+ * environment variable.
+ *
+ * @ingroup Theme
+ */
+EAPI void
+elm_theme_all_set(const char *theme)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   
+   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_THEME");
+   ecore_x_window_prop_string_set(ecore_x_window_root_first_get(),
+                                  atom, theme);
+#endif
+   elm_theme_set(NULL, theme);
+}
+
+/**
+ * Set a specific theme to be used for this object and its children
+ * 
+ * @param obj The object to set the theme on
+ * @param th The theme to set
+ * 
+ * This sets a specific theme that will be used for the given object and any
+ * child objects it has. If @p th is NULL then the theme to be used is
+ * cleared and the object will inherit its theme from its parent (which
+ * ultimately will use the default theme if no specific themes are set).
+ * 
+ * Use special themes with great care as this will annoy users and make
+ * configuration difficult. Avoid any custom themes at all if it can be
+ * helped.
+ * 
+ * @ingroup Theme
+ */
+EAPI void
+elm_object_theme_set(Evas_Object *obj, Elm_Theme *th)
+{
+   elm_widget_theme_set(obj, th);
+}
+
+/**
+ * Get the specific theme to be used
+ * 
+ * @param obj The object to get the specific theme from
+ * @return The specifc theme set.
+ * 
+ * This will return a specific theme set, or NULL if no specific theme is
+ * set on that object. It will not return inherited themes from parents, only
+ * the specific theme set for that specific object. See elm_object_theme_set()
+ * for more information.
+ * 
+ * @ingroup Theme
+ */
+EAPI Elm_Theme *
+elm_object_theme_get(Evas_Object *obj)
+{
+   return elm_widget_theme_get(obj);
+}
diff --git a/src/lib/elm_thumb.c b/src/lib/elm_thumb.c
new file mode 100644 (file)
index 0000000..d12fa55
--- /dev/null
@@ -0,0 +1,728 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Thumb Thumb
+ *
+ * A thumb object is used for displaying the thumbnail of an image or video.
+ * You must have compiled Elementary with Ethumb_Client support and the DBus
+ * service must be present and auto-activated in order to have thumbnails to
+ * be generated.
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * clicked - This is called when a user has clicked the thumb without dragging
+ * around.
+ *
+ * clicked,double - This is called when a user has double-clicked the thumb.
+ *
+ * press - This is called when a user has pressed down the thumb.
+ *
+ * generate,start - The thumbnail generation started.
+ *
+ * generate,stop - The generation process stopped.
+ *
+ * generate,error - The generation failed.
+ *
+ * load,error - The thumbnail image loading failed.
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *self;
+   struct {
+       Evas_Object *frm;
+       Evas_Object *view;
+       struct {
+            float x, y;
+       } align;
+   } children;
+   const char *file;
+   const char *key;
+   Ecore_Event_Handler *eeh;
+   int id;
+   Elm_Thumb_Animation_Setting anim_setting;
+   Eina_Bool on_hold : 1;
+   Eina_Bool is_video : 1;
+   Eina_Bool is_generating : 1;
+   Eina_Bool keep_aspect : 1;
+};
+
+static const char *widtype = NULL;
+
+static const char SIG_CLICKED[] = "clicked";
+static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
+static const char SIG_GENERATE_ERROR[] = "generate,error";
+static const char SIG_GENERATE_START[] = "generate,start";
+static const char SIG_GENERATE_STOP[] = "generate,stop";
+static const char SIG_LOAD_ERROR[] = "load,error";
+static const char SIG_PRESS[]= "press";
+static const Evas_Smart_Cb_Description _signals[] = {
+  {SIG_CLICKED, ""},
+  {SIG_CLICKED_DOUBLE, ""},
+  {SIG_GENERATE_ERROR, ""},
+  {SIG_GENERATE_START, ""},
+  {SIG_GENERATE_STOP, ""},
+  {SIG_LOAD_ERROR, ""},
+  {SIG_PRESS, ""},
+  {NULL, NULL}
+};
+
+static const char EDJE_SIGNAL_GENERATE_START[] = "elm,thumb,generate,start";
+static const char EDJE_SIGNAL_GENERATE_STOP[] = "elm,thumb,generate,stop";
+static const char EDJE_SIGNAL_GENERATE_ERROR[] = "elm,thumb,generate,error";
+static const char EDJE_SIGNAL_LOAD_ERROR[] = "elm,thumb,load,error";
+static const char EDJE_SIGNAL_PULSE_START[] = "elm,state,pulse,start";
+static const char EDJE_SIGNAL_PULSE_STOP[] = "elm,state,pulse,stop";
+
+#ifdef HAVE_ELEMENTARY_ETHUMB
+Ethumb_Client *_elm_ethumb_client = NULL;
+#endif
+Eina_Bool _elm_ethumb_connected = EINA_FALSE;
+
+EAPI int ELM_ECORE_EVENT_ETHUMB_CONNECT = 0;
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   eina_stringshare_del(wd->file);
+   eina_stringshare_del(wd->key);
+   if (wd->eeh)
+     ecore_event_handler_del(wd->eeh);
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   _elm_theme_object_set(obj, wd->children.frm, "thumb", "base", elm_widget_style_get(obj));
+}
+
+#ifdef HAVE_ELEMENTARY_ETHUMB
+static void
+_mouse_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Widget_Data *wd = data;
+   Evas_Event_Mouse_Down *ev = event_info;
+   if (ev->button != 1)
+     return;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
+     wd->on_hold = EINA_TRUE;
+   else
+     wd->on_hold = EINA_FALSE;
+   if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
+     evas_object_smart_callback_call(data, SIG_CLICKED_DOUBLE, NULL);
+   else
+     evas_object_smart_callback_call(data, SIG_PRESS, NULL);
+}
+
+static void
+_mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+
+   Widget_Data *wd = data;
+   Evas_Event_Mouse_Up *ev = event_info;
+   if (ev->button != 1)
+     return;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
+     wd->on_hold = EINA_TRUE;
+   else
+     wd->on_hold = EINA_FALSE;
+   if (!wd->on_hold)
+     evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
+   wd->on_hold = EINA_FALSE;
+}
+
+static void
+_finished_thumb(Widget_Data *wd, int id, const char *thumb_path, const char *thumb_key)
+{
+   int r;
+   Evas *evas;
+
+   evas = evas_object_evas_get(wd->self);
+   if (wd->children.view)
+     evas_object_del(wd->children.view);
+   wd->children.view = NULL;
+   wd->id = id;
+
+   if (wd->is_video &&
+       ethumb_client_format_get(_elm_ethumb_client) == ETHUMB_THUMB_EET)
+     {
+       wd->children.view = edje_object_add(evas);
+       if (!wd->children.view)
+         {
+            ERR("could not create edje object");
+            goto err;
+         }
+       if (!edje_object_file_set(wd->children.view, thumb_path, "movie/thumb"))
+         {
+            ERR("could not set file=%s key=%s for %s", thumb_path, thumb_key,
+                wd->file);
+            goto view_err;
+         }
+     }
+   else
+     {
+       wd->children.view = evas_object_image_filled_add(evas);
+       if (!wd->children.view)
+         {
+            ERR("could not create image object");
+            goto err;
+         }
+       evas_object_image_file_set(wd->children.view, thumb_path, thumb_key);
+       r = evas_object_image_load_error_get(wd->children.view);
+       if (r != EVAS_LOAD_ERROR_NONE)
+         {
+            ERR("%s: %s", thumb_path, evas_load_error_str(r));
+            goto view_err;
+         }
+     }
+
+   elm_widget_sub_object_add(wd->self, wd->children.view);
+   edje_object_part_swallow(wd->children.frm, "elm.swallow.content",
+                           wd->children.view);
+   edje_object_signal_emit(wd->children.frm, EDJE_SIGNAL_GENERATE_STOP, "elm");
+   evas_object_smart_callback_call(wd->self, SIG_GENERATE_STOP, NULL);
+   return;
+
+view_err:
+   evas_object_del(wd->children.view);
+   wd->children.view = NULL;
+err:
+   edje_object_signal_emit(wd->children.frm, EDJE_SIGNAL_LOAD_ERROR, "elm");
+   evas_object_smart_callback_call(wd->self, SIG_LOAD_ERROR, NULL);
+}
+
+static void
+_finished_thumb_cb(void *data, Ethumb_Client *c __UNUSED__, int id, const char *file, const char *key, const char *thumb_path, const char *thumb_key, Eina_Bool success)
+{
+   Widget_Data *wd = data;
+
+   edje_object_signal_emit(wd->children.frm, EDJE_SIGNAL_PULSE_STOP, "elm");
+   wd->is_generating = EINA_FALSE;
+
+   if (success)
+     {
+       _finished_thumb(wd, id, thumb_path, thumb_key);
+       return;
+     }
+
+   ERR("could not generate thumbnail for %s (key: %s)", file, key ? key : "");
+   edje_object_signal_emit(wd->children.frm, EDJE_SIGNAL_GENERATE_ERROR, "elm");
+   evas_object_smart_callback_call(wd->self, SIG_GENERATE_ERROR, NULL);
+}
+
+static void
+_thumb_apply(Widget_Data *wd)
+{
+   ethumb_client_file_set(_elm_ethumb_client, wd->file, wd->key);
+   if (ethumb_client_thumb_exists(_elm_ethumb_client))
+     {
+       const char *thumb_path, *thumb_key;
+       ethumb_client_thumb_path_get(_elm_ethumb_client, &thumb_path,
+                                    &thumb_key);
+       _finished_thumb(wd, 0, thumb_path, thumb_key);
+       return;
+     }
+   else if (ethumb_client_generate(_elm_ethumb_client, _finished_thumb_cb, wd,
+                                  NULL) != -1)
+     {
+       edje_object_signal_emit(wd->children.frm, EDJE_SIGNAL_PULSE_START,
+                               "elm");
+       edje_object_signal_emit(wd->children.frm, EDJE_SIGNAL_GENERATE_START,
+                               "elm");
+       evas_object_smart_callback_call(wd->self, SIG_GENERATE_START, NULL);
+     }
+   else
+     {
+       edje_object_signal_emit(wd->children.frm, EDJE_SIGNAL_GENERATE_ERROR,
+                               "elm");
+       evas_object_smart_callback_call(wd->self, SIG_GENERATE_ERROR, NULL);
+     }
+   wd->is_generating = EINA_FALSE;
+}
+
+static int
+_thumb_apply_cb(void *data, int type __UNUSED__, void *ev __UNUSED__)
+{
+   _thumb_apply(data);
+   return ECORE_CALLBACK_RENEW;
+}
+
+static void
+_thumb_show(Widget_Data *wd)
+{
+   evas_object_show(wd->children.frm);
+
+   if (elm_thumb_ethumb_client_connected())
+     {
+       _thumb_apply(wd);
+       return;
+     }
+
+   if (!wd->eeh)
+     wd->eeh = ecore_event_handler_add(ELM_ECORE_EVENT_ETHUMB_CONNECT,
+                                      _thumb_apply_cb, wd);
+}
+
+static void
+_thumb_show_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _thumb_show(data);
+}
+
+static void
+_cancel_cb(void *data, Eina_Bool success)
+{
+   Widget_Data *wd = data;
+
+   if (success)
+     {
+       wd->is_generating = EINA_FALSE;
+       edje_object_signal_emit(wd->children.frm, EDJE_SIGNAL_GENERATE_STOP,
+                               "elm");
+       evas_object_smart_callback_call(wd->self, SIG_GENERATE_STOP, NULL);
+     }
+}
+
+static void
+_thumb_hide_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = data;
+
+   evas_object_hide(wd->children.frm);
+
+   if (wd->is_generating)
+     ethumb_client_generate_cancel(_elm_ethumb_client, wd->id, _cancel_cb, wd, NULL);
+   else if (wd->eeh)
+     {
+       ecore_event_handler_del(wd->eeh);
+       wd->eeh = NULL;
+     }
+}
+
+#endif
+
+#ifdef ELM_ETHUMB
+static Eina_Bool _elm_need_ethumb = 0;
+
+static void _on_die_cb(void *, Ethumb_Client *);
+
+static void
+_connect_cb(void *data __UNUSED__, Ethumb_Client *c, Eina_Bool success)
+{
+   if (success)
+     {
+       ethumb_client_on_server_die_callback_set(c, _on_die_cb, NULL, NULL);
+       _elm_ethumb_connected = EINA_TRUE;
+       ecore_event_add(ELM_ECORE_EVENT_ETHUMB_CONNECT, NULL, NULL, NULL);
+     }
+   else
+     _elm_ethumb_client = NULL;
+}
+
+static void
+_on_die_cb(void *data __UNUSED__, Ethumb_Client *c __UNUSED__)
+{
+   ethumb_client_disconnect(_elm_ethumb_client);
+   _elm_ethumb_client = NULL;
+   _elm_ethumb_connected = EINA_FALSE;
+   _elm_ethumb_client = ethumb_client_connect(_connect_cb, NULL, NULL);
+}
+#endif
+
+void
+_elm_unneed_ethumb(void)
+{
+#ifdef ELM_ETHUMB
+   if (_elm_need_ethumb)
+     {
+       _elm_need_ethumb = 0;
+       ethumb_client_disconnect(_elm_ethumb_client);
+       _elm_ethumb_client = NULL;
+       ethumb_client_shutdown();
+       ELM_ECORE_EVENT_ETHUMB_CONNECT = 0;
+     }
+#endif
+}
+
+/**
+ * This must be called before any other function that handle with
+ * elm_thumb objects or ethumb_client instances.
+ *
+ * @ingroup Thumb
+ */
+EAPI void
+elm_need_ethumb(void)
+{
+#ifdef ELM_ETHUMB
+   if (_elm_need_ethumb)
+     return;
+   ELM_ECORE_EVENT_ETHUMB_CONNECT = ecore_event_type_new();
+   _elm_need_ethumb = 1;
+   ethumb_client_init();
+   _elm_ethumb_client = ethumb_client_connect(_connect_cb, NULL, NULL);
+#endif
+}
+
+/**
+ * Add a new thumb object to the parent.
+ *
+ * @param parent The parent object.
+ * @return The new object or NULL if it cannot be created.
+ *
+ * @see elm_thumb_file_set()
+ * @see elm_thumb_ethumb_client_get()
+ * @see elm_thumb_keep_aspect_set()
+ * @see elm_thumb_align_set()
+ * @see elm_thumb_align_get()
+ *
+ * @ingroup Thumb
+ */
+EAPI Evas_Object *
+elm_thumb_add(Evas_Object *parent)
+{
+   Evas *evas;
+   Widget_Data *wd;
+   Evas_Object *obj;
+   Evas_Coord minw, minh;
+
+   wd = ELM_NEW(Widget_Data);
+   evas = evas_object_evas_get(parent);
+   obj = elm_widget_add(evas);
+   ELM_SET_WIDTYPE(widtype, "thumb");
+   elm_widget_type_set(obj, "thumb");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+
+   wd->children.frm = edje_object_add(evas);
+   _elm_theme_object_set(obj, wd->children.frm, "thumb", "base", "default");
+   elm_widget_resize_object_set(obj, wd->children.frm);
+
+   edje_object_size_min_calc(obj, &minw, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+
+   wd->self = obj;
+   wd->children.view = NULL;
+   wd->file = NULL;
+   wd->key = NULL;
+   wd->eeh = NULL;
+   wd->children.align.x = 0.5;
+   wd->children.align.y = 0.5;
+   wd->on_hold = EINA_FALSE;
+   wd->is_video = EINA_FALSE;
+   wd->is_generating = EINA_FALSE;
+   wd->keep_aspect = EINA_FALSE;
+
+#ifdef HAVE_ELEMENTARY_ETHUMB
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
+                                 _mouse_down_cb, wd);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP,
+                                 _mouse_up_cb, wd);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW,
+                                 _thumb_show_cb, wd);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE,
+                                 _thumb_hide_cb, wd);
+#endif
+
+   // TODO: convert Elementary to subclassing of Evas_Smart_Class
+   // TODO: and save some bytes, making descriptions per-class and not instance!
+   evas_object_smart_callbacks_descriptions_set(obj, _signals);
+   return obj;
+}
+
+/**
+ * Set the file that will be used as thumbnail.
+ *
+ * The file can be an image or a video (in that case, acceptable extensions are:
+ * avi, mp4, ogv, mov, mpg and wmv). To start the video animation, use the
+ * function elm_thumb_animate().
+ *
+ * @param obj The thumb object.
+ * @param file The path to file that will be used as thumb.
+ * @param key The key used in case of an EET file.
+ *
+ * @see elm_thumb_file_get()
+ * @see elm_thumb_animate()
+ *
+ * @ingroup Thumb
+ */
+EAPI void
+elm_thumb_file_set(Evas_Object *obj, const char *file, const char *key)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Eina_Bool file_replaced, key_replaced;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   file_replaced = eina_stringshare_replace(&(wd->file), file);
+   key_replaced = eina_stringshare_replace(&(wd->key), key);
+
+   if (file_replaced)
+     {
+       int prefix_size;
+       const char **ext, *ptr;
+       static const char *extensions[] = { ".avi", ".mp4", ".ogv", ".mov",
+                                           ".mpg", ".wmv", NULL };
+
+       prefix_size = eina_stringshare_strlen(wd->file) - 4;
+       if (prefix_size >= 0)
+         {
+            ptr = wd->file + prefix_size;
+            wd->is_video = EINA_FALSE;
+            for (ext = extensions; *ext; ext++)
+              if (!strcasecmp(ptr, *ext))
+                {
+                   wd->is_video = EINA_TRUE;
+                   break;
+                }
+         }
+     }
+
+#ifdef HAVE_ELEMENTARY_ETHUMB
+   if ((file_replaced || key_replaced) && evas_object_visible_get(obj))
+     _thumb_show(wd);
+#endif
+}
+
+/**
+ * Get the image or video path and key used to generate the thumbnail.
+ *
+ * @param obj The thumb object.
+ * @param file Pointer to filename.
+ * @param key Pointer to key.
+ *
+ * @see elm_thumb_file_set()
+ * @see elm_thumb_animate()
+ *
+ * @ingroup Thumb
+ */
+EAPI void
+elm_thumb_file_get(const Evas_Object *obj, const char **file, const char **key)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (file)
+     *file = wd->file;
+   if (key)
+     *key = wd->key;
+}
+
+/**
+ * Set the animation state for the thumb object. If its content is an animated
+ * video, you may start/stop the animation or tell it to play continuously and
+ * looping.
+ *
+ * @param obj The thumb object.
+ * @param setting The animation setting.
+ *
+ * @see elm_thumb_file_set()
+ *
+ * @ingroup Thumb
+ */
+EAPI void
+elm_thumb_animate_set(Evas_Object *obj, Elm_Thumb_Animation_Setting setting)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (setting < ELM_THUMB_ANIMATION_START ||
+       setting >= ELM_THUMB_ANIMATION_LAST)
+     {
+        return;
+     }
+
+   wd->anim_setting = setting;
+   if (setting == ELM_THUMB_ANIMATION_LOOP)
+     edje_object_signal_emit(wd->children.view, "animate_loop", "");
+   else if (setting == ELM_THUMB_ANIMATION_START)
+     edje_object_signal_emit(wd->children.view, "animate", "");
+   else if (setting == ELM_THUMB_ANIMATION_STOP)
+     edje_object_signal_emit(wd->children.view, "animate_stop", "");
+}
+
+/**
+ * Get the animation state for the thumb object.
+ *
+ * @param obj The thumb object.
+ * @return getting The animation setting or @c ELM_THUMB_ANIMATION_LAST,
+ * on errors.
+ *
+ * @see elm_thumb_file_get()
+ *
+ * @ingroup Thumb
+ */
+EAPI Elm_Thumb_Animation_Setting
+elm_thumb_animate_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) ELM_THUMB_ANIMATION_LAST;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   return wd->anim_setting;
+}
+
+/**
+ * Set whether the thumbnail exhibition should keep the image or video aspect.
+ *
+ * For positioning the image/video within the object use the function
+ * elm_thumb_align_set().
+ *
+ * @param obj The thumb object.
+ * @param setting Whether keep or not the aspect.
+ *
+ * @see elm_thumb_file_set()
+ * @see elm_thumb_align_set()
+ *
+ * @ingroup Thumb
+ */
+EAPI void
+elm_thumb_keep_aspect_set(Evas_Object *obj, Eina_Bool setting)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   wd->keep_aspect = setting;
+}
+
+/**
+ * Get back the aspect info set with @c elm_thumb_keep_aspect_set().
+ *
+ * @param obj The thumb object.
+ * @return Whether the thumb object keeps or not the aspect for its content.
+ *
+ * @see elm_thumb_file_get()
+ * @see elm_thumb_align_get()
+ *
+ * @ingroup Thumb
+ */
+EAPI Eina_Bool
+elm_thumb_keep_aspect_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   return wd->keep_aspect;
+}
+
+/**
+ * Set image/video's alignment within the thumbnail.
+ *
+ * @param obj The thumb object.
+ * @param x_align The x alignment (0 <= x <= 1).
+ * @param y_align The y alignment (0 <= y <= 1).
+ *
+ * @see elm_thumb_keep_aspect_set()
+ * @see elm_thumb_align_get()
+ *
+ * @ingroup Thumb
+ */
+EAPI void
+elm_thumb_align_set(Evas_Object *obj, float x_align, float y_align)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (x_align > 1.0)
+     x_align = 1.0;
+   else if (x_align < 0.0)
+     x_align = 0.0;
+   wd->children.align.x = x_align;
+
+   if (y_align > 1.0)
+     y_align = 1.0;
+   else if (y_align < 0.0)
+     y_align = 0.0;
+   wd->children.align.y = y_align;
+}
+
+/**
+ * Get the alignenment set for the thumb object.
+ *
+ * @param obj The thumb object.
+ * @param x Pointer to x alignenment.
+ * @param y Pointer to y alignenment.
+ *
+ * @see elm_thumb_align_set()
+ *
+ * @ingroup Thumb
+ */
+EAPI void
+elm_thumb_align_get(const Evas_Object *obj, float *x, float *y)
+{
+    ELM_CHECK_WIDTYPE(obj, widtype);
+    Widget_Data *wd = elm_widget_data_get(obj);
+    if (x) *x = wd->children.align.x;
+    if (y) *y = wd->children.align.y;
+}
+
+/**
+ * Get the ethumb_client handle so custom configuration can be made.
+ * This must be called before the objects are created to be sure no object is
+ * visible and no generation started.
+ *
+ * @return Ethumb_Client instance or NULL.
+ *
+ * Example of usage:
+ *
+ * @code
+ * #include <Elementary.h>
+ * #ifndef ELM_LIB_QUICKLAUNCH
+ * EAPI int
+ * elm_main(int argc, char **argv)
+ * {
+ *    Ethumb_Client *client;
+ *
+ *    elm_need_ethumb();
+ *
+ *    // ... your code
+ *
+ *    client = elm_thumb_ethumb_client_get();
+ *    if (!client)
+ *      {
+ *         ERR("could not get ethumb_client");
+ *         return 1;
+ *      }
+ *    ethumb_client_size_set(client, 100, 100);
+ *    ethumb_client_crop_align_set(client, 0.5, 0.5);
+ *    // ... your code
+ *
+ *    // Create elm_thumb objects here
+ *
+ *    elm_run();
+ *    elm_shutdown();
+ *    return 0;
+ * }
+ * #endif
+ * ELM_MAIN()
+ * @endcode
+ *
+ * @ingroup Thumb
+ */
+#ifdef ELM_ETHUMB
+EAPI Ethumb_Client *
+elm_thumb_ethumb_client_get(void)
+{
+   return _elm_ethumb_client;
+}
+#else
+EAPI void *
+elm_thumb_ethumb_client_get(void)
+{
+   return NULL;
+}
+#endif
+
+/**
+ * Get the ethumb_client connection state.
+ *
+ * @return EINA_TRUE if the client is connected to the server or
+ *        EINA_FALSE otherwise.
+ */
+EAPI Eina_Bool
+elm_thumb_ethumb_client_connected(void)
+{
+   return _elm_ethumb_connected;
+}
diff --git a/src/lib/elm_toggle.c b/src/lib/elm_toggle.c
new file mode 100644 (file)
index 0000000..b057215
--- /dev/null
@@ -0,0 +1,399 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Toggle
+ *
+ * A toggle is a slider which can be used to toggle between
+ * two values.  It has two states: on and off.
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * changed - Whenever the toggle value has been changed.  Is not called
+ * until the toggle is released by the cursor (assuming it has been triggered
+ * by the cursor in the first place).
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *tgl;
+   Evas_Object *icon;
+   Eina_Bool state;
+   Eina_Bool *statep;
+   const char *label;
+   const char *ontext, *offtext;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _disable_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+static void _signal_toggle_off(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_toggle_on(void *data, Evas_Object *obj, const char *emission, const char *source);
+
+static const char SIG_CHANGED[] = "changed";
+static const Evas_Smart_Cb_Description _signals[] = {
+  {SIG_CHANGED, ""},
+  {NULL, NULL}
+};
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->label) eina_stringshare_del(wd->label);
+   if (wd->ontext) eina_stringshare_del(wd->ontext);
+   if (wd->offtext) eina_stringshare_del(wd->offtext);
+   free(wd);
+}
+
+static void
+_disable_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (elm_widget_disabled_get(obj))
+     edje_object_signal_emit(wd->tgl, "elm,state,disabled", "elm");
+   else
+     edje_object_signal_emit(wd->tgl, "elm,state,enabled", "elm");
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _elm_theme_object_set(obj, wd->tgl, "toggle", "base", elm_widget_style_get(obj));
+   if (wd->icon)
+     edje_object_signal_emit(wd->tgl, "elm,state,icon,visible", "elm");
+   else
+     edje_object_signal_emit(wd->tgl, "elm,state,icon,hidden", "elm");
+   if (wd->state)
+     edje_object_signal_emit(wd->tgl, "elm,state,toggle,on", "elm");
+   else
+     edje_object_signal_emit(wd->tgl, "elm,state,toggle,off", "elm");
+   if (wd->label)
+     edje_object_signal_emit(wd->tgl, "elm,state,text,visible", "elm");
+   else
+     edje_object_signal_emit(wd->tgl, "elm,state,text,hidden", "elm");
+   edje_object_part_text_set(wd->tgl, "elm.text", wd->label);
+   edje_object_part_text_set(wd->tgl, "elm.ontext", wd->ontext);
+   edje_object_part_text_set(wd->tgl, "elm.offtext", wd->offtext);
+   edje_object_message_signal_process(wd->tgl);
+   edje_object_scale_set(wd->tgl, elm_widget_scale_get(obj) * _elm_config->scale);
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1;
+
+   if (!wd) return;
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   edje_object_size_min_restricted_calc(wd->tgl, &minw, &minh, minw, minh);
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (obj != wd->icon) return;
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *sub = event_info;
+   if (!wd) return;
+   if (sub == wd->icon)
+     {
+       edje_object_signal_emit(wd->tgl, "elm,state,icon,hidden", "elm");
+       evas_object_event_callback_del_full
+         (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
+       wd->icon = NULL;
+       _sizing_eval(obj);
+     }
+}
+
+static void
+_signal_toggle_off(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   wd->state = 0;
+   if (wd->statep) *wd->statep = wd->state;
+   evas_object_smart_callback_call(data, SIG_CHANGED, NULL);
+}
+
+static void
+_signal_toggle_on(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   wd->state = 1;
+   if (wd->statep) *wd->statep = wd->state;
+   evas_object_smart_callback_call(data, SIG_CHANGED, NULL);
+}
+
+/**
+ * Add a toggle to @p parent.
+ *
+ * @param parent The parent object
+ *
+ * @return The toggle object
+ *
+ * @ingroup Toggle
+ */
+EAPI Evas_Object *
+elm_toggle_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "toggle");
+   elm_widget_type_set(obj, "toggle");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_disable_hook_set(obj, _disable_hook);
+
+   wd->tgl = edje_object_add(e);
+   _elm_theme_object_set(obj, wd->tgl, "toggle", "base", "default");
+   wd->ontext = eina_stringshare_add("ON");
+   wd->offtext = eina_stringshare_add("OFF");
+   edje_object_signal_callback_add(wd->tgl, "elm,action,toggle,on", "",
+                                   _signal_toggle_on, obj);
+   edje_object_signal_callback_add(wd->tgl, "elm,action,toggle,off", "",
+                                   _signal_toggle_off, obj);
+   elm_widget_resize_object_set(obj, wd->tgl);
+   edje_object_part_text_set(wd->tgl, "elm.ontext", wd->ontext);
+   edje_object_part_text_set(wd->tgl, "elm.offtext", wd->offtext);
+
+   evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+
+   _sizing_eval(obj);
+
+   // TODO: convert Elementary to subclassing of Evas_Smart_Class
+   // TODO: and save some bytes, making descriptions per-class and not instance!
+   evas_object_smart_callbacks_descriptions_set(obj, _signals);
+   return obj;
+}
+
+/**
+ * Sets the label to be displayed with the toggle.
+ *
+ * @param obj The toggle object
+ * @param label The label to be displayed
+ *
+ * @ingroup Toggle
+ */
+EAPI void
+elm_toggle_label_set(Evas_Object *obj, const char *label)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->label, label);
+   if (label)
+     edje_object_signal_emit(wd->tgl, "elm,state,text,visible", "elm");
+   else
+     edje_object_signal_emit(wd->tgl, "elm,state,text,hidden", "elm");
+   edje_object_message_signal_process(wd->tgl);
+   edje_object_part_text_set(wd->tgl, "elm.text", label);
+   _sizing_eval(obj);
+}
+
+/**
+ * Gets the label of the toggle
+ *
+ * @param obj The toggle object
+ * @return The label of the toggle
+ *
+ * @ingroup Toggle
+ */
+EAPI const char *
+elm_toggle_label_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->label;
+}
+
+/**
+ * Sets the icon to be displayed with the toggle.
+ *
+ * @param obj The toggle object
+ * @param icon The icon object to be displayed
+ *
+ * @ingroup Toggle
+ */
+EAPI void
+elm_toggle_icon_set(Evas_Object *obj, Evas_Object *icon)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if ((wd->icon != icon) && (wd->icon))
+     elm_widget_sub_object_del(obj, wd->icon);
+   wd->icon = icon;
+   if (!icon) return;
+   elm_widget_sub_object_add(obj, icon);
+   evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                  _changed_size_hints, obj);
+   edje_object_part_swallow(wd->tgl, "elm.swallow.content", icon);
+   edje_object_signal_emit(wd->tgl, "elm,state,icon,visible", "elm");
+   _sizing_eval(obj);
+}
+
+/**
+ * Gets the icon of the toggle
+ *
+ * @param obj The toggle object
+ * @return The icon object
+ *
+ * @ingroup Toggle
+ */
+EAPI Evas_Object *
+elm_toggle_icon_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->icon;
+}
+
+/**
+ * Sets the labels to be associated with the on and off states of the toggle.
+ *
+ * @param obj The toggle object
+ * @param onlabel The label displayed when the toggle is in the "on" state
+ * @param offlabel The label displayed when the toggle is in the "off" state
+ *
+ * @ingroup Toggle
+ */
+EAPI void
+elm_toggle_states_labels_set(Evas_Object *obj, const char *onlabel, const char *offlabel)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   eina_stringshare_replace(&wd->ontext, onlabel);
+   eina_stringshare_replace(&wd->offtext, offlabel);
+   edje_object_part_text_set(wd->tgl, "elm.ontext", onlabel);
+   edje_object_part_text_set(wd->tgl, "elm.offtext", offlabel);
+   _sizing_eval(obj);
+}
+
+
+/**
+ * Gets the labels associated with the on and off states of the toggle.
+ *
+ * @param obj The toggle object
+ * @param onlabel A char** to place the onlabel of @p obj into
+ * @param offlabel A char** to place the offlabel of @p obj into
+ *
+ * @ingroup Toggle
+ */
+EAPI void
+elm_toggle_states_labels_get(const Evas_Object *obj, const char **onlabel, const char **offlabel)
+{
+   if (onlabel) *onlabel = NULL;
+   if (offlabel) *offlabel = NULL;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (onlabel) *onlabel = wd->ontext;
+   if (offlabel) *offlabel = wd->offtext;
+}
+
+/**
+ * Sets the state of the toggle to @p state.
+ *
+ * @param obj The toggle object
+ * @param state The state of @p obj
+ *
+ * @ingroup Toggle
+ */
+EAPI void
+elm_toggle_state_set(Evas_Object *obj, Eina_Bool state)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (state != wd->state)
+     {
+       wd->state = state;
+       if (wd->statep) *wd->statep = wd->state;
+       if (wd->state)
+         edje_object_signal_emit(wd->tgl, "elm,state,toggle,on", "elm");
+       else
+         edje_object_signal_emit(wd->tgl, "elm,state,toggle,off", "elm");
+     }
+}
+
+/**
+ * Gets the state of the toggle to @p state.
+ *
+ * @param obj The toggle object
+ * @return The state of @p obj
+ *
+ * @ingroup Toggle
+ */
+EAPI Eina_Bool
+elm_toggle_state_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->state;
+}
+
+/**
+ * Sets the state pointer of the toggle to @p statep.
+ *
+ * @param obj The toggle object
+ * @param statep The state pointer of @p obj
+ *
+ * @ingroup Toggle
+ */
+EAPI void
+elm_toggle_state_pointer_set(Evas_Object *obj, Eina_Bool *statep)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (statep)
+     {
+       wd->statep = statep;
+       if (*wd->statep != wd->state)
+         {
+            wd->state = *wd->statep;
+            if (wd->state)
+              edje_object_signal_emit(wd->tgl, "elm,state,toggle,on", "elm");
+            else
+              edje_object_signal_emit(wd->tgl, "elm,state,toggle,off", "elm");
+         }
+     }
+   else
+     wd->statep = NULL;
+}
diff --git a/src/lib/elm_toolbar.c b/src/lib/elm_toolbar.c
new file mode 100644 (file)
index 0000000..10173f9
--- /dev/null
@@ -0,0 +1,1081 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Toolbar Toolbar
+ *
+ * A toolbar is a widget that displays a list of buttons inside
+ * a box.  It is scrollable, and only one item can be selected at a time.
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *scr, *bx;
+   Eina_List *items;
+   int icon_size;
+   Eina_Bool scrollable : 1;
+   Evas_Object *menu_parent;
+   Eina_Bool homogeneous : 1;
+   double align;
+};
+
+struct _Elm_Toolbar_Item
+{
+   Evas_Object *obj;
+   Evas_Object *base;
+   const char *label;
+   Evas_Object *icon;
+   Evas_Smart_Cb func;
+   Evas_Smart_Cb del_cb;
+   const void *data;
+   Eina_Bool selected : 1;
+   Eina_Bool disabled : 1;
+   Eina_Bool separator : 1;
+   Eina_Bool menu;
+   Evas_Object *o_menu;
+};
+
+static const char *widtype = NULL;
+static void _item_show(Elm_Toolbar_Item *it);
+static void _item_select(Elm_Toolbar_Item *it);
+static void _item_disable(Elm_Toolbar_Item *it, Eina_Bool disabled);
+static void _del_pre_hook(Evas_Object *obj);
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _menu_move_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _menu_hide(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data);
+
+static void
+_item_show(Elm_Toolbar_Item *it)
+{
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+   Evas_Coord x, y, w, h, bx, by;
+
+   if (!wd) return;
+   evas_object_geometry_get(wd->bx, &bx, &by, NULL, NULL);
+   evas_object_geometry_get(it->base, &x, &y, &w, &h);
+   elm_smart_scroller_child_region_show(wd->scr, x - bx, y - by, w, h);
+}
+
+static void
+_item_select(Elm_Toolbar_Item *it)
+{
+   Elm_Toolbar_Item *it2;
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+   Evas_Object *obj2;
+   const Eina_List *l;
+
+   if (!wd) return;
+   if ((it->selected) || (it->disabled) || (it->separator)) return;
+   EINA_LIST_FOREACH(wd->items, l, it2)
+     {
+       if (it2->selected)
+         {
+            it2->selected = EINA_FALSE;
+            edje_object_signal_emit(it2->base, "elm,state,unselected", "elm");
+            break;
+         }
+     }
+   it->selected = EINA_TRUE;
+   edje_object_signal_emit(it->base, "elm,state,selected", "elm");
+   _item_show(it);
+   obj2 = it->obj;
+   if(it->menu)
+     {
+        evas_object_show(it->o_menu);
+        evas_object_event_callback_add(it->base, EVAS_CALLBACK_RESIZE,
+                                       _menu_move_resize, it);
+        evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOVE,
+                                       _menu_move_resize, it);
+
+        _menu_move_resize(it, NULL, NULL, NULL);
+     }
+   if (it->func) it->func((void *)(it->data), it->obj, it);
+   evas_object_smart_callback_call(obj2, "clicked", it);
+}
+
+static void
+_menu_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Elm_Toolbar_Item *it = data;
+   elm_toolbar_item_unselect_all(it->obj);
+}
+
+static void
+_menu_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   // avoid hide being emitted during object deletion
+   evas_object_event_callback_del_full
+     (obj, EVAS_CALLBACK_HIDE, _menu_hide, data);
+}
+
+static void
+_menu_move_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+    Elm_Toolbar_Item *it = data;
+    Evas_Coord x,y,w,h;
+    Widget_Data *wd = elm_widget_data_get(it->obj);
+
+    if ((!wd) || (!wd->menu_parent)) return;
+    evas_object_geometry_get(it->base, &x, &y, &w, &h);
+    elm_menu_move(it->o_menu, x, y+h);
+}
+
+static void
+_item_disable(Elm_Toolbar_Item *it, Eina_Bool disabled)
+{
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+
+   if (!wd) return;
+   if (it->disabled == disabled) return;
+   it->disabled = disabled;
+   if (it->disabled)
+     edje_object_signal_emit(it->base, "elm,state,disabled", "elm");
+   else
+     edje_object_signal_emit(it->base, "elm,state,enabled", "elm");
+}
+
+static void
+_del_pre_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Elm_Toolbar_Item *it;
+
+   if (!wd) return;
+   EINA_LIST_FREE(wd->items, it)
+     {
+       if (it->del_cb) it->del_cb((void *)it->data, it->obj, it);
+       eina_stringshare_del(it->label);
+       if (it->icon) evas_object_del(it->icon);
+       if ((!wd->menu_parent) && (it->o_menu)) evas_object_del(it->o_menu);
+       evas_object_del(it->base);
+       free(it);
+     }
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   const Eina_List *l;
+   Elm_Toolbar_Item *it;
+   const char *style = elm_widget_style_get(obj);
+   double scale = 0;
+
+   if (!wd) return;
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "toolbar", "base", elm_widget_style_get(obj));
+   scale = (elm_widget_scale_get(obj) * _elm_config->scale);
+//   edje_object_scale_set(wd->scr, scale);
+   EINA_LIST_FOREACH(wd->items, l, it)
+     {
+        Evas_Coord mw, mh;
+
+       edje_object_scale_set(it->base, scale);
+        if (!it->separator)
+          {
+             if (it->selected)
+               edje_object_signal_emit(it->base, "elm,state,selected", "elm");
+             if (it->disabled)
+               edje_object_signal_emit(it->base, "elm,state,disabled", "elm");
+             _elm_theme_object_set(obj, it->base, "toolbar", "item", style);
+             if (it->icon)
+               {
+                  int ms = 0;
+
+                  ms = ((double)wd->icon_size * _elm_config->scale);
+                 evas_object_size_hint_min_set(it->icon, ms, ms);
+                 evas_object_size_hint_max_set(it->icon, ms, ms);
+                  edje_object_part_swallow(it->base, "elm.swallow.icon",
+                                           it->icon);
+               }
+             edje_object_part_text_set(it->base, "elm.text", it->label);
+          }
+        else
+          _elm_theme_object_set(obj, it->base, "toolbar", "separator", style);
+
+       mw = mh = -1;
+       if (!it->separator)
+         elm_coords_finger_size_adjust(1, &mw, 1, &mh);
+       edje_object_size_min_restricted_calc(it->base, &mw, &mh, mw, mh);
+       if (!it->separator)
+         elm_coords_finger_size_adjust(1, &mw, 1, &mh);
+        evas_object_size_hint_min_set(it->base, mw, mh);
+     }
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1;
+   Evas_Coord vw = 0, vh = 0;
+   Evas_Coord w, h;
+
+   if (!wd) return;
+   evas_object_smart_calculate(wd->bx);
+   edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
+                             &minw, &minh);
+   evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+   if (w < minw) w = minw;
+   if (h < minh) h = minh;
+
+   evas_object_resize(wd->scr, w, h);
+
+   evas_object_size_hint_min_get(wd->bx, &minw, &minh);
+   if (w > minw) minw = w;
+   evas_object_resize(wd->bx, minw, minh);
+   elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
+   if (wd->scrollable)
+     minw = w - vw;
+   else
+     minw = minw + (w - vw);
+   minh = minh + (h - vh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+static void
+_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Coord mw, mh, vw, vh, w, h;
+   const Eina_List *l;
+   Elm_Toolbar_Item *it;
+
+   if (!wd) return;
+   elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
+   evas_object_size_hint_min_get(wd->bx, &mw, &mh);
+   evas_object_geometry_get(wd->bx, NULL, NULL, &w, &h);
+   if (vw >= mw)
+     {
+       if (w != vw) evas_object_resize(wd->bx, vw, h);
+     }
+   EINA_LIST_FOREACH(wd->items, l, it)
+     {
+       if (it->selected)
+         {
+            _item_show(it);
+            break;
+         }
+     }
+}
+
+static void
+_select(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   _item_select(data);
+}
+
+static void
+_layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data)
+{
+   Widget_Data *wd = data;
+   if (!wd) return;
+   _els_box_layout(o, priv, 1, wd->homogeneous);
+}
+
+/**
+ * Add a toolbar object to @p parent.
+ *
+ * @param parent The parent object
+ *
+ * @return The created object, or NULL on failure
+ *
+ * @ingroup Toolbar
+ */
+EAPI Evas_Object *
+elm_toolbar_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   Widget_Data *wd;
+
+   wd = ELM_NEW(Widget_Data);
+   e = evas_object_evas_get(parent);
+   obj = elm_widget_add(e);
+   ELM_SET_WIDTYPE(widtype, "toolbar");
+   elm_widget_type_set(obj, "toolbar");
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_pre_hook_set(obj, _del_pre_hook);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_can_focus_set(obj, 0);
+
+   wd->scr = elm_smart_scroller_add(e);
+   elm_smart_scroller_widget_set(wd->scr, obj);
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "toolbar", "base", "default");
+   elm_smart_scroller_bounce_allow_set(wd->scr, 1, 0);
+   elm_widget_resize_object_set(obj, wd->scr);
+   elm_smart_scroller_policy_set(wd->scr,
+                                ELM_SMART_SCROLLER_POLICY_AUTO,
+                                ELM_SMART_SCROLLER_POLICY_OFF);
+
+   wd->icon_size = 32;
+   wd->scrollable = EINA_TRUE;
+   wd->homogeneous = EINA_TRUE;
+   wd->align = 0.5;
+
+   wd->bx = evas_object_box_add(e);
+   evas_object_size_hint_align_set(wd->bx, wd->align, 0.5);
+   evas_object_box_layout_set(wd->bx, _layout, wd, NULL);
+   elm_widget_sub_object_add(obj, wd->bx);
+   elm_smart_scroller_child_set(wd->scr, wd->bx);
+   evas_object_show(wd->bx);
+
+   evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_RESIZE, _resize, obj);
+
+   _sizing_eval(obj);
+   return obj;
+}
+
+/**
+ * Set the icon size (in pixels) for the toolbar.
+ *
+ * @param obj The toolbar object
+ * @param icon_size The icon size in pixels
+ *
+ * @ingroup Toolbar
+ */
+EAPI void
+elm_toolbar_icon_size_set(Evas_Object *obj, int icon_size)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (icon_size > 48) return;
+   if (wd->icon_size == icon_size) return;
+   wd->icon_size = icon_size;
+   _theme_hook(obj);
+}
+
+/**
+ * Get the icon size (in pixels) for the toolbar.
+ *
+ * @param obj The toolbar object
+ * @return The icon size in pixels
+ *
+ * @ingroup Toolbar
+ */
+EAPI int
+elm_toolbar_icon_size_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   return wd->icon_size;
+}
+
+/**
+ * Add an item to the toolbar.
+ *
+ * @param obj The toolbar object
+ * @param icon The icon object of the item
+ * @param label The label of the item
+ * @param func The function to call when the item is clicked
+ * @param data The data to associate with the item
+ *
+ * @return The toolbar item, or NULL upon failure
+ *
+ * @ingroup Toolbar
+ */
+EAPI Elm_Toolbar_Item *
+elm_toolbar_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, Evas_Smart_Cb func, const void *data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord mw, mh;
+   Elm_Toolbar_Item *it;
+
+   if (!wd) return NULL;
+   it = ELM_NEW(Elm_Toolbar_Item);
+   if (!it) return NULL;
+   wd->items = eina_list_append(wd->items, it);
+   it->obj = obj;
+   it->label = eina_stringshare_add(label);
+   it->icon = icon;
+   it->func = func;
+   it->data = data;
+   it->separator = EINA_FALSE;
+   it->base = edje_object_add(evas_object_evas_get(obj));
+   _elm_theme_object_set(obj, it->base, "toolbar", "item", elm_widget_style_get(obj));
+   edje_object_signal_callback_add(it->base, "elm,action,click", "elm",
+                                  _select, it);
+   elm_widget_sub_object_add(obj, it->base);
+   if (it->icon)
+     {
+        int ms = 0;
+
+        ms = ((double)wd->icon_size * _elm_config->scale);
+       evas_object_size_hint_min_set(it->icon, ms, ms);
+       evas_object_size_hint_max_set(it->icon, ms, ms);
+       edje_object_part_swallow(it->base, "elm.swallow.icon", it->icon);
+       evas_object_show(it->icon);
+       elm_widget_sub_object_add(obj, it->icon);
+     }
+   edje_object_part_text_set(it->base, "elm.text", it->label);
+   mw = mh = -1;
+   elm_coords_finger_size_adjust(1, &mw, 1, &mh);
+   edje_object_size_min_restricted_calc(it->base, &mw, &mh, mw, mh);
+   elm_coords_finger_size_adjust(1, &mw, 1, &mh);
+   evas_object_size_hint_weight_set(it->base, -1.0, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(it->base, 0.5, EVAS_HINT_FILL);
+   evas_object_size_hint_min_set(it->base, mw, mh);
+   evas_object_box_append(wd->bx, it->base);
+   evas_object_show(it->base);
+   _sizing_eval(obj);
+   return it;
+}
+
+/**
+ * Get the icon associated with @p item.
+ *
+ * @param item The toolbar item
+ * @return The icon object
+ *
+ * @ingroup Toolbar
+ */
+EAPI Evas_Object *
+elm_toolbar_item_icon_get(Elm_Toolbar_Item *item)
+{
+   if (!item) return NULL;
+   return item->icon;
+}
+
+/**
+ * Get the label associated with @p item.
+ *
+ * @param item The toolbar item
+ * @return The label
+ *
+ * @ingroup Toolbar
+ */
+EAPI const char *
+elm_toolbar_item_label_get(const Elm_Toolbar_Item *item)
+{
+   if (!item) return NULL;
+   return item->label;
+}
+
+/**
+ * Get the selected state of @p item.
+ *
+ * @param item The toolbar item
+ * @return If true, the item is selected
+ *
+ * @ingroup Toolbar
+ */
+EAPI Eina_Bool
+elm_toolbar_item_selected_get(const Elm_Toolbar_Item *item)
+{
+   if (!item) return EINA_FALSE;
+   return item->selected;
+}
+
+/**
+ * Set the label associated with @p item.
+ *
+ * @param item The toolbar item
+ * @param label The label of @p item
+ *
+ * @ingroup Toolbar
+ */
+EAPI void
+elm_toolbar_item_label_set(Elm_Toolbar_Item *item, const char *label)
+{
+   Evas_Coord mw = -1, mh = -1;
+
+   if (!item) return;
+   eina_stringshare_replace(&item->label, label);
+   edje_object_part_text_set(item->base, "elm.text", item->label);
+
+   elm_coords_finger_size_adjust(1, &mw, 1, &mh);
+   edje_object_size_min_restricted_calc(item->base, &mw, &mh, mw, mh);
+   elm_coords_finger_size_adjust(1, &mw, 1, &mh);
+   evas_object_size_hint_weight_set(item->base, -1.0, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(item->base, 0.5, EVAS_HINT_FILL);
+   evas_object_size_hint_min_set(item->base, mw, mh);
+}
+
+
+/**
+ * Delete a toolbar item.
+ *
+ * @param it The toolbar item
+ *
+ * @ingroup Toolbar
+ */
+EAPI void
+elm_toolbar_item_del(Elm_Toolbar_Item *it)
+{
+   Widget_Data *wd = elm_widget_data_get(it->obj);
+   Evas_Object *obj2 = it->obj;
+
+   if ((!wd) || (!it)) return;
+   if (it->del_cb) it->del_cb((void *)it->data, it->obj, it);
+   wd->items = eina_list_remove(wd->items, it);
+   eina_stringshare_del(it->label);
+   if (it->icon) evas_object_del(it->icon);
+   evas_object_del(it->base);
+   free(it);
+   _theme_hook(obj2);
+}
+
+/**
+ * Set the function called when a toolbar item is freed.
+ *
+ * @param it The item to set the callback on
+ * @param func The function called
+ *
+ * @ingroup Toolbar
+ */
+EAPI void
+elm_toolbar_item_del_cb_set(Elm_Toolbar_Item *it, Evas_Smart_Cb func)
+{
+   it->del_cb = func;
+}
+
+/**
+ * Select the toolbar item @p item.
+ *
+ * @param item The toolbar item
+ *
+ * @ingroup Toolbar
+ */
+EAPI void
+elm_toolbar_item_select(Elm_Toolbar_Item *item)
+{
+   if (!item) return;
+   _item_select(item);
+}
+
+/**
+ * Get the disabled state of @p item.
+ *
+ * @param item The toolbar item
+ * @return If true, the item is disabled
+ *
+ * @ingroup Toolbar
+ */
+EAPI Eina_Bool
+elm_toolbar_item_disabled_get(Elm_Toolbar_Item *item)
+{
+   if (!item) return EINA_FALSE;
+   return item->disabled;
+}
+
+/**
+ * Set the disabled state of @p item.
+ *
+ * @param item The toolbar item
+ * @param disabled If true, the item is disabled
+ *
+ * @ingroup Toolbar
+ */
+EAPI void
+elm_toolbar_item_disabled_set(Elm_Toolbar_Item *item, Eina_Bool disabled)
+{
+   if (!item) return;
+   _item_disable(item, disabled);
+}
+
+/**
+ * Get the separator state of @p item.
+ *
+ * @param item The toolbar item
+ * @param separator If true, the item is a separator
+ *
+ * @ingroup Toolbar
+ */
+EAPI void
+elm_toolbar_item_separator_set(Elm_Toolbar_Item *item, Eina_Bool separator)
+{
+   if (!item) return;
+   if (item->separator == separator) return;
+   item->separator = separator;
+   _theme_hook(item->obj);
+}
+
+/**
+ * Set the separator state of @p item.
+ *
+ * @param item The toolbar item
+ * @return If true, the item is a separator
+ *
+ * @ingroup Toolbar
+ */
+EAPI Eina_Bool
+elm_toolbar_item_separator_get(Elm_Toolbar_Item *item)
+{
+   if (!item) return EINA_FALSE;
+   return item->separator;
+}
+
+/**
+ * Set the scrollable state of toolbar @p obj.
+ *
+ * @param obj The toolbar object
+ * @param scrollable If true, the toolbar will be scrollable
+ *
+ * @ingroup Toolbar
+ */
+EAPI void
+elm_toolbar_scrollable_set(Evas_Object *obj, Eina_Bool scrollable)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   wd->scrollable = scrollable;
+   _sizing_eval(obj);
+}
+
+/**
+ * Get the scrollable state of toolbar @p obj.
+ *
+ * @param obj The toolbar object
+ * @return If true, the toolbar is scrollable
+ *
+ * @ingroup Toolbar
+ */
+EAPI Eina_Bool
+elm_toolbar_scrollable_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   return wd->scrollable;
+}
+
+/**
+ * Set the homogenous mode of toolbar @p obj.
+ *
+ * @param obj The toolbar object
+ * @param homogenous If true, the toolbar items will be uniform in size
+ *
+ * @ingroup Toolbar
+ */
+EAPI void
+elm_toolbar_homogenous_set(Evas_Object *obj, Eina_Bool homogenous)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   wd->homogeneous = !!homogenous;
+   evas_object_smart_calculate(wd->bx);
+}
+
+/**
+ * Get the homogenous mode of toolbar @p obj.
+ *
+ * @param obj The toolbar object
+ * @return If true, the toolbar items are uniform in size
+ *
+ * @ingroup Toolbar
+ */
+EAPI Eina_Bool
+elm_toolbar_homogenous_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   return wd->homogeneous;
+}
+
+/**
+ * Set the parent object of the toolbar menu
+ *
+ * @param obj The toolbar object
+ * @param parent The parent of the menu object
+ *
+ * @ingroup Toolbar
+ */
+EAPI void
+elm_toolbar_menu_parent_set(Evas_Object *obj, Evas_Object *parent)
+{
+   Eina_List *l;
+   Elm_Toolbar_Item *it;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if ((!wd) || (!parent)) return;
+   wd->menu_parent = parent;
+   EINA_LIST_FOREACH(wd->items, l, it)
+     {
+        if (it->o_menu)
+          elm_menu_parent_set(it->o_menu, wd->menu_parent);
+     }
+}
+
+/**
+ * Get the parent object of the toolbar menu
+ *
+ * @param obj The toolbar object
+ * @return The parent of the menu object
+ *
+ * @ingroup Toolbar
+ */
+EAPI Evas_Object *
+elm_toolbar_menu_parent_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+
+   return wd->menu_parent;
+}
+
+/**
+ * Unselect all of the items in the toolbar.
+ *
+ * @param obj The toolbar object
+ *
+ * @ingroup Toolbar
+ */
+EAPI void
+elm_toolbar_item_unselect_all(Evas_Object *obj)
+{
+   Eina_List *l;
+   Elm_Toolbar_Item *it;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   EINA_LIST_FOREACH(wd->items, l, it)
+     {
+        if (it->selected)
+          {
+             it->selected = EINA_FALSE;
+             edje_object_signal_emit(it->base, "elm,state,unselected", "elm");
+             break;
+          }
+     }
+}
+
+/**
+ * Set the alignment of the items.
+ *
+ * @param obj The toolbar object
+ * @param align The new alignment. (left) 0.0 ... 1.0 (right)
+ *
+ * @ingroup Toolbar
+ */
+EAPI void
+elm_toolbar_align_set(Evas_Object *obj, double align)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   if (wd->align != align)
+     evas_object_size_hint_align_set(wd->bx, align, 0.5);
+   wd->align = align;
+}
+
+/**
+ * Get the alignment of the items.
+ *
+ * @param obj The toolbar object
+ * @return The alignment. (left) 0.0 ... 1.0 (right)
+ *
+ * @ingroup Toolbar
+ */
+EAPI double
+elm_toolbar_align_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return 0.0;
+   return wd->align;
+}
+
+/**
+ * Set whether the toolbar item opens a menu.
+ *
+ * @param item The toolbar item
+ * @param menu If true, @p item will open a menu when selected
+ *
+ * @ingroup Toolbar
+ */
+EAPI void
+elm_toolbar_item_menu_set(Elm_Toolbar_Item *item, Eina_Bool menu)
+{
+   Widget_Data *wd = elm_widget_data_get(item->obj);
+
+   if ((!wd) || (!item)) return;
+   if (item->menu == menu) return;
+   item->menu = menu;
+   if (menu)
+     {
+       item->o_menu = elm_menu_add(item->base);
+       if (wd->menu_parent)
+         elm_menu_parent_set(item->o_menu, wd->menu_parent);
+       evas_object_event_callback_add(item->o_menu, EVAS_CALLBACK_HIDE,
+                                       _menu_hide, item);
+       evas_object_event_callback_add(item->o_menu, EVAS_CALLBACK_DEL,
+                                      _menu_del, item);
+     }
+   else if (item->o_menu)
+     {
+       evas_object_del(item->o_menu);
+     }
+}
+
+
+/**
+ * Get whether the toolbar item opens a menu.
+ *
+ * @param item The toolbar item
+ * @return If true, @p item opens a menu when selected
+ *
+ * @ingroup Toolbar
+ */
+EAPI Evas_Object *
+elm_toolbar_item_menu_get(Elm_Toolbar_Item *item)
+{
+   if (!item) return NULL;
+   Widget_Data *wd = elm_widget_data_get(item->obj);
+   if (!wd) return NULL;
+   elm_toolbar_item_menu_set(item, 1);
+   return item->o_menu;
+}
+
+/**
+ * Return a list of all toolbar items.
+ *
+ * @param obj The toolbar object
+ *
+ * @return An Eina_List* of the toolbar items in @p obj
+ *
+ * @ingroup Toolbar
+ */
+EAPI Eina_List *
+elm_toolbar_item_get_all(Evas_Object *obj)
+{
+   Eina_List *l;
+   Elm_Toolbar_Item *it;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+
+   return wd->items;
+}
+
+/**
+ * Return the first toolbar item in the list of toolbar items.
+ *
+ * @param obj The toolbar object
+ *
+ * @return The first toolbar item, or NULL on failure
+ *
+ * @ingroup Toolbar
+ */
+EAPI Elm_Toolbar_Item *
+elm_toolbar_item_get_first(Evas_Object *obj)
+{
+   Eina_List *l;
+   Elm_Toolbar_Item *it;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   if (!(it = eina_list_data_get(wd->items))) return NULL;
+
+   return it;
+}
+
+/**
+ * Return the last toolbar item in the list of toolbar items.
+ *
+ * @param obj The toolbar object
+ *
+ * @return The last toolbar item, or NULL on failure
+ *
+ * @ingroup Toolbar
+ */
+EAPI Elm_Toolbar_Item *
+elm_toolbar_item_get_last(Evas_Object *obj)
+{
+   Eina_List *l, *last;
+   Elm_Toolbar_Item *it;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   if (!(last = eina_list_last(wd->items))) return NULL;
+   it = eina_list_data_get(last);
+
+   return it;
+}
+
+/**
+ * Return the next toolbar item (relative to the currently selected
+ * toolbar item) in the list of toolbar items.
+ *
+ * @param obj The toolbar object
+ *
+ * @return The next toolbar item, or NULL on failure
+ *
+ * @ingroup Toolbar
+ */
+EAPI Elm_Toolbar_Item *
+elm_toolbar_item_get_next(Evas_Object *obj)
+{
+   Eina_List *l, *l2;
+   Elm_Toolbar_Item *it, *next;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return NULL;
+   EINA_LIST_FOREACH_SAFE(wd->items, l, l2, it)
+     {
+        if (it->selected)
+          {
+            if (!(next = eina_list_data_get(l2))) return NULL;
+            return next;
+          }
+     }
+   return NULL;
+}
+
+/**
+ * Selects the next non-disabled, non-separator toolbar item in the list
+ * of toolbar items.
+ *
+ * @param obj The toolbar object
+ *
+ * @return The newly selected toolbar item, or NULL on failure
+ *
+ * @ingroup Toolbar
+ */
+EAPI Elm_Toolbar_Item *
+elm_toolbar_item_select_next(Evas_Object *obj)
+{
+   Eina_List *l, *l2;
+   Elm_Toolbar_Item *it, *next;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return NULL;
+   EINA_LIST_FOREACH(wd->items, l, it)
+     {
+        if (it->selected)
+          {
+             EINA_LIST_FOREACH(l, l2, next)
+               if ((!next->disabled) && (next->separator))
+                 {
+                    _item_select(next);
+                    return next;
+                 }
+          }
+     }
+  return NULL;
+}
+
+/**
+ * Selects the first non-disabled, non-separator toolbar item in the list
+ * of toolbar items.
+ *
+ * @param obj The toolbar object
+ *
+ * @return The newly selected toolbar item, or NULL on failure
+ *
+ * @ingroup Toolbar
+ */
+EAPI Elm_Toolbar_Item *
+elm_toolbar_item_select_first(Evas_Object *obj)
+{
+   Eina_List *l;
+   Elm_Toolbar_Item *it;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   EINA_LIST_FOREACH(wd->items, l, it)
+     {
+        if ((!it->disabled) && (!it->separator))
+          {
+             _item_select(it);
+             return it;
+          }
+     }
+
+   return NULL;
+}
+
+/**
+ * Selects the last non-disabled, non-separator toolbar item in the list
+ * of toolbar items.
+ *
+ * @param obj The toolbar object
+ *
+ * @return The newly selected toolbar item, or NULL on failure
+ *
+ * @ingroup Toolbar
+ */
+EAPI Elm_Toolbar_Item *
+elm_toolbar_item_select_last(Evas_Object *obj)
+{
+   Eina_List *l;
+   Elm_Toolbar_Item *it;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   EINA_LIST_REVERSE_FOREACH(wd->items, l, it)
+     {
+        if ((!it->disabled) && (!it->separator))
+          {
+             _item_select(it);
+             return it;
+          }
+     }
+   return NULL;
+}
+
+/**
+ * Returns a pointer to a toolbar item by its label
+ *
+ * @param obj The toolbar object
+ * @param label The label of the item to find
+ *
+ * @return The pointer to the toolbar item matching @p label
+ * Returns NULL on failure.
+ *
+ * @ingroup Toolbar
+ */
+EAPI Elm_Toolbar_Item *
+elm_toolbar_item_find_by_label(Evas_Object *obj, const char *label)
+{
+   Eina_List *l;
+   Elm_Toolbar_Item *it;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   
+   if (!wd) return NULL;
+   EINA_LIST_FOREACH(wd->items, l, it)
+     {
+        if (!strcmp(it->label, label)) return it;
+     }
+
+   return NULL;
+}
diff --git a/src/lib/elm_widget.c b/src/lib/elm_widget.c
new file mode 100644 (file)
index 0000000..684d197
--- /dev/null
@@ -0,0 +1,1274 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+static const char SMART_NAME[] = "elm_widget";
+
+#define API_ENTRY \
+   Smart_Data *sd = evas_object_smart_data_get(obj); \
+   if ((!obj) || (!sd) || (!_elm_widget_is(obj)))
+#define INTERNAL_ENTRY \
+   Smart_Data *sd = evas_object_smart_data_get(obj); \
+   if (!sd) return;
+
+typedef struct _Smart_Data Smart_Data;
+
+struct _Smart_Data
+{
+   Evas_Object   *obj;
+   const char    *type;
+   Evas_Object   *parent_obj;
+   Evas_Coord     x, y, w, h;
+   Eina_List     *subobjs;
+   Evas_Object   *resize_obj;
+   Evas_Object   *hover_obj;
+   void         (*del_func) (Evas_Object *obj);
+   void         (*del_pre_func) (Evas_Object *obj);
+   void         (*focus_func) (Evas_Object *obj);
+   void         (*activate_func) (Evas_Object *obj);
+   void         (*disable_func) (Evas_Object *obj);
+   void         (*theme_func) (Evas_Object *obj);
+   void         (*changed_func) (Evas_Object *obj);
+   void         (*on_focus_func) (void *data, Evas_Object *obj);
+   void          *on_focus_data;
+   void         (*on_change_func) (void *data, Evas_Object *obj);
+   void          *on_change_data;
+   void         (*on_show_region_func) (void *data, Evas_Object *obj);
+   void          *on_show_region_data;
+   void          *data;
+   Evas_Coord     rx, ry, rw, rh;
+   int            scroll_hold;
+   int            scroll_freeze;
+   double         scale;
+   Elm_Theme     *theme;
+   const char    *style;
+   
+   int            child_drag_x_locked;
+   int            child_drag_y_locked;
+   Eina_Bool      drag_x_locked : 1;
+   Eina_Bool      drag_y_locked : 1;
+   
+   Eina_Bool      can_focus : 1;
+   Eina_Bool      child_can_focus : 1;
+   Eina_Bool      focused : 1;
+   Eina_Bool      disabled : 1;
+};
+
+/* local subsystem functions */
+static void _smart_reconfigure(Smart_Data *sd);
+static void _smart_add(Evas_Object *obj);
+static void _smart_del(Evas_Object *obj);
+static void _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+static void _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
+static void _smart_show(Evas_Object *obj);
+static void _smart_hide(Evas_Object *obj);
+static void _smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
+static void _smart_clip_set(Evas_Object *obj, Evas_Object * clip);
+static void _smart_clip_unset(Evas_Object *obj);
+static void _smart_calculate(Evas_Object *obj);
+static void _smart_init(void);
+static inline Eina_Bool _elm_widget_is(const Evas_Object *obj);
+
+/* local subsystem globals */
+static Evas_Smart *_e_smart = NULL;
+
+static void
+_sub_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Smart_Data *sd = data;
+
+   if (obj == sd->resize_obj)
+     sd->resize_obj = NULL;
+   else if (obj == sd->hover_obj)
+     sd->hover_obj = NULL;
+   else
+     sd->subobjs = eina_list_remove(sd->subobjs, obj);
+   evas_object_smart_callback_call(sd->obj, "sub-object-del", obj);
+}
+
+static void
+_sub_obj_mouse_down(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Evas_Object *o = obj;
+   do 
+     {
+        if (_elm_widget_is(o)) break;
+        o = evas_object_smart_parent_get(o);
+     }
+   while (o);
+   if (!o) return;
+   if (!elm_widget_can_focus_get(o)) return;
+   elm_widget_focus_steal(o);
+}
+
+EAPI Evas_Object *
+elm_widget_add(Evas *evas)
+{
+   _smart_init();
+   return evas_object_smart_add(evas, _e_smart);
+}
+
+EAPI void
+elm_widget_del_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
+{
+   API_ENTRY return;
+   sd->del_func = func;
+}
+
+EAPI void
+elm_widget_del_pre_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
+{
+   API_ENTRY return;
+   sd->del_pre_func = func;
+}
+
+EAPI void
+elm_widget_focus_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
+{
+   API_ENTRY return;
+   sd->focus_func = func;
+}
+
+EAPI void
+elm_widget_activate_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
+{
+   API_ENTRY return;
+   sd->activate_func = func;
+}
+
+EAPI void
+elm_widget_disable_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
+{
+   API_ENTRY return;
+   sd->disable_func = func;
+}
+
+EAPI void
+elm_widget_theme_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
+{
+   API_ENTRY return;
+   sd->theme_func = func;
+}
+
+EAPI void
+elm_widget_changed_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
+{
+   API_ENTRY return;
+   sd->changed_func = func;
+}
+
+EAPI void
+elm_widget_theme(Evas_Object *obj)
+{
+   const Eina_List *l;
+   Evas_Object *child;
+
+   API_ENTRY return;
+   EINA_LIST_FOREACH(sd->subobjs, l, child)
+     elm_widget_theme(child);
+   if (sd->resize_obj) elm_widget_theme(sd->resize_obj);
+   if (sd->hover_obj) elm_widget_theme(sd->hover_obj);
+   if (sd->theme_func) sd->theme_func(obj);
+}
+
+EAPI void
+elm_widget_on_focus_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data)
+{
+   API_ENTRY return;
+   sd->on_focus_func = func;
+   sd->on_focus_data = data;
+}
+
+EAPI void
+elm_widget_on_change_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data)
+{
+   API_ENTRY return;
+   sd->on_change_func = func;
+   sd->on_change_data = data;
+}
+
+EAPI void
+elm_widget_on_show_region_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data)
+{
+   API_ENTRY return;
+   sd->on_show_region_func = func;
+   sd->on_show_region_data = data;
+}
+
+EAPI void
+elm_widget_data_set(Evas_Object *obj, void *data)
+{
+   API_ENTRY return;
+   sd->data = data;
+}
+
+EAPI void *
+elm_widget_data_get(const Evas_Object *obj)
+{
+   API_ENTRY return NULL;
+   return sd->data;
+}
+
+EAPI void
+elm_widget_sub_object_add(Evas_Object *obj, Evas_Object *sobj)
+{
+   API_ENTRY return;
+   double scale, pscale = elm_widget_scale_get(sobj);
+   Elm_Theme *th, *pth = elm_widget_theme_get(sobj);
+
+   sd->subobjs = eina_list_append(sd->subobjs, sobj);
+   if (!sd->child_can_focus)
+     {
+       if (elm_widget_can_focus_get(sobj)) sd->child_can_focus = 1;
+     }
+   if (_elm_widget_is(sobj))
+     {
+       Smart_Data *sd2 = evas_object_smart_data_get(sobj);
+       if (sd2)
+         {
+            if (sd2->parent_obj)
+               elm_widget_sub_object_del(sd2->parent_obj, sobj);
+            sd2->parent_obj = obj;
+         }
+     }
+   evas_object_data_set(sobj, "elm-parent", obj);
+   evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
+   evas_object_smart_callback_call(obj, "sub-object-add", sobj);
+   scale = elm_widget_scale_get(sobj);
+   th = elm_widget_theme_get(sobj);
+   if ((scale != pscale) || (th != pth)) elm_widget_theme(sobj);
+}
+
+EAPI void
+elm_widget_sub_object_del(Evas_Object *obj, Evas_Object *sobj)
+{
+   Evas_Object *sobj_parent;
+   API_ENTRY return;
+   if (!sobj) return;
+
+   sobj_parent = evas_object_data_del(sobj, "elm-parent");
+   if (sobj_parent != obj)
+     {
+       static int abort_on_warn = -1;
+       ERR("removing sub object %p from parent %p, "
+           "but elm-parent is different %p!",
+           sobj, obj, sobj_parent);
+       if (EINA_UNLIKELY(abort_on_warn == -1))
+         {
+            if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
+            else abort_on_warn = 0;
+         }
+       if (abort_on_warn == 1) abort();
+     }
+   sd->subobjs = eina_list_remove(sd->subobjs, sobj);
+   if (!sd->child_can_focus)
+     {
+       if (elm_widget_can_focus_get(sobj)) sd->child_can_focus = 0;
+     }
+   if (_elm_widget_is(sobj))
+     {
+       Smart_Data *sd2 = evas_object_smart_data_get(sobj);
+       if (sd2) sd2->parent_obj = NULL;
+     }
+   evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
+   evas_object_smart_callback_call(obj, "sub-object-del", sobj);
+}
+
+EAPI void
+elm_widget_resize_object_set(Evas_Object *obj, Evas_Object *sobj)
+{
+   API_ENTRY return;
+   if (sd->resize_obj)
+     {
+       evas_object_data_del(sd->resize_obj, "elm-parent");
+       if (_elm_widget_is(sd->resize_obj))
+         {
+            Smart_Data *sd2 = evas_object_smart_data_get(sd->resize_obj);
+            if (sd2) sd2->parent_obj = NULL;
+         }
+       evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_DEL,
+           _sub_obj_del, sd);
+       evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_MOUSE_DOWN,
+           _sub_obj_mouse_down, sd);
+       evas_object_smart_member_del(sd->resize_obj);
+     }
+   sd->resize_obj = sobj;
+   if (sd->resize_obj)
+     {
+       if (_elm_widget_is(sd->resize_obj))
+         {
+            Smart_Data *sd2 = evas_object_smart_data_get(sd->resize_obj);
+            if (sd2) sd2->parent_obj = obj;
+         }
+       evas_object_clip_set(sobj, evas_object_clip_get(obj));
+       evas_object_smart_member_add(sobj, obj);
+       evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
+       evas_object_event_callback_add(sobj, EVAS_CALLBACK_MOUSE_DOWN,
+                                       _sub_obj_mouse_down, sd);
+       _smart_reconfigure(sd);
+       evas_object_data_set(sobj, "elm-parent", obj);
+       evas_object_smart_callback_call(obj, "sub-object-add", sobj);
+     }
+}
+
+EAPI void
+elm_widget_hover_object_set(Evas_Object *obj, Evas_Object *sobj)
+{
+   API_ENTRY return;
+   if (sd->hover_obj)
+     {
+       evas_object_event_callback_del_full(sd->hover_obj, EVAS_CALLBACK_DEL,
+           _sub_obj_del, sd);
+     }
+   sd->hover_obj = sobj;
+   if (sd->hover_obj)
+     {
+       evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
+       _smart_reconfigure(sd);
+     }
+}
+
+EAPI void
+elm_widget_can_focus_set(Evas_Object *obj, int can_focus)
+{
+   API_ENTRY return;
+   sd->can_focus = can_focus;
+}
+
+EAPI int
+elm_widget_can_focus_get(const Evas_Object *obj)
+{
+   API_ENTRY return 0;
+   if (sd->can_focus) return 1;
+   if (sd->child_can_focus) return 1;
+   return 0;
+}
+
+EAPI int
+elm_widget_focus_get(const Evas_Object *obj)
+{
+   API_ENTRY return 0;
+   return sd->focused;
+}
+
+EAPI Evas_Object *
+elm_widget_focused_object_get(const Evas_Object *obj)
+{
+   const Evas_Object *subobj;
+   const Eina_List *l;
+   API_ENTRY return NULL;
+
+   if (!sd->focused) return NULL;
+   EINA_LIST_FOREACH(sd->subobjs, l, subobj)
+     {
+       Evas_Object *fobj = elm_widget_focused_object_get(subobj);
+       if (fobj) return fobj;
+     }
+   return (Evas_Object *)obj;
+}
+
+EAPI Evas_Object *
+elm_widget_top_get(const Evas_Object *obj)
+{
+#if 1 // strict way  
+   API_ENTRY return NULL;
+   if (sd->parent_obj) return elm_widget_top_get(sd->parent_obj);
+   return (Evas_Object *)obj;
+#else // loose way
+   Smart_Data *sd = evas_object_smart_data_get(obj);
+   Evas_Object *par;
+   
+   if (!obj) return NULL;
+   if ((sd) && _elm_widget_is(obj))
+     {
+        if ((sd->type) && (!strcmp(sd->type, "win"))) 
+          return (Evas_Object *)obj;
+        if (sd->parent_obj)
+          return elm_widget_top_get(sd->parent_obj);
+     }
+   par = evas_object_smart_parent_get(obj);
+   if (!par) return (Evas_Object *)obj;
+   return elm_widget_top_get(par);
+#endif   
+}
+
+EAPI Eina_Bool
+elm_widget_is(const Evas_Object *obj)
+{
+   return _elm_widget_is(obj);
+}
+
+EAPI Evas_Object *
+elm_widget_parent_widget_get(const Evas_Object *obj)
+{
+   Evas_Object *parent;
+
+   if (_elm_widget_is(obj))
+     {
+       Smart_Data *sd = evas_object_smart_data_get(obj);
+       if (!sd) return NULL;
+       parent = sd->parent_obj;
+     }
+   else
+     {
+       parent = evas_object_data_get(obj, "elm-parent");
+       if (!parent)
+         parent = evas_object_smart_data_get(obj);
+     }
+
+   while (parent)
+     {
+       Evas_Object *elm_parent;
+       if (_elm_widget_is(parent)) break;
+       elm_parent = evas_object_data_get(parent, "elm-parent");
+       if (elm_parent)
+         parent = elm_parent;
+       else
+         parent = evas_object_smart_parent_get(parent);
+     }
+   return parent;
+}
+
+EAPI int
+elm_widget_focus_jump(Evas_Object *obj, int forward)
+{
+   API_ENTRY return 0;
+   if (!elm_widget_can_focus_get(obj)) return 0;
+
+   /* if it has a focus func its an end-point widget like a button */
+   if (sd->focus_func)
+     {
+       if (!sd->focused) sd->focused = 1;
+       else sd->focused = 0;
+       if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
+       sd->focus_func(obj);
+       return sd->focused;
+     }
+   /* its some container */
+   else
+     {
+       int focus_next;
+       int noloop = 0;
+
+       focus_next = 0;
+       if (!sd->focused)
+         {
+            elm_widget_focus_set(obj, forward);
+            sd->focused = 1;
+            if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
+            return 1;
+         }
+       else
+         {
+            if (forward)
+              {
+                 if (elm_widget_can_focus_get(sd->resize_obj))
+                   {
+                      if ((focus_next) &&
+                          (!elm_widget_disabled_get(sd->resize_obj)))
+                        {
+                           /* the previous focused item was unfocused - so focus
+                            * the next one (that can be focused) */
+                           if (elm_widget_focus_jump(sd->resize_obj, forward))
+                              return 1;
+                           else noloop = 1;
+                        }
+                      else
+                        {
+                           if (elm_widget_focus_get(sd->resize_obj))
+                             {
+                                /* jump to the next focused item or focus this item */
+                                if (elm_widget_focus_jump(sd->resize_obj, forward))
+                                   return 1;
+                                /* it returned 0 - it got to the last item and is past it */
+                                focus_next = 1;
+                             }
+                        }
+                   }
+                 if (!noloop)
+                   {
+                      const Eina_List *l;
+                      Evas_Object *child;
+                      EINA_LIST_FOREACH(sd->subobjs, l, child)
+                        {
+                           if (elm_widget_can_focus_get(child))
+                             {
+                                if ((focus_next) &&
+                                    (!elm_widget_disabled_get(child)))
+                                  {
+                                     /* the previous focused item was unfocused - so focus
+                                      * the next one (that can be focused) */
+                                     if (elm_widget_focus_jump(child, forward))
+                                        return 1;
+                                     else break;
+                                  }
+                                else
+                                  {
+                                     if (elm_widget_focus_get(child))
+                                       {
+                                          /* jump to the next focused item or focus this item */
+                                          if (elm_widget_focus_jump(child, forward))
+                                             return 1;
+                                          /* it returned 0 - it got to the last item and is past it */
+                                          focus_next = 1;
+                                       }
+                                  }
+                             }
+                        }
+                   }
+              }
+            else
+              {
+                 const Eina_List *l;
+                 Evas_Object *child;
+
+                 EINA_LIST_REVERSE_FOREACH(sd->subobjs, l, child)
+                   {
+                      if (elm_widget_can_focus_get(child))
+                        {
+                           if ((focus_next) &&
+                               (!elm_widget_disabled_get(child)))
+                             {
+                                /* the previous focused item was unfocused - so focus
+                                 * the next one (that can be focused) */
+                                if (elm_widget_focus_jump(child, forward))
+                                   return 1;
+                                else break;
+                             }
+                           else
+                             {
+                                if (elm_widget_focus_get(child))
+                                  {
+                                     /* jump to the next focused item or focus this item */
+                                     if (elm_widget_focus_jump(child, forward))
+                                        return 1;
+                                     /* it returned 0 - it got to the last item and is past it */
+                                     focus_next = 1;
+                                  }
+                             }
+                        }
+                   }
+                 if (!l)
+                   {
+                      if (elm_widget_can_focus_get(sd->resize_obj))
+                        {
+                           if ((focus_next) &&
+                               (!elm_widget_disabled_get(sd->resize_obj)))
+                             {
+                                /* the previous focused item was unfocused - so focus
+                                 * the next one (that can be focused) */
+                                if (elm_widget_focus_jump(sd->resize_obj, forward))
+                                   return 1;
+                             }
+                           else
+                             {
+                                if (elm_widget_focus_get(sd->resize_obj))
+                                  {
+                                     /* jump to the next focused item or focus this item */
+                                     if (elm_widget_focus_jump(sd->resize_obj, forward))
+                                        return 1;
+                                     /* it returned 0 - it got to the last item and is past it */
+                                     focus_next = 1;
+                                  }
+                             }
+                        }
+                   }
+              }
+         }
+     }
+   /* no next item can be focused */
+   if (sd->focused)
+     {
+       sd->focused = 0;
+       if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
+     }
+   return 0;
+}
+
+EAPI void
+elm_widget_focus_set(Evas_Object *obj, int first)
+{
+   API_ENTRY return;
+   if (!sd->focused)
+     {
+       sd->focused = 1;
+       if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
+     }
+   if (sd->focus_func)
+     {
+       sd->focus_func(obj);
+       return;
+     }
+   else
+     {
+       if (first)
+         {
+            if ((elm_widget_can_focus_get(sd->resize_obj)) &&
+                (!elm_widget_disabled_get(sd->resize_obj)))
+              {
+                 elm_widget_focus_set(sd->resize_obj, first);
+              }
+            else
+              {
+                 const Eina_List *l;
+                 Evas_Object *child;
+                 EINA_LIST_FOREACH(sd->subobjs, l, child)
+                   {
+                      if ((elm_widget_can_focus_get(child)) &&
+                          (!elm_widget_disabled_get(child)))
+                        {
+                           elm_widget_focus_set(child, first);
+                           break;
+                        }
+                   }
+              }
+         }
+       else
+         {
+            const Eina_List *l;
+            Evas_Object *child;
+            EINA_LIST_REVERSE_FOREACH(sd->subobjs, l, child)
+              {
+                 if ((elm_widget_can_focus_get(child)) &&
+                     (!elm_widget_disabled_get(child)))
+                   {
+                      elm_widget_focus_set(child, first);
+                      break;
+                   }
+              }
+            if (!l)
+              {
+                 if ((elm_widget_can_focus_get(sd->resize_obj)) &&
+                     (!elm_widget_disabled_get(sd->resize_obj)))
+                   {
+                      elm_widget_focus_set(sd->resize_obj, first);
+                   }
+              }
+         }
+     }
+}
+
+EAPI Evas_Object *
+elm_widget_parent_get(const Evas_Object *obj)
+{
+   API_ENTRY return NULL;
+   return sd->parent_obj;
+}
+
+EAPI void
+elm_widget_focused_object_clear(Evas_Object *obj)
+{
+   API_ENTRY return;
+   if (!sd->focused) return;
+   if (elm_widget_focus_get(sd->resize_obj))
+     elm_widget_focused_object_clear(sd->resize_obj);
+   else
+     {
+       const Eina_List *l;
+       Evas_Object *child;
+       EINA_LIST_FOREACH(sd->subobjs, l, child)
+         {
+            if (elm_widget_focus_get(child))
+              {
+                 elm_widget_focused_object_clear(child);
+                 break;
+              }
+         }
+     }
+   sd->focused = 0;
+   if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
+   if (sd->focus_func) sd->focus_func(obj);
+}
+
+static void
+_elm_widget_parent_focus(Evas_Object *obj)
+{
+   API_ENTRY return;
+   Evas_Object *o = elm_widget_parent_get(obj);
+
+   if (sd->focused) return;
+   if (o) _elm_widget_parent_focus(o);
+   sd->focused = 1;
+   if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
+   if (sd->focus_func) sd->focus_func(obj);
+}
+
+EAPI void
+elm_widget_focus_steal(Evas_Object *obj)
+{
+   Evas_Object *parent, *o;
+   API_ENTRY return;
+
+   if (sd->focused) return;
+   if (sd->disabled) return;
+   parent = obj;
+   for (;;)
+     {
+       o = elm_widget_parent_get(parent);
+       if (!o) break;
+       sd = evas_object_smart_data_get(o);
+       if (sd->focused) break;
+       parent = o;
+     }
+   if (!elm_widget_parent_get(parent))
+     elm_widget_focused_object_clear(parent);
+   else
+     {
+       parent = elm_widget_parent_get(parent);
+       sd = evas_object_smart_data_get(parent);
+       if (elm_widget_focus_get(sd->resize_obj))
+          {
+             elm_widget_focused_object_clear(sd->resize_obj);
+          }
+       else
+         {
+            const Eina_List *l;
+            Evas_Object *child;
+            EINA_LIST_FOREACH(sd->subobjs, l, child)
+              {
+                 if (elm_widget_focus_get(child))
+                   {
+                      elm_widget_focused_object_clear(child);
+                      break;
+                   }
+              }
+         }
+     }
+   _elm_widget_parent_focus(obj);
+   return;
+}
+
+EAPI void
+elm_widget_activate(Evas_Object *obj)
+{
+   API_ENTRY return;
+   elm_widget_change(obj);
+   if (sd->activate_func) sd->activate_func(obj);
+}
+
+EAPI void
+elm_widget_change(Evas_Object *obj)
+{
+   API_ENTRY return;
+   elm_widget_change(elm_widget_parent_get(obj));
+   if (sd->on_change_func) sd->on_change_func(sd->on_change_data, obj);
+}
+
+EAPI void
+elm_widget_disabled_set(Evas_Object *obj, int disabled)
+{
+   API_ENTRY return;
+
+   if (sd->disabled == disabled) return;
+   sd->disabled = disabled;
+   if (sd->focused)
+     {
+       Evas_Object *o, *parent;
+
+       parent = obj;
+       for (;;)
+         {
+            o = elm_widget_parent_get(parent);
+            if (!o) break;
+            parent = o;
+         }
+       elm_widget_focus_jump(parent, 1);
+     }
+   if (sd->disable_func) sd->disable_func(obj);
+}
+
+EAPI int
+elm_widget_disabled_get(const Evas_Object *obj)
+{
+   API_ENTRY return 0;
+   return sd->disabled;
+}
+
+EAPI void
+elm_widget_show_region_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
+{
+   API_ENTRY return;
+   if ((x == sd->rx) && (y == sd->ry) && (w == sd->rw) && (h == sd->rh)) return;
+   sd->rx = x;
+   sd->ry = y;
+   sd->rw = w;
+   sd->rh = h;
+   if (sd->on_show_region_func)
+     sd->on_show_region_func(sd->on_show_region_data, obj);
+}
+
+EAPI void
+elm_widget_show_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
+{
+   API_ENTRY return;
+   if (x) *x = sd->rx;
+   if (y) *y = sd->ry;
+   if (w) *w = sd->rw;
+   if (h) *h = sd->rh;
+}
+
+EAPI void
+elm_widget_scroll_hold_push(Evas_Object *obj)
+{
+   API_ENTRY return;
+   sd->scroll_hold++;
+   if (sd->scroll_hold == 1)
+     evas_object_smart_callback_call(obj, "scroll-hold-on", obj);
+   if (sd->parent_obj) elm_widget_scroll_hold_push(sd->parent_obj);
+   // FIXME: on delete/reparent hold pop
+}
+
+EAPI void
+elm_widget_scroll_hold_pop(Evas_Object *obj)
+{
+   API_ENTRY return;
+   sd->scroll_hold--;
+   if (sd->scroll_hold < 0) sd->scroll_hold = 0;
+   if (sd->scroll_hold == 0)
+     evas_object_smart_callback_call(obj, "scroll-hold-off", obj);
+   if (sd->parent_obj) elm_widget_scroll_hold_pop(sd->parent_obj);
+}
+
+EAPI int
+elm_widget_scroll_hold_get(const Evas_Object *obj)
+{
+   API_ENTRY return 0;
+   return sd->scroll_hold;
+}
+
+EAPI void
+elm_widget_scroll_freeze_push(Evas_Object *obj)
+{
+   API_ENTRY return;
+   sd->scroll_freeze++;
+   if (sd->scroll_freeze == 1)
+     evas_object_smart_callback_call(obj, "scroll-freeze-on", obj);
+   if (sd->parent_obj) elm_widget_scroll_freeze_push(sd->parent_obj);
+   // FIXME: on delete/reparent freeze pop
+}
+
+EAPI void
+elm_widget_scroll_freeze_pop(Evas_Object *obj)
+{
+   API_ENTRY return;
+   sd->scroll_freeze--;
+   if (sd->scroll_freeze < 0) sd->scroll_freeze = 0;
+   if (sd->scroll_freeze == 0)
+     evas_object_smart_callback_call(obj, "scroll-freeze-off", obj);
+   if (sd->parent_obj) elm_widget_scroll_freeze_pop(sd->parent_obj);
+}
+
+EAPI int
+elm_widget_scroll_freeze_get(const Evas_Object *obj)
+{
+   API_ENTRY return 0;
+   return sd->scroll_freeze;
+}
+
+EAPI void
+elm_widget_scale_set(Evas_Object *obj, double scale)
+{
+   API_ENTRY return;
+   if (scale <= 0.0) scale = 0.0;
+   if (sd->scale != scale)
+     {
+       sd->scale = scale;
+       elm_widget_theme(obj);
+     }
+}
+
+EAPI double
+elm_widget_scale_get(const Evas_Object *obj)
+{
+   API_ENTRY return 1.0;
+   // FIXME: save walking up the tree by storingcaching parent scale
+   if (sd->scale == 0.0)
+     {
+       if (sd->parent_obj)
+         return elm_widget_scale_get(sd->parent_obj);
+       else
+         return 1.0;
+     }
+   return sd->scale;
+}
+
+EAPI void
+elm_widget_theme_set(Evas_Object *obj, Elm_Theme *th)
+{
+   API_ENTRY return;
+   if (sd->theme != th)
+     {
+        if (sd->theme) elm_theme_free(sd->theme);
+        sd->theme = th;
+        if (th) th->ref++;
+        elm_widget_theme(obj);
+     }
+}
+
+EAPI Elm_Theme *
+elm_widget_theme_get(const Evas_Object *obj)
+{
+   API_ENTRY return NULL;
+   if (!sd->theme)
+     {
+        if (sd->parent_obj)
+          return elm_widget_theme_get(sd->parent_obj);
+        else
+          return NULL;
+     }
+   return sd->theme;
+}
+
+EAPI void
+elm_widget_style_set(Evas_Object *obj, const char *style)
+{
+   API_ENTRY return;
+
+   if (eina_stringshare_replace(&sd->style, style))
+     elm_widget_theme(obj);
+}
+
+EAPI const char *
+elm_widget_style_get(const Evas_Object *obj)
+{
+   API_ENTRY return "";
+   if (sd->style) return sd->style;
+   return "default";
+}
+
+EAPI void
+elm_widget_type_set(Evas_Object *obj, const char *type)
+{
+   API_ENTRY return;
+   eina_stringshare_replace(&sd->type, type);
+}
+
+EAPI const char *
+elm_widget_type_get(const Evas_Object *obj)
+{
+   API_ENTRY return "";
+   if (sd->type) return sd->type;
+   return "";
+}
+
+
+
+
+
+
+
+
+
+static void
+_propagate_x_drag_lock(Evas_Object *obj, int dir)
+{
+   Smart_Data *sd = evas_object_smart_data_get(obj);
+   if (sd->parent_obj)
+     {
+        Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj);
+        if (sd2)
+          {
+             sd2->child_drag_x_locked += dir;
+             _propagate_x_drag_lock(sd->parent_obj, dir);
+          }
+     }
+}
+
+static void
+_propagate_y_drag_lock(Evas_Object *obj, int dir)
+{
+   Smart_Data *sd = evas_object_smart_data_get(obj);
+   if (sd->parent_obj)
+     {
+        Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj);
+        if (sd2)
+          {
+             sd2->child_drag_y_locked += dir;
+             _propagate_y_drag_lock(sd->parent_obj, dir);
+          }
+     }
+}
+
+EAPI void
+elm_widget_drag_lock_x_set(Evas_Object *obj, Eina_Bool lock)
+{
+   API_ENTRY return;
+   if (sd->drag_x_locked == lock) return;
+   sd->drag_x_locked = lock;
+   if (sd->drag_x_locked) _propagate_x_drag_lock(obj, 1);
+   else _propagate_x_drag_lock(obj, -1);
+}
+
+EAPI void
+elm_widget_drag_lock_y_set(Evas_Object *obj, Eina_Bool lock)
+{
+   API_ENTRY return;
+   if (sd->drag_y_locked == lock) return;
+   sd->drag_y_locked = lock;
+   if (sd->drag_y_locked) _propagate_y_drag_lock(obj, 1);
+   else _propagate_y_drag_lock(obj, -1);
+}
+
+EAPI Eina_Bool
+elm_widget_drag_lock_x_get(Evas_Object *obj)
+{
+   API_ENTRY return 0;
+   printf("check %p x lock %i\n", obj, sd->drag_x_locked);
+   return sd->drag_x_locked;
+}
+
+EAPI Eina_Bool
+elm_widget_drag_lock_y_get(Evas_Object *obj)
+{
+   API_ENTRY return 0;
+   printf("check %p y lock %i\n", obj, sd->drag_y_locked);
+   return sd->drag_y_locked;
+}
+
+EAPI int
+elm_widget_drag_child_locked_x_get(Evas_Object *obj)
+{
+   API_ENTRY return 0;
+   return sd->child_drag_x_locked;
+}
+
+EAPI int
+elm_widget_drag_child_locked_y_get(Evas_Object *obj)
+{
+   API_ENTRY return 0;
+   return sd->child_drag_y_locked;
+}
+
+
+
+
+
+
+
+
+
+
+
+/* local subsystem functions */
+static void
+_smart_reconfigure(Smart_Data *sd)
+{
+   if (sd->resize_obj)
+     {
+       evas_object_move(sd->resize_obj, sd->x, sd->y);
+       evas_object_resize(sd->resize_obj, sd->w, sd->h);
+     }
+   if (sd->hover_obj)
+     {
+       evas_object_move(sd->hover_obj, sd->x, sd->y);
+       evas_object_resize(sd->hover_obj, sd->w, sd->h);
+     }
+}
+
+static void
+_smart_add(Evas_Object *obj)
+{
+   Smart_Data *sd;
+
+   sd = calloc(1, sizeof(Smart_Data));
+   if (!sd) return;
+   sd->obj = obj;
+   sd->x = 0;
+   sd->y = 0;
+   sd->w = 0;
+   sd->h = 0;
+   sd->can_focus = 1;
+   evas_object_smart_data_set(obj, sd);
+}
+
+static void
+_smart_del(Evas_Object *obj)
+{
+   Evas_Object *sobj;
+
+   INTERNAL_ENTRY;
+   if (sd->del_pre_func) sd->del_pre_func(obj);
+   if (sd->resize_obj)
+     {
+       sobj = sd->resize_obj;
+       sd->resize_obj = NULL;
+       evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
+       evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
+       evas_object_del(sobj);
+     }
+   if (sd->hover_obj)
+     {
+       sobj = sd->hover_obj;
+       sd->hover_obj = NULL;
+       evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
+       evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
+       evas_object_del(sobj);
+     }
+   EINA_LIST_FREE(sd->subobjs, sobj)
+     {
+       evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
+       evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
+       evas_object_del(sobj);
+     }
+   if (sd->del_func) sd->del_func(obj);
+   if (sd->style) eina_stringshare_del(sd->style);
+   if (sd->type) eina_stringshare_del(sd->type);
+   if (sd->theme) elm_theme_free(sd->theme);
+   free(sd);
+}
+
+static void
+_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   INTERNAL_ENTRY;
+   sd->x = x;
+   sd->y = y;
+   _smart_reconfigure(sd);
+}
+
+static void
+_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+   INTERNAL_ENTRY;
+   sd->w = w;
+   sd->h = h;
+   _smart_reconfigure(sd);
+}
+
+static void
+_smart_show(Evas_Object *obj)
+{
+   INTERNAL_ENTRY;
+   evas_object_show(sd->resize_obj);
+}
+
+static void
+_smart_hide(Evas_Object *obj)
+{
+   INTERNAL_ENTRY;
+   evas_object_hide(sd->resize_obj);
+}
+
+static void
+_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
+{
+   INTERNAL_ENTRY;
+   evas_object_color_set(sd->resize_obj, r, g, b, a);
+}
+
+static void
+_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
+{
+   INTERNAL_ENTRY;
+   evas_object_clip_set(sd->resize_obj, clip);
+}
+
+static void
+_smart_clip_unset(Evas_Object *obj)
+{
+   INTERNAL_ENTRY;
+   evas_object_clip_unset(sd->resize_obj);
+}
+
+static void
+_smart_calculate(Evas_Object *obj)
+{
+   INTERNAL_ENTRY;
+   if (sd->changed_func) sd->changed_func(obj);
+}
+
+/* never need to touch this */
+
+static void
+_smart_init(void)
+{
+   if (_e_smart) return;
+     {
+       static const Evas_Smart_Class sc =
+         {
+            SMART_NAME,
+              EVAS_SMART_CLASS_VERSION,
+              _smart_add,
+              _smart_del,
+              _smart_move,
+              _smart_resize,
+              _smart_show,
+              _smart_hide,
+              _smart_color_set,
+              _smart_clip_set,
+              _smart_clip_unset,
+              _smart_calculate,
+              NULL,
+              NULL,
+              NULL,
+               NULL,
+               NULL,
+               NULL
+         };
+       _e_smart = evas_smart_class_new(&sc);
+     }
+}
+
+/* utilities */
+
+Eina_List *
+_elm_stringlist_get(const char *str)
+{
+   Eina_List *list = NULL;
+   const char *s, *b;
+   if (!str) return NULL;
+   for (b = s = str; 1; s++)
+     {
+       if ((*s == ' ') || (*s == 0))
+         {
+            char *t = malloc(s - b + 1);
+            if (t)
+              {
+                 strncpy(t, b, s - b);
+                 t[s - b] = 0;
+                 list = eina_list_append(list, eina_stringshare_add(t));
+                 free(t);
+              }
+            b = s + 1;
+         }
+       if (*s == 0) break;
+     }
+   return list;
+}
+
+void
+_elm_stringlist_free(Eina_List *list)
+{
+   const char *s;
+   EINA_LIST_FREE(list, s) eina_stringshare_del(s);
+}
+
+Eina_Bool
+_elm_widget_type_check(const Evas_Object *obj, const char *type)
+{
+   const char *provided, *expected = "(unknown)";
+   static int abort_on_warn = -1;
+   provided = elm_widget_type_get(obj);
+   if (EINA_LIKELY(provided == type)) return EINA_TRUE;
+   if (type) expected = type;
+   if ((!provided) || (provided[0] == 0))
+     {
+        provided = evas_object_type_get(obj);
+        if ((!provided) || (provided[0] == 0))
+          provided = "(unknown)";
+     }
+   ERR("Passing Object: %p, of type: '%s' when expecting type: '%s'", obj, provided, expected);
+   if (abort_on_warn == -1)
+     {
+        if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
+        else abort_on_warn = 0;
+     }
+   if (abort_on_warn == 1) abort();
+   return EINA_FALSE;
+}
+
+static inline Eina_Bool
+_elm_widget_is(const Evas_Object *obj)
+{
+   const char *type = evas_object_type_get(obj);
+   return type == SMART_NAME;
+}
diff --git a/src/lib/elm_win.c b/src/lib/elm_win.c
new file mode 100644 (file)
index 0000000..72472c7
--- /dev/null
@@ -0,0 +1,1738 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Win Win
+ *
+ * The window class of Elementary.  Contains functions to manipulate
+ * windows.
+ */
+
+typedef struct _Elm_Win Elm_Win;
+
+struct _Elm_Win
+{
+   Ecore_Evas *ee;
+   Evas *evas;
+   Evas_Object *parent, *win_obj;
+   Eina_List *subobjs;
+#ifdef HAVE_ELEMENTARY_X
+   Ecore_X_Window xwin;
+   Ecore_Event_Handler *client_message_handler;
+#endif   
+   Ecore_Job *deferred_resize_job;
+   Ecore_Job *deferred_child_eval_job;
+
+   Elm_Win_Type type;
+   Elm_Win_Keyboard_Mode kbdmode;
+   Eina_Bool autodel : 1;
+   int *autodel_clear, rot;
+   struct {
+      int x, y;
+   } screen;
+};
+
+static const char *widtype = NULL;
+static void _elm_win_obj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _elm_win_obj_callback_parent_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _elm_win_obj_intercept_show(void *data, Evas_Object *obj);
+static void _elm_win_move(Ecore_Evas *ee);
+static void _elm_win_resize(Ecore_Evas *ee);
+static void _elm_win_delete_request(Ecore_Evas *ee);
+static void _elm_win_resize_job(void *data);
+#ifdef HAVE_ELEMENTARY_X
+static void _elm_win_xwin_update(Elm_Win *win);
+#endif
+static void _elm_win_eval_subobjs(Evas_Object *obj);
+static void _elm_win_subobj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _elm_win_subobj_callback_changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+Eina_List *_elm_win_list = NULL;
+
+static void
+_elm_win_move(Ecore_Evas *ee)
+{
+   Evas_Object *obj = ecore_evas_object_associate_get(ee);
+   Elm_Win *win;
+   int x, y;
+   
+   if (!obj) return;
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   ecore_evas_geometry_get(ee, &x, &y, NULL, NULL);
+   win->screen.x = x;
+   win->screen.y = y;
+   evas_object_smart_callback_call(win->win_obj, "moved", NULL);
+}
+
+static void
+_elm_win_resize(Ecore_Evas *ee)
+{
+   Evas_Object *obj = ecore_evas_object_associate_get(ee);
+   Elm_Win *win;
+   
+   if (!obj) return;
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   if (win->deferred_resize_job) ecore_job_del(win->deferred_resize_job);
+   win->deferred_resize_job = ecore_job_add(_elm_win_resize_job, win);
+}
+
+static void
+_elm_win_focus_in(Ecore_Evas *ee)
+{
+   Evas_Object *obj = ecore_evas_object_associate_get(ee);
+   Elm_Win *win;
+   
+   if (!obj) return;
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   /*NB: Why two different "focus signals" here ??? */
+   evas_object_smart_callback_call(win->win_obj, "focus-in", NULL); // FIXME: remove me
+   evas_object_smart_callback_call(win->win_obj, "focus,in", NULL);
+}
+
+static void
+_elm_win_focus_out(Ecore_Evas *ee)
+{
+   Evas_Object *obj = ecore_evas_object_associate_get(ee);
+   Elm_Win *win;
+   
+   if (!obj) return;
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   evas_object_smart_callback_call(win->win_obj, "focus-out", NULL); // FIXME: remove me
+   evas_object_smart_callback_call(win->win_obj, "focus,out", NULL);
+}
+
+static void
+_deferred_ecore_evas_free(void *data)
+{
+   ecore_evas_free(data);
+}
+
+static void
+_elm_win_obj_callback_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Elm_Win *win = data;
+   Evas_Object *child;
+
+   if (win->parent)
+     {
+        evas_object_event_callback_del_full(win->parent, EVAS_CALLBACK_DEL,
+                                            _elm_win_obj_callback_parent_del, win);
+        win->parent = NULL;
+     }
+   if (win->autodel_clear) *(win->autodel_clear) = -1;
+   _elm_win_list = eina_list_remove(_elm_win_list, win->win_obj);
+   while (win->subobjs) elm_win_resize_object_del(obj, win->subobjs->data);
+   ecore_evas_callback_delete_request_set(win->ee, NULL);
+   ecore_evas_callback_resize_set(win->ee, NULL);
+   if (win->deferred_resize_job) ecore_job_del(win->deferred_resize_job);
+   if (win->deferred_child_eval_job) ecore_job_del(win->deferred_child_eval_job);
+   while (((child = evas_object_bottom_get(win->evas)) != NULL) &&
+         (child != obj))
+     {
+       evas_object_del(child);
+     }
+   while (((child = evas_object_top_get(win->evas)) != NULL) &&
+         (child != obj))
+     {
+       evas_object_del(child);
+     }
+#ifdef HAVE_ELEMENTARY_X
+   if (win->client_message_handler)
+     ecore_event_handler_del(win->client_message_handler);
+#endif   
+// FIXME: Why are we flushing edje on every window destroy ??
+//   evas_image_cache_flush(win->evas);
+//   evas_font_cache_flush(win->evas);
+//   edje_file_cache_flush();
+//   edje_collection_cache_flush();
+// FIXME: we are in the del handler for the object and delete the canvas
+// that lives under it from the handler... nasty. deferring doesnt help either
+   ecore_job_add(_deferred_ecore_evas_free, win->ee);
+//   ecore_evas_free(win->ee);
+   free(win);
+
+   if ((!_elm_win_list) &&
+       (elm_policy_get(ELM_POLICY_QUIT) == ELM_POLICY_QUIT_LAST_WINDOW_CLOSED))
+     {
+        evas_image_cache_flush(e);
+        evas_font_cache_flush(e);
+        edje_file_cache_flush();
+        edje_collection_cache_flush();
+       elm_exit();
+     }
+}
+
+static void
+_elm_win_obj_callback_parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Elm_Win *win = data;
+   if (obj == win->parent) win->parent = NULL;
+}
+
+static void
+_elm_win_obj_intercept_show(void *data __UNUSED__, Evas_Object *obj)
+{
+   // this is called to make sure all smart containers have calculated their
+   // sizes BEFORE we show the window to make sure it initially appears at
+   // our desired size (ie min size is known first)
+   evas_smart_objects_calculate(evas_object_evas_get(obj));
+   evas_object_show(obj);
+}
+
+static void
+_elm_win_delete_request(Ecore_Evas *ee)
+{
+   Evas_Object *obj = ecore_evas_object_associate_get(ee);
+   Elm_Win *win;
+   if (strcmp(elm_widget_type_get(obj), "win")) return;
+   
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   int autodel = win->autodel;
+   win->autodel_clear = &autodel;
+   evas_object_smart_callback_call(win->win_obj, "delete-request", NULL); // FIXME: remove me
+   evas_object_smart_callback_call(win->win_obj, "delete,request", NULL);
+   // FIXME: if above callback deletes - then the below will be invalid
+   if (autodel) evas_object_del(win->win_obj);
+   else win->autodel_clear = NULL;
+}
+
+static void
+_elm_win_resize_job(void *data)
+{
+   Elm_Win *win = data;
+   const Eina_List *l;
+   Evas_Object *obj;
+   int w, h;
+
+   win->deferred_resize_job = NULL;
+   ecore_evas_geometry_get(win->ee, NULL, NULL, &w, &h);
+   evas_object_resize(win->win_obj, w, h);
+   EINA_LIST_FOREACH(win->subobjs, l, obj)
+     {
+       evas_object_move(obj, 0, 0);
+       evas_object_resize(obj, w, h);
+     }
+}
+
+#ifdef HAVE_ELEMENTARY_X
+static void
+_elm_win_xwindow_get(Elm_Win *win)
+{
+   win->xwin = 0;
+   switch (_elm_config->engine)
+     {
+      case ELM_SOFTWARE_X11:
+       if (win->ee) win->xwin = ecore_evas_software_x11_window_get(win->ee);
+       break;
+      case ELM_SOFTWARE_FB:
+      case ELM_SOFTWARE_DIRECTFB:
+      case ELM_SOFTWARE_16_WINCE:
+      case ELM_SOFTWARE_SDL:
+      case ELM_SOFTWARE_16_SDL:
+      case ELM_OPENGL_SDL:
+       break;
+      case ELM_SOFTWARE_16_X11:
+       if (win->ee) win->xwin = ecore_evas_software_x11_16_window_get(win->ee);
+       break;
+      case ELM_XRENDER_X11:
+       if (win->ee) win->xwin = ecore_evas_xrender_x11_window_get(win->ee);
+       break;
+      case ELM_OPENGL_X11:
+       if (win->ee) win->xwin = ecore_evas_gl_x11_window_get(win->ee);
+       break;
+      case ELM_SOFTWARE_WIN32:
+       if (win->ee) win->xwin = (long)ecore_evas_win32_window_get(win->ee);
+       break;
+      default:
+       break;
+     }
+}
+#endif
+
+#ifdef HAVE_ELEMENTARY_X
+static void
+_elm_win_xwin_update(Elm_Win *win)
+{
+   _elm_win_xwindow_get(win);
+   if (win->parent)
+     {
+       Elm_Win *win2;
+
+       win2 = elm_widget_data_get(win->parent);
+       if (win2)
+         {
+            if (win->xwin)
+              ecore_x_icccm_transient_for_set(win->xwin, win2->xwin);
+         }
+     }
+
+   if (!win->xwin) return; /* nothing more to do */
+
+   switch (win->type)
+     {
+      case ELM_WIN_BASIC:
+        ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_NORMAL);
+        break;
+      case ELM_WIN_DIALOG_BASIC:
+        ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DIALOG);
+        break;
+      case ELM_WIN_DESKTOP:
+        ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DESKTOP);
+        break;
+      case ELM_WIN_DOCK:
+        ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DOCK);
+        break;
+      case ELM_WIN_TOOLBAR:
+        ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_TOOLBAR);
+        break;
+      case ELM_WIN_MENU:
+        ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_MENU);
+        break;
+      case ELM_WIN_UTILITY:
+        ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_UTILITY);
+        break;
+      case ELM_WIN_SPLASH:
+        ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_SPLASH);
+        break;
+      default:
+        break;
+     }
+   ecore_x_e_virtual_keyboard_state_set
+     (win->xwin, (Ecore_X_Virtual_Keyboard_State)win->kbdmode);
+}
+#endif
+
+static void
+_elm_win_eval_subobjs(Evas_Object *obj)
+{
+   const Eina_List *l;
+   const Evas_Object *child;
+   
+   Elm_Win *win = elm_widget_data_get(obj);
+   Evas_Coord w, h, minw = -1, minh = -1, maxw = -1, maxh = -1;
+   int xx = 1, xy = 1;
+   double wx, wy;
+
+   EINA_LIST_FOREACH(win->subobjs, l, child)
+     {
+       evas_object_size_hint_weight_get(child, &wx, &wy);
+       if (wx == 0.0) xx = 0;
+       if (wy == 0.0) xy = 0;
+
+       evas_object_size_hint_min_get(child, &w, &h);
+       if (w < 1) w = -1;
+       if (h < 1) h = -1;
+       if (w > minw) minw = w;
+       if (h > minh) minh = h;
+
+       evas_object_size_hint_max_get(child, &w, &h);
+       if (w < 1) w = -1;
+       if (h < 1) h = -1;
+       if (maxw == -1) maxw = w;
+       else if ((w > 0) && (w < maxw)) maxw = w;
+       if (maxh == -1) maxh = h;
+       else if ((h > 0) && (h < maxh)) maxh = h;
+     }
+   if ((maxw >= 0) && (maxw < minw)) maxw = minw;
+   if ((maxh >= 0) && (maxh < minh)) maxh = minh;
+   if (!xx) maxw = minw;
+   else maxw = 32767;
+   if (!xy) maxh = minh;
+   else maxh = 32767;
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+   evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+   if (w < minw) w = minw;
+   if (h < minh) h = minh;
+   if ((maxw >= 0) && (w > maxw)) w = maxw;
+   if ((maxh >= 0) && (h > maxh)) h = maxh;
+   evas_object_resize(obj, w, h);
+}
+
+static void
+_elm_win_subobj_callback_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   elm_win_resize_object_del(data, obj);
+}
+
+static void
+_elm_win_subobj_callback_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _elm_win_eval_subobjs(data);
+}
+
+void
+_elm_win_shutdown(void)
+{
+   while (_elm_win_list)
+     evas_object_del(_elm_win_list->data);
+}
+
+void
+_elm_win_rescale(void)
+{
+   const Eina_List *l;
+   Evas_Object *obj;
+
+   EINA_LIST_FOREACH(_elm_win_list, l, obj)
+     elm_widget_theme(obj);
+}
+
+#ifdef HAVE_ELEMENTARY_X
+static int
+_elm_win_client_message(void *data, int type __UNUSED__, void *event)
+{
+   Elm_Win *win = data;
+   Ecore_X_Event_Client_Message *e = event;
+
+   if (e->format != 32) return 1;
+   if (e->message_type == ECORE_X_ATOM_E_COMP_FLUSH)
+     {
+        if (e->data.l[0] == win->xwin)
+          {
+             Evas *evas = evas_object_evas_get(win->win_obj);
+             if (evas)
+               {
+                  edje_file_cache_flush();
+                  edje_collection_cache_flush();
+                  evas_image_cache_flush(evas);
+                  evas_font_cache_flush(evas);
+               }
+          }
+     }
+   else if (e->message_type == ECORE_X_ATOM_E_COMP_DUMP)
+     {
+        if (e->data.l[0] == win->xwin)
+          {
+             Evas *evas = evas_object_evas_get(win->win_obj);
+             if (evas)
+               {
+                  edje_file_cache_flush();
+                  edje_collection_cache_flush();
+                  evas_image_cache_flush(evas);
+                  evas_font_cache_flush(evas);
+                  evas_render_dump(evas);
+               }
+          }
+     }
+   return 1;
+}
+#endif
+
+/**
+ * Adds a window object. If this is the first window created, pass NULL as
+ * @p parent.
+ *
+ * @param parent Parent object to add the window to, or NULL
+ * @param name The name of the window
+ * @param type The window type, one of the following:
+ * ELM_WIN_BASIC
+ * ELM_WIN_DIALOG_BASIC
+ * ELM_WIN_DESKTOP
+ * ELM_WIN_DOCK
+ * ELM_WIN_TOOLBAR
+ * ELM_WIN_MENU
+ * ELM_WIN_UTILITY
+ * ELM_WIN_SPLASH
+ *
+ * @return The created object, or NULL on failure
+ *
+ * @ingroup Win
+ */
+EAPI Evas_Object *
+elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type)
+{
+   Elm_Win *win;
+   const Eina_List *l;
+   const char *fontpath;
+
+   win = ELM_NEW(Elm_Win);
+   switch (_elm_config->engine)
+     {
+      case ELM_SOFTWARE_X11:
+       win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
+#ifdef HAVE_ELEMENTARY_X
+        win->client_message_handler = ecore_event_handler_add
+          (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
+#endif        
+       break;
+      case ELM_SOFTWARE_FB:
+       win->ee = ecore_evas_fb_new(NULL, 0, 1, 1);
+       break;
+      case ELM_SOFTWARE_DIRECTFB:
+        win->ee = ecore_evas_directfb_new(NULL, 1, 0, 0, 1, 1);
+       break;
+      case ELM_SOFTWARE_16_X11:
+       win->ee = ecore_evas_software_x11_16_new(NULL, 0, 0, 0, 1, 1);
+        if (!win->ee)
+          {
+             CRITICAL("Software-16 engine create failed. Try software.");
+             win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
+          }
+#ifdef HAVE_ELEMENTARY_X
+        win->client_message_handler = ecore_event_handler_add
+          (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
+#endif        
+       break;
+      case ELM_XRENDER_X11:
+       win->ee = ecore_evas_xrender_x11_new(NULL, 0, 0, 0, 1, 1);
+        if (!win->ee)
+          {
+             CRITICAL("XRender engine create failed. Try software.");
+             win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
+          }
+#ifdef HAVE_ELEMENTARY_X
+        win->client_message_handler = ecore_event_handler_add
+          (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
+#endif        
+       break;
+      case ELM_OPENGL_X11:
+       win->ee = ecore_evas_gl_x11_new(NULL, 0, 0, 0, 1, 1);
+        if (!win->ee)
+          {
+             CRITICAL("OpenGL engine create failed. Try software.");
+             win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
+          }
+#ifdef HAVE_ELEMENTARY_X
+        win->client_message_handler = ecore_event_handler_add
+          (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
+#endif        
+       break;
+      case ELM_SOFTWARE_WIN32:
+       win->ee = ecore_evas_software_gdi_new(NULL, 0, 0, 1, 1);
+       break;
+      case ELM_SOFTWARE_16_WINCE:
+       win->ee = ecore_evas_software_wince_gdi_new(NULL, 0, 0, 1, 1);
+       break;
+      case ELM_SOFTWARE_SDL:
+       win->ee = ecore_evas_sdl_new(NULL, 0, 0, 0, 0, 0, 1);
+        if (!win->ee)
+          {
+             CRITICAL("Software SDL engine create failed. Try software.");
+             win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
+          }
+       break;
+      case ELM_SOFTWARE_16_SDL:
+       win->ee = ecore_evas_sdl16_new(NULL, 0, 0, 0, 0, 0, 1);
+        if (!win->ee)
+          {
+             CRITICAL("Sofware-16-SDL engine create failed. Try software.");
+             win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
+          }
+       break;
+      case ELM_OPENGL_SDL:
+       win->ee = ecore_evas_gl_sdl_new(NULL, 1, 1, 0, 0);
+        if (!win->ee)
+          {
+             CRITICAL("OpenGL SDL engine create failed. Try software.");
+             win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
+          }
+       break;
+      default:
+       break;
+     }
+   if (!win->ee)
+     {
+       ERR("Cannot create window.");
+       free(win);
+       return NULL;
+     }
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwindow_get(win);
+#endif   
+   if ((_elm_config->bgpixmap) && (!_elm_config->compositing))
+     ecore_evas_avoid_damage_set(win->ee, ECORE_EVAS_AVOID_DAMAGE_EXPOSE);
+// bg pixmap done by x - has other issues like can be redrawn by x before it
+// is filled/ready by app
+//     ecore_evas_avoid_damage_set(win->ee, ECORE_EVAS_AVOID_DAMAGE_BUILT_IN);
+
+   win->type = type;
+   win->parent = parent;
+   if (win->parent)
+     evas_object_event_callback_add(win->parent, EVAS_CALLBACK_DEL,
+                                    _elm_win_obj_callback_parent_del, win);
+
+   win->evas = ecore_evas_get(win->ee);
+   win->win_obj = elm_widget_add(win->evas);
+   elm_widget_type_set(win->win_obj, "win");
+   ELM_SET_WIDTYPE(widtype, "win");
+   elm_widget_data_set(win->win_obj, win);
+   evas_object_color_set(win->win_obj, 0, 0, 0, 0);
+   evas_object_move(win->win_obj, 0, 0);
+   evas_object_resize(win->win_obj, 1, 1);
+   evas_object_layer_set(win->win_obj, 50);
+   evas_object_pass_events_set(win->win_obj, 1);
+
+   evas_object_intercept_show_callback_add(win->win_obj,
+                                           _elm_win_obj_intercept_show, win);
+   ecore_evas_object_associate(win->ee, win->win_obj,
+                              ECORE_EVAS_OBJECT_ASSOCIATE_BASE |
+                              ECORE_EVAS_OBJECT_ASSOCIATE_STACK |
+                              ECORE_EVAS_OBJECT_ASSOCIATE_LAYER);
+   evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_DEL,
+                                 _elm_win_obj_callback_del, win);
+
+   ecore_evas_name_class_set(win->ee, name, _elm_appname);
+   ecore_evas_callback_delete_request_set(win->ee, _elm_win_delete_request);
+   ecore_evas_callback_resize_set(win->ee, _elm_win_resize);
+   ecore_evas_callback_focus_in_set(win->ee, _elm_win_focus_in);
+   ecore_evas_callback_focus_out_set(win->ee, _elm_win_focus_out);
+   ecore_evas_callback_move_set(win->ee, _elm_win_move);
+   evas_image_cache_set(win->evas, (_elm_config->image_cache * 1024));
+   evas_font_cache_set(win->evas, (_elm_config->font_cache * 1024));
+   EINA_LIST_FOREACH(_elm_config->font_dirs, l, fontpath)
+     evas_font_path_append(win->evas, fontpath);
+   if (_elm_config->font_hinting == 0)
+     evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_NONE);
+   else if (_elm_config->font_hinting == 1)
+     evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_AUTO);
+   else if (_elm_config->font_hinting == 2)
+     evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_BYTECODE);
+
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwin_update(win);
+#endif
+   
+   _elm_win_list = eina_list_append(_elm_win_list, win->win_obj);
+
+   switch (_elm_config->engine)
+     {
+      case ELM_SOFTWARE_16_WINCE:
+      case ELM_SOFTWARE_FB:
+       ecore_evas_fullscreen_set(win->ee, 1);
+       break;
+      case ELM_SOFTWARE_X11:
+      case ELM_SOFTWARE_16_X11:
+      case ELM_XRENDER_X11:
+      case ELM_OPENGL_X11:
+      case ELM_SOFTWARE_WIN32:
+      case ELM_SOFTWARE_SDL:
+      case ELM_SOFTWARE_16_SDL:
+      case ELM_OPENGL_SDL:
+      default:
+       break;
+     }
+   
+   return win->win_obj;
+}
+
+/**
+ * Add @p subobj as a resize object of window @p obj.
+ *
+ * @param obj The window object
+ * @param subobj The resize object to add
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_resize_object_add(Evas_Object *obj, Evas_Object *subobj)
+{
+   Evas_Coord w, h;
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   win->subobjs = eina_list_append(win->subobjs, subobj);
+   elm_widget_sub_object_add(obj, subobj);
+   evas_object_event_callback_add(subobj, EVAS_CALLBACK_DEL,
+                                  _elm_win_subobj_callback_del, obj);
+   evas_object_event_callback_add(subobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                  _elm_win_subobj_callback_changed_size_hints,
+                                  obj);
+   ecore_evas_geometry_get(win->ee, NULL, NULL, &w, &h);
+   evas_object_move(subobj, 0, 0);
+   evas_object_resize(subobj, w, h);
+   _elm_win_eval_subobjs(obj);
+}
+
+/**
+ * Delete @p subobj as a resize object of window @p obj.
+ *
+ * @param obj The window object
+ * @param subobj The resize object to add
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_resize_object_del(Evas_Object *obj, Evas_Object *subobj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   evas_object_event_callback_del_full(subobj,
+                                       EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                       _elm_win_subobj_callback_changed_size_hints,
+                                       obj);
+   evas_object_event_callback_del_full(subobj, EVAS_CALLBACK_DEL,
+                                       _elm_win_subobj_callback_del, obj);
+   win->subobjs = eina_list_remove(win->subobjs, subobj);
+   elm_widget_sub_object_del(obj, subobj);
+   _elm_win_eval_subobjs(obj);
+}
+
+/**
+ * Set the title of the window
+ *
+ * @param obj The window object
+ * @param title The title to set
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_title_set(Evas_Object *obj, const char *title)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   ecore_evas_title_set(win->ee, title);
+}
+
+/**
+ * Set the window's autodel state.
+ *
+ * @param obj The window object
+ * @param autodel If true, the window will automatically delete itself when closed
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_autodel_set(Evas_Object *obj, Eina_Bool autodel)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   win->autodel = autodel;
+}
+
+/**
+ * Activate a window object.
+ *
+ * @param obj The window object
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_activate(Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   ecore_evas_activate(win->ee);
+}
+
+/**
+ * Lower a window object.
+ *
+ * @param obj The window object
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_lower(Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   ecore_evas_lower(win->ee);
+}
+
+/**
+ * Raise a window object.
+ *
+ * @param obj The window object
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_raise(Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   ecore_evas_raise(win->ee);
+}
+
+/**
+ * Set the borderless state of a window.
+ *
+ * @param obj The window object
+ * @param borderless If true, the window is borderless
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_borderless_set(Evas_Object *obj, Eina_Bool borderless)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   ecore_evas_borderless_set(win->ee, borderless);
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwin_update(win);
+#endif
+}
+
+/**
+ * Get the borderless state of a window.
+ *
+ * @param obj The window object
+ * @return If true, the window is borderless
+ *
+ * @ingroup Win
+ */
+EAPI Eina_Bool
+elm_win_borderless_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   win = elm_widget_data_get(obj);
+   if (!win) return EINA_FALSE;
+   return ecore_evas_borderless_get(win->ee);
+}
+
+/**
+ * Set the shaped state of a window.
+ *
+ * @param obj The window object
+ * @param shaped If true, the window is shaped
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_shaped_set(Evas_Object *obj, Eina_Bool shaped)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   ecore_evas_shaped_set(win->ee, shaped);
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwin_update(win);
+#endif
+}
+
+/**
+ * Get the shaped state of a window.
+ *
+ * @param obj The window object
+ * @return If true, the window is shaped
+ *
+ * @ingroup Win
+ */
+EAPI Eina_Bool
+elm_win_shaped_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   win = elm_widget_data_get(obj);
+   if (!win) return EINA_FALSE;
+   return ecore_evas_shaped_get(win->ee);
+}
+
+/**
+ * Set the alpha channel state of a window.
+ *
+ * @param obj The window object
+ * @param alpha If true, the window has an alpha channel
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_alpha_set(Evas_Object *obj, Eina_Bool alpha)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+#ifdef HAVE_ELEMENTARY_X
+   if (win->xwin)
+     {
+       if (alpha)
+         {
+            if (!_elm_config->compositing)
+              elm_win_shaped_set(obj, alpha);
+            else
+              ecore_evas_alpha_set(win->ee, alpha);
+         }
+       else
+         ecore_evas_alpha_set(win->ee, alpha);
+       _elm_win_xwin_update(win);
+     }
+   else
+#endif
+     ecore_evas_alpha_set(win->ee, alpha);
+}
+
+/**
+ * Get the alpha channel state of a window.
+ *
+ * @param obj The window object
+ * @return If true, the window has an alpha channel
+ *
+ * @ingroup Win
+ */
+EAPI Eina_Bool
+elm_win_alpha_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   win = elm_widget_data_get(obj);
+   if (!win) return EINA_FALSE;
+   return ecore_evas_alpha_get(win->ee);
+}
+
+/**
+ * Set the transparency state of a window.
+ *
+ * @param obj The window object
+ * @param transparent If true, the window is transparent
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_transparent_set(Evas_Object *obj, Eina_Bool transparent)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   
+#ifdef HAVE_ELEMENTARY_X
+   if (win->xwin)
+     {
+       ecore_evas_transparent_set(win->ee, transparent);         
+       _elm_win_xwin_update(win);
+     }
+   else
+#endif
+     ecore_evas_transparent_set(win->ee, transparent);
+}
+
+/**
+ * Get the transparency state of a window.
+ *
+ * @param obj The window object
+ * @return If true, the window is transparent
+ *
+ * @ingroup Win
+ */
+EAPI Eina_Bool
+elm_win_transparent_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   win = elm_widget_data_get(obj);
+   if (!win) return EINA_FALSE;
+
+   return ecore_evas_transparent_get(win->ee);
+}
+
+/**
+ * Set the override state of a window.
+ *
+ * @param obj The window object
+ * @param override If true, the window is overridden
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_override_set(Evas_Object *obj, Eina_Bool override)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   ecore_evas_override_set(win->ee, override);
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwin_update(win);
+#endif
+}
+
+/**
+ * Get the override state of a window.
+ *
+ * @param obj The window object
+ * @return If true, the window is overridden
+ *
+ * @ingroup Win
+ */
+EAPI Eina_Bool
+elm_win_override_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   win = elm_widget_data_get(obj);
+   if (!win) return EINA_FALSE;
+   return ecore_evas_override_get(win->ee);
+}
+
+/**
+ * Set the fullscreen state of a window.
+ *
+ * @param obj The window object
+ * @param fullscreen If true, the window is fullscreen
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_fullscreen_set(Evas_Object *obj, Eina_Bool fullscreen)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   switch (_elm_config->engine)
+     {
+     case ELM_SOFTWARE_16_WINCE:
+     case ELM_SOFTWARE_FB:
+       // these engines... can ONLY be fullscreen
+       break;
+     default:
+       ecore_evas_fullscreen_set(win->ee, fullscreen);
+#ifdef HAVE_ELEMENTARY_X
+       _elm_win_xwin_update(win);
+#endif
+       break;
+     }
+}
+
+/**
+ * Get the fullscreen state of a window.
+ *
+ * @param obj The window object
+ * @return If true, the window is fullscreen
+ *
+ * @ingroup Win
+ */
+EAPI Eina_Bool
+elm_win_fullscreen_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   win = elm_widget_data_get(obj);
+   if (!win) return EINA_FALSE;
+   switch (_elm_config->engine)
+     {
+     case ELM_SOFTWARE_16_WINCE:
+     case ELM_SOFTWARE_FB:
+       // these engines... can ONLY be fullscreen
+       return EINA_TRUE;
+       break;
+     default:
+       return ecore_evas_fullscreen_get(win->ee);
+       break;
+     }
+   return EINA_FALSE;
+}
+
+/**
+ * Set the maximized state of a window.
+ *
+ * @param obj The window object
+ * @param maximized If true, the window is maximized
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_maximized_set(Evas_Object *obj, Eina_Bool maximized)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   ecore_evas_maximized_set(win->ee, maximized);
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwin_update(win);
+#endif
+}
+
+/**
+ * Get the maximized state of a window.
+ *
+ * @param obj The window object
+ * @return If true, the window is maximized
+ *
+ * @ingroup Win
+ */
+EAPI Eina_Bool
+elm_win_maximized_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   win = elm_widget_data_get(obj);
+   if (!win) return EINA_FALSE;
+   return ecore_evas_maximized_get(win->ee);
+}
+
+/**
+ * Set the iconified state of a window.
+ *
+ * @param obj The window object
+ * @param iconified If true, the window is iconified
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_iconified_set(Evas_Object *obj, Eina_Bool iconified)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   ecore_evas_iconified_set(win->ee, iconified);
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwin_update(win);
+#endif
+}
+
+/**
+ * Get the iconified state of a window.
+ *
+ * @param obj The window object
+ * @return If true, the window is iconified
+ *
+ * @ingroup Win
+ */
+EAPI Eina_Bool
+elm_win_iconified_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   win = elm_widget_data_get(obj);
+   if (!win) return EINA_FALSE;
+   return ecore_evas_iconified_get(win->ee);
+}
+
+/**
+ * Set the layer of the window.
+ *
+ * @param obj The window object
+ * @param layer The layer of the window
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_layer_set(Evas_Object *obj, int layer)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   ecore_evas_layer_set(win->ee, layer); 
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwin_update(win);
+#endif
+}
+
+/**
+ * Get the layer of the window.
+ *
+ * @param obj The window object
+ * @return The layer of the window
+ *
+ * @ingroup Win
+ */
+EAPI int
+elm_win_layer_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) -1;
+   win = elm_widget_data_get(obj);
+   if (!win) return -1;
+   return ecore_evas_layer_get(win->ee);
+}
+
+/**
+ * Set the rotation of the window.
+ *
+ * @param obj The window object
+ * @param rotation The rotation of the window, in degrees (0-360)
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_rotation_set(Evas_Object *obj, int rotation)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   if (win->rot == rotation) return;
+   win->rot = rotation;
+   ecore_evas_rotation_set(win->ee, rotation);
+   evas_object_size_hint_min_set(obj, -1, -1);
+   evas_object_size_hint_max_set(obj, -1, -1);
+   _elm_win_eval_subobjs(obj);
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwin_update(win);
+#endif
+}
+
+/**
+ * Rotates the window and resizes it
+ *
+ * @param obj The window object
+ * @param layer The rotation of the window in degrees (0-360)
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_rotation_with_resize_set(Evas_Object *obj, int rotation)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   if (win->rot == rotation) return;
+   win->rot = rotation;
+   ecore_evas_rotation_with_resize_set(win->ee, rotation);
+   evas_object_size_hint_min_set(obj, -1, -1);
+   evas_object_size_hint_max_set(obj, -1, -1);
+   _elm_win_eval_subobjs(obj);
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwin_update(win);
+#endif
+}
+
+/**
+ * Get the rotation of the window.
+ *
+ * @param obj The window object
+ * @return The rotation of the window in degrees (0-360)
+ *
+ * @ingroup Win
+ */
+EAPI int
+elm_win_rotation_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) -1;
+   win = elm_widget_data_get(obj);
+   if (!win) return -1;
+   return win->rot;
+}
+
+/**
+ * Set the sticky state of the window.
+ *
+ * @param obj The window object
+ * @param sticky If true, the window's sticky state is enabled
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_sticky_set(Evas_Object *obj, Eina_Bool sticky)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   ecore_evas_sticky_set(win->ee, sticky);
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwin_update(win);
+#endif
+}
+
+/**
+ * Get the sticky state of the window.
+ *
+ * @param obj The window object
+ * @return If true, the window's sticky state is enabled
+ *
+ * @ingroup Win
+ */
+EAPI Eina_Bool
+elm_win_sticky_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   win = elm_widget_data_get(obj);
+   if (!win) return EINA_FALSE;
+   return ecore_evas_sticky_get(win->ee);
+}
+
+/**
+ * Sets the keyboard mode of the window.
+ *
+ * @param obj The window object
+ * @param mode The mode to set; one of:
+ * ELM_WIN_KEYBOARD_UNKNOWN
+ * ELM_WIN_KEYBOARD_OFF
+ * ELM_WIN_KEYBOARD_ON
+ * ELM_WIN_KEYBOARD_ALPHA
+ * ELM_WIN_KEYBOARD_NUMERIC
+ * ELM_WIN_KEYBOARD_PIN
+ * ELM_WIN_KEYBOARD_PHONE_NUMBER
+ * ELM_WIN_KEYBOARD_HEX
+ * ELM_WIN_KEYBOARD_TERMINAL
+ * ELM_WIN_KEYBOARD_PASSWORD
+ * ELM_WIN_KEYBOARD_IP
+ * ELM_WIN_KEYBOARD_HOST
+ * ELM_WIN_KEYBOARD_FILE
+ * ELM_WIN_KEYBOARD_URL
+ * ELM_WIN_KEYBOARD_KEYPAD
+ * ELM_WIN_KEYBOARD_J2ME
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_keyboard_mode_set(Evas_Object *obj, Elm_Win_Keyboard_Mode mode)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   if (mode == win->kbdmode) return;
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwindow_get(win);
+#endif
+   win->kbdmode = mode;
+#ifdef HAVE_ELEMENTARY_X
+   if (win->xwin)
+     ecore_x_e_virtual_keyboard_state_set
+     (win->xwin, (Ecore_X_Virtual_Keyboard_State)win->kbdmode);
+#endif
+}
+
+/**
+ * Sets whether the window is a keyboard.
+ *
+ * @param obj The window object
+ * @param is_keyboard If true, the window is a virtual keyboard
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_keyboard_win_set(Evas_Object *obj, Eina_Bool is_keyboard)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwindow_get(win);
+   if (win->xwin)
+     ecore_x_e_virtual_keyboard_set(win->xwin, is_keyboard);
+#endif
+}
+
+/**
+ * Get the screen position of a window.
+ *
+ * @param obj The window object
+ * @param x The int to store the x coordinate to
+ * @param y The int to store the y coordinate to
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_screen_position_get(const Evas_Object *obj, int *x, int *y)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   if (x) *x = win->screen.x;
+   if (y) *y = win->screen.y;
+}
+
+/**
+ * Set if this window is an illume conformant window
+ *
+ * @param obj The window object
+ * @param conformant The conformant flag (1 = conformant, 0 = non-conformant)
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_conformant_set(Evas_Object *obj, Eina_Bool conformant)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwindow_get(win);
+   if (win->xwin)
+     ecore_x_e_illume_conformant_set(win->xwin, conformant);
+#endif
+}
+
+/**
+ * Get if this window is an illume conformant window
+ *
+ * @param obj The window object
+ * @return A boolean if this window is illume conformant or not
+ *
+ * @ingroup Win
+ */
+EAPI Eina_Bool
+elm_win_conformant_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   win = elm_widget_data_get(obj);
+   if (!win) return EINA_FALSE;
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwindow_get(win);
+   if (win->xwin)
+     return ecore_x_e_illume_conformant_get(win->xwin);
+#endif
+   return EINA_FALSE;
+}
+
+/**
+ * Set a window to be an illume quickpanel window
+ *
+ * By default window objects are not quickpanel windows.
+ *
+ * @param obj The window object
+ * @param quickpanel The quickpanel flag (1 = quickpanel, 0 = normal window)
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_quickpanel_set(Evas_Object *obj, Eina_Bool quickpanel)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwindow_get(win);
+   if (win->xwin)
+     {
+        ecore_x_e_illume_quickpanel_set(win->xwin, quickpanel);
+        if (quickpanel)
+          {
+             Ecore_X_Window_State states[2];
+
+             states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
+             states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
+             ecore_x_netwm_window_state_set(win->xwin, states, 2);
+             ecore_x_icccm_hints_set(win->xwin, 0, 0, 0, 0, 0, 0, 0);
+          }
+     }
+#endif
+}
+
+/**
+ * Get if this window is a quickpanel or not
+ *
+ * @param obj The window object
+ * @return A boolean if this window is a quickpanel or not
+ *
+ * @ingroup Win
+ */
+EAPI Eina_Bool
+elm_win_quickpanel_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   win = elm_widget_data_get(obj);
+   if (!win) return EINA_FALSE;
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwindow_get(win);
+   if (win->xwin)
+     return ecore_x_e_illume_quickpanel_get(win->xwin);
+#endif
+   return EINA_FALSE;
+}
+
+/**
+ * Set the major priority of a quickpanel window
+ *
+ * @param obj The window object
+ * @param priority The major priority for this quickpanel
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_quickpanel_priority_major_set(Evas_Object *obj, int priority)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwindow_get(win);
+   if (win->xwin)
+     ecore_x_e_illume_quickpanel_priority_major_set(win->xwin, priority);
+#endif
+}
+
+/**
+ * Get the major priority of a quickpanel window
+ *
+ * @param obj The window object
+ * @return The major priority of this quickpanel
+ *
+ * @ingroup Win
+ */
+EAPI int
+elm_win_quickpanel_priority_major_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) -1;
+   win = elm_widget_data_get(obj);
+   if (!win) return -1;
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwindow_get(win);
+   if (win->xwin)
+     return ecore_x_e_illume_quickpanel_priority_major_get(win->xwin);
+#endif
+   return -1;
+}
+
+/**
+ * Set the minor priority of a quickpanel window
+ *
+ * @param obj The window object
+ * @param priority The minor priority for this quickpanel
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_quickpanel_priority_minor_set(Evas_Object *obj, int priority)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwindow_get(win);
+   if (win->xwin)
+     ecore_x_e_illume_quickpanel_priority_minor_set(win->xwin, priority);
+#endif
+}
+
+/**
+ * Get the minor priority of a quickpanel window
+ *
+ * @param obj The window object
+ * @return The minor priority of this quickpanel
+ *
+ * @ingroup Win
+ */
+EAPI int
+elm_win_quickpanel_priority_minor_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) -1;
+   win = elm_widget_data_get(obj);
+   if (!win) return -1;
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwindow_get(win);
+   if (win->xwin)
+     return ecore_x_e_illume_quickpanel_priority_minor_get(win->xwin);
+#endif
+   return -1;
+}
+
+/**
+ * Set which zone this quickpanel should appear in
+ *
+ * @param obj The window object
+ * @param zone The requested zone for this quickpanel
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_quickpanel_zone_set(Evas_Object *obj, int zone)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwindow_get(win);
+   if (win->xwin)
+     ecore_x_e_illume_quickpanel_zone_set(win->xwin, zone);
+#endif
+}
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *frm;
+   Evas_Object *content;
+};
+
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+
+static const char *widtype2 = NULL;
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   _elm_theme_object_set(obj, wd->frm, "win", "inwin", elm_widget_style_get(obj));
+   if (wd->content)
+     edje_object_part_swallow(wd->frm, "elm.swallow.content", wd->content);
+   _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord minw = -1, minh = -1;
+
+   evas_object_size_hint_min_get(wd->content, &minw, &minh);
+   edje_object_size_min_calc(wd->frm, &minw, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Object *sub = event_info;
+   if (sub == wd->content)
+     {
+       evas_object_event_callback_del_full
+          (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
+       wd->content = NULL;
+       _sizing_eval(obj);
+     }
+}
+
+/**
+ * @defgroup Inwin Inwin
+ *
+ * An inwin is a window inside a window that is useful for a quick popup.  It does not hover.
+ */
+EAPI Evas_Object *
+elm_win_inwin_add(Evas_Object *obj)
+{
+   Evas_Object *obj2;
+   Widget_Data *wd;
+   Elm_Win *win;
+
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   win = elm_widget_data_get(obj);
+   if (!win) return NULL;
+   wd = ELM_NEW(Widget_Data);
+   obj2 = elm_widget_add(win->evas);
+   elm_widget_type_set(obj2, "inwin");
+   ELM_SET_WIDTYPE(widtype2, "inwin");
+   elm_widget_sub_object_add(obj, obj2);
+   evas_object_size_hint_weight_set(obj2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(obj2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_win_resize_object_add(obj, obj2);
+
+   elm_widget_data_set(obj2, wd);
+   elm_widget_del_hook_set(obj2, _del_hook);
+   elm_widget_theme_hook_set(obj2, _theme_hook);
+
+   wd->frm = edje_object_add(win->evas);
+   _elm_theme_object_set(obj, wd->frm, "win", "inwin", "default");
+   elm_widget_resize_object_set(obj2, wd->frm);
+
+   evas_object_smart_callback_add(obj2, "sub-object-del", _sub_del, obj2);
+
+   _sizing_eval(obj2);
+   return obj2;
+}
+
+/**
+ * Activates an inwin object
+ *
+ * @param obj The inwin to activate
+ *
+ * @ingroup Inwin
+ */
+EAPI void
+elm_win_inwin_activate(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype2);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   evas_object_raise(obj);
+   evas_object_show(obj);
+   edje_object_signal_emit(wd->frm, "elm,action,show", "elm");
+   elm_widget_focused_object_clear(elm_widget_parent_get(obj));
+}
+
+/**
+ * Set the content of an inwin object.
+ *
+ * @param obj The inwin object
+ * @param content The object to set as content
+ *
+ * @ingroup Inwin
+ */
+EAPI void
+elm_win_inwin_content_set(Evas_Object *obj, Evas_Object *content)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype2);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if ((wd->content) && (wd->content != content))
+     elm_widget_sub_object_del(obj, wd->content);
+   wd->content = content;
+   if (content)
+     {
+       elm_widget_sub_object_add(obj, content);
+       evas_object_event_callback_add(content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                      _changed_size_hints, obj);
+       edje_object_part_swallow(wd->frm, "elm.swallow.content", content);
+       _sizing_eval(obj);
+     }
+}
+
+/* windowing spcific calls - shall we do this differently? */
+/**
+ * Get the Ecore_X_Window of an Evas_Object
+ *
+ * @param obj The object
+ *
+ * @return The Ecore_X_Window of @p obj
+ *
+ * @ingroup Win
+ */
+EAPI Ecore_X_Window
+elm_win_xwindow_get(const Evas_Object *obj)
+{
+   Ecore_X_Window xwin = 0;
+   Ecore_Evas *ee = NULL;
+   if (!obj) return 0;
+#ifdef HAVE_ELEMENTARY_X
+   ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
+   if (ee) xwin = (Ecore_X_Window)ecore_evas_window_get(ee);
+   return xwin;
+#else
+   return 0;
+#endif
+}
diff --git a/src/lib/els_box.c b/src/lib/els_box.c
new file mode 100644 (file)
index 0000000..3d6d2c8
--- /dev/null
@@ -0,0 +1,222 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+static void
+_smart_extents_calculate(Evas_Object *box, Evas_Object_Box_Data *priv, int horizontal, int homogeneous)
+{
+   Evas_Coord minw, minh, maxw, maxh, mnw, mnh;
+   const Eina_List *l;
+   Evas_Object_Box_Option *opt;
+
+   /* FIXME: need to calc max */
+   minw = 0;
+   minh = 0;
+   maxw = -1;
+   maxh = -1;
+   if (homogeneous)
+     {
+       EINA_LIST_FOREACH(priv->children, l, opt)
+         {
+            evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
+            if (minh < mnh) minh = mnh;
+            if (minw < mnw) minw = mnw;
+         }
+       if (horizontal)
+          minw *= eina_list_count(priv->children);
+       else
+          minh *= eina_list_count(priv->children);
+     }
+   else
+     {
+       EINA_LIST_FOREACH(priv->children, l, opt)
+         {
+            evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
+            if (horizontal)
+              {
+                 if (minh < mnh) minh = mnh;
+                 minw += mnw;
+              }
+            else
+              {
+                 if (minw < mnw) minw = mnw;
+                 minh += mnh;
+              }
+         }
+     }
+   evas_object_size_hint_min_set(box, minw, minh);
+}
+
+void
+_els_box_layout(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal, int homogeneous)
+{
+   Evas_Coord x, y, w, h, xx, yy;
+   const Eina_List *l;
+   Evas_Object *obj;
+   Evas_Coord minw, minh, wdif, hdif;
+   int count = 0, expand = 0;
+   double ax, ay;
+   Evas_Object_Box_Option *opt;
+
+   _smart_extents_calculate(o, priv, horizontal, homogeneous);
+
+   evas_object_geometry_get(o, &x, &y, &w, &h);
+
+   evas_object_size_hint_min_get(o, &minw, &minh);
+   evas_object_size_hint_align_get(o, &ax, &ay);
+   count = eina_list_count(priv->children);
+   if (w < minw)
+     {
+       x = x + ((w - minw) * (1.0 - ax));
+       w = minw;
+     }
+   if (h < minh)
+     {
+       y = y + ((h - minh) * (1.0 - ay));
+       h = minh;
+     }
+   EINA_LIST_FOREACH(priv->children, l, opt)
+     {
+        double wx, wy;
+
+       evas_object_size_hint_weight_get(opt->obj, &wx, &wy);
+       if (horizontal)
+         {
+            if (wx > 0.0) expand++;
+         }
+       else
+         {
+            if (wy > 0.0) expand++;
+         }
+     }
+   if (expand == 0)
+     {
+       evas_object_size_hint_align_get(o, &ax, &ay);
+       if (horizontal)
+         {
+            x += (double)(w - minw) * ax;
+            w = minw;
+         }
+       else
+         {
+            y += (double)(h - minh) * ay;
+            h = minh;
+         }
+     }
+   wdif = w - minw;
+   hdif = h - minh;
+   xx = x;
+   yy = y;
+   EINA_LIST_FOREACH(priv->children, l, opt)
+     {
+        Evas_Coord mnw, mnh, mxw, mxh;
+        double wx, wy;
+        int fw, fh, xw, xh;
+
+       obj = opt->obj;
+       evas_object_size_hint_align_get(obj, &ax, &ay);
+       evas_object_size_hint_weight_get(obj, &wx, &wy);
+       evas_object_size_hint_min_get(obj, &mnw, &mnh);
+       evas_object_size_hint_max_get(obj, &mxw, &mxh);
+       fw = fh = 0;
+       xw = xh = 0;
+       if (ax == -1.0) {fw = 1; ax = 0.5;}
+       if (ay == -1.0) {fh = 1; ay = 0.5;}
+       if (wx > 0.0) xw = 1;
+       if (wy > 0.0) xh = 1;
+       if (horizontal)
+         {
+            if (homogeneous)
+              {
+                 Evas_Coord ww, hh, ow, oh;
+
+                 ww = (w / (Evas_Coord)count);
+                 hh = h;
+                 ow = mnw;
+                 if (fw) ow = ww;
+                 if ((mxw >= 0) && (mxw < ow))
+                   ow = mxw;
+                 oh = mnh;
+                 if (fh) oh = hh;
+                 if ((mxh >= 0) && (mxh < oh))
+                   oh = mxh;
+                 evas_object_move(obj,
+                                  xx + (Evas_Coord)(((double)(ww - ow)) * ax),
+                                  yy + (Evas_Coord)(((double)(hh - oh)) * ay));
+                 evas_object_resize(obj, ow, oh);
+                 xx += ww;
+              }
+            else
+              {
+                 Evas_Coord ww, hh, ow, oh;
+
+                 ww = mnw;
+                 if ((expand > 0) && (xw))
+                   {
+                      if (expand == 1) ow = wdif;
+                      else ow = (w - minw) / expand;
+                      wdif -= ow;
+                      ww += ow;
+                   }
+                 hh = h;
+                 ow = mnw;
+                 if (fw) ow = ww;
+                 if ((mxw >= 0) && (mxw < ow)) ow = mxw;
+                 oh = mnh;
+                 if (fh) oh = hh;
+                 if ((mxh >= 0) && (mxh < oh)) oh = mxh;
+                 evas_object_move(obj,
+                                  xx + (Evas_Coord)(((double)(ww - ow)) * ax),
+                                  yy + (Evas_Coord)(((double)(hh - oh)) * ay));
+                 evas_object_resize(obj, ow, oh);
+                 xx += ww;
+              }
+         }
+       else
+         {
+            if (homogeneous)
+              {
+                 Evas_Coord ww, hh, ow, oh;
+
+                 ww = w;
+                 hh = (h / (Evas_Coord)count);
+                 ow = mnw;
+                 if (fw) ow = ww;
+                 if ((mxw >= 0) && (mxw < ow)) ow = mxw;
+                 oh = mnh;
+                 if (fh) oh = hh;
+                 if ((mxh >= 0) && (mxh < oh)) oh = mxh;
+                 evas_object_move(obj,
+                                  xx + (Evas_Coord)(((double)(ww - ow)) * ax),
+                                  yy + (Evas_Coord)(((double)(hh - oh)) * ay));
+                 evas_object_resize(obj, ow, oh);
+                 yy += hh;
+              }
+            else
+              {
+                 Evas_Coord ww, hh, ow, oh;
+
+                 ww = w;
+                 hh = mnh;
+                 if ((expand > 0) && (xh))
+                   {
+                      if (expand == 1) oh = hdif;
+                      else oh = (h - minh) / expand;
+                      hdif -= oh;
+                      hh += oh;
+                   }
+                 ow = mnw;
+                 if (fw) ow = ww;
+                 if ((mxw >= 0) && (mxw < ow)) ow = mxw;
+                 oh = mnh;
+                 if (fh) oh = hh;
+                 if ((mxh >= 0) && (mxh < oh)) oh = mxh;
+                 evas_object_move(obj,
+                                  xx + (Evas_Coord)(((double)(ww - ow)) * ax),
+                                  yy + (Evas_Coord)(((double)(hh - oh)) * ay));
+                 evas_object_resize(obj, ow, oh);
+                 yy += hh;
+              }
+         }
+     }
+}
+
diff --git a/src/lib/els_box.h b/src/lib/els_box.h
new file mode 100644 (file)
index 0000000..e394884
--- /dev/null
@@ -0,0 +1 @@
+void _els_box_layout(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal, int homogeneous);
diff --git a/src/lib/els_icon.c b/src/lib/els_icon.c
new file mode 100644 (file)
index 0000000..371b16b
--- /dev/null
@@ -0,0 +1,554 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+typedef struct _Smart_Data Smart_Data;
+
+struct _Smart_Data
+{
+   Evas_Coord   x, y, w, h;
+   Evas_Object *obj;
+   int          size;
+   double       scale;
+   unsigned char fill_inside : 1;
+   unsigned char scale_up : 1;
+   unsigned char scale_down : 1;
+};
+
+/* local subsystem functions */
+static void _smart_reconfigure(Smart_Data *sd);
+static void _smart_init(void);
+static void _smart_add(Evas_Object *obj);
+static void _smart_del(Evas_Object *obj);
+static void _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+static void _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
+static void _smart_show(Evas_Object *obj);
+static void _smart_hide(Evas_Object *obj);
+static void _smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
+static void _smart_clip_set(Evas_Object *obj, Evas_Object * clip);
+static void _smart_clip_unset(Evas_Object *obj);
+
+static void _els_smart_icon_flip_horizontal(Smart_Data *sd);
+static void _els_smart_icon_flip_vertical(Smart_Data *sd);
+static void _els_smart_icon_rotate_180(Smart_Data *sd);
+
+/* local subsystem globals */
+static Evas_Smart *_e_smart = NULL;
+
+/* externally accessible functions */
+Evas_Object *
+_els_smart_icon_add(Evas *evas)
+{
+   _smart_init();
+   return evas_object_smart_add(evas, _e_smart);
+}
+
+Eina_Bool
+_els_smart_icon_file_key_set(Evas_Object *obj, const char *file, const char *key)
+{
+   Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return 0;
+   /* smart code here */
+   if (sd->size != 0)
+     evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
+   evas_object_image_file_set(sd->obj, file, key);
+   if (evas_object_image_load_error_get(sd->obj) != EVAS_LOAD_ERROR_NONE)
+     return 0;
+   _smart_reconfigure(sd);
+   return 1;
+}
+
+Eina_Bool
+_els_smart_icon_file_edje_set(Evas_Object *obj, const char *file, const char *part)
+{
+   Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return 0;
+   /* smart code here */
+   if (sd->obj) evas_object_del(sd->obj);
+   sd->obj = edje_object_add(evas_object_evas_get(obj));
+   evas_object_smart_member_add(sd->obj, obj);
+   if (!edje_object_file_set(sd->obj, file, part))
+     return 0;
+   _smart_reconfigure(sd);
+   return 1;
+}
+
+void
+_els_smart_icon_smooth_scale_set(Evas_Object *obj, int smooth)
+{
+   Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (!strcmp(evas_object_type_get(sd->obj), "edje"))
+     return;
+   evas_object_image_smooth_scale_set(sd->obj, smooth);
+}
+
+void
+_els_smart_icon_size_get(Evas_Object *obj, int *w, int *h)
+{
+   Smart_Data *sd;
+   int tw, th;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (!strcmp(evas_object_type_get(sd->obj), "edje"))
+     edje_object_size_min_get(sd->obj, &tw, &th);
+   else
+     evas_object_image_size_get(sd->obj, &tw, &th);
+   tw = ((double)tw) * sd->scale;
+   th = ((double)th) * sd->scale;
+   if (w) *w = tw;
+   if (h) *h = th;
+}
+
+void
+_els_smart_icon_fill_inside_set(Evas_Object *obj, int fill_inside)
+{
+   Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (((sd->fill_inside) && (fill_inside)) ||
+       ((!sd->fill_inside) && (!fill_inside))) return;
+   sd->fill_inside = fill_inside;
+   _smart_reconfigure(sd);
+}
+
+void
+_els_smart_icon_scale_up_set(Evas_Object *obj, int scale_up)
+{
+   Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (((sd->scale_up) && (scale_up)) ||
+       ((!sd->scale_up) && (!scale_up))) return;
+   sd->scale_up = scale_up;
+   _smart_reconfigure(sd);
+}
+
+void
+_els_smart_icon_scale_down_set(Evas_Object *obj, int scale_down)
+{
+   Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (((sd->scale_down) && (scale_down)) ||
+       ((!sd->scale_down) && (!scale_down))) return;
+   sd->scale_down = scale_down;
+   _smart_reconfigure(sd);
+}
+
+void
+_els_smart_icon_scale_size_set(Evas_Object *obj, int size)
+{
+   Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   sd->size = size;
+   if (!sd->obj) return;
+   if (!strcmp(evas_object_type_get(sd->obj), "edje"))
+     return;
+   evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
+}
+
+void
+_els_smart_icon_scale_set(Evas_Object *obj, double scale)
+{
+   Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   sd->scale = scale;
+   _smart_reconfigure(sd);
+}
+
+void
+_els_smart_icon_orient_set(Evas_Object *obj, Elm_Image_Orient orient)
+{
+   Smart_Data *sd;
+   Evas_Object    *tmp;
+   unsigned int   *data, *data2, *to, *from;
+   int             x, y, w, hw, iw, ih;
+   const char     *file, *key;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (!strcmp(evas_object_type_get(sd->obj), "edje"))
+     return;
+
+   switch (orient)
+     {
+      case ELM_IMAGE_FLIP_HORIZONTAL:
+         _els_smart_icon_flip_horizontal(sd);
+         return;
+      case ELM_IMAGE_FLIP_VERTICAL:
+         _els_smart_icon_flip_vertical(sd);
+        return;
+      case ELM_IMAGE_ROTATE_180_CW:
+         _els_smart_icon_rotate_180(sd);
+         return;
+     default:
+        return;
+     }
+
+   evas_object_image_size_get(sd->obj, &iw, &ih);
+   evas_object_image_file_get(sd->obj, &file, &key);
+   tmp = evas_object_image_add(evas_object_evas_get(sd->obj));
+   evas_object_image_file_set(tmp, file, key);
+   data2 = evas_object_image_data_get(tmp, 0);
+
+   w = ih;
+   ih = iw;
+   iw = w;
+   hw = w * ih;
+
+   evas_object_image_size_set(sd->obj, iw, ih);
+   data = evas_object_image_data_get(sd->obj, 1);
+   switch (orient)
+     {
+      case ELM_IMAGE_FLIP_TRANSPOSE:
+        to = data;
+        hw = -hw + 1;
+        break;
+      case ELM_IMAGE_FLIP_TRANSVERSE:
+        to = data + hw - 1;
+        w = -w;
+        hw = hw - 1;
+        break;
+      case ELM_IMAGE_ROTATE_90_CW:
+        to = data + w - 1;
+        hw = -hw - 1;
+        break;
+      case ELM_IMAGE_ROTATE_90_CCW:
+        to = data + hw - w;
+        w = -w;
+        hw = hw + 1;
+        break;
+      default:
+        ERR("unknown orient %d", orient);
+        evas_object_del(tmp);
+        evas_object_image_data_set(sd->obj, data); // give it back
+        return;
+     }
+   from = data2;
+   for (x = iw; --x >= 0;)
+     {
+        for (y = ih; --y >= 0;)
+          {
+             *to = *from;
+             from++;
+             to += w;
+          }
+        to += hw;
+     }
+   evas_object_del(tmp);
+   evas_object_image_data_set(sd->obj, data);
+   evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
+   _smart_reconfigure(sd);
+}
+
+/* local subsystem globals */
+static void
+_smart_reconfigure(Smart_Data *sd)
+{
+   int iw, ih;
+   Evas_Coord x, y, w, h;
+
+   if (!sd->obj) return;
+   if (!strcmp(evas_object_type_get(sd->obj), "edje"))
+     {
+       w = sd->w;
+       h = sd->h;
+       x = sd->x;
+       y = sd->y;
+       evas_object_move(sd->obj, x, y);
+       evas_object_resize(sd->obj, w, h);
+     }
+   else
+     {
+       iw = 0;
+       ih = 0;
+       evas_object_image_size_get(sd->obj, &iw, &ih);
+
+       iw = ((double)iw) * sd->scale;
+       ih = ((double)ih) * sd->scale;
+
+       if (iw < 1) iw = 1;
+       if (ih < 1) ih = 1;
+
+       if (sd->fill_inside)
+         {
+            w = sd->w;
+            h = ((double)ih * w) / (double)iw;
+            if (h > sd->h)
+              {
+                 h = sd->h;
+                 w = ((double)iw * h) / (double)ih;
+              }
+         }
+       else
+         {
+            w = sd->w;
+            h = ((double)ih * w) / (double)iw;
+            if (h < sd->h)
+              {
+                 h = sd->h;
+                 w = ((double)iw * h) / (double)ih;
+              }
+         }
+       if (!sd->scale_up)
+         {
+            if ((w > iw) || (h > ih))
+              {
+                 w = iw;
+                 h = ih;
+              }
+         }
+       if (!sd->scale_down)
+         {
+            if ((w < iw) || (h < ih))
+              {
+                 w = iw;
+                 h = ih;
+              }
+         }
+       x = sd->x + ((sd->w - w) / 2);
+       y = sd->y + ((sd->h - h) / 2);
+       evas_object_move(sd->obj, x, y);
+       evas_object_image_fill_set(sd->obj, 0, 0, w, h);
+       evas_object_resize(sd->obj, w, h);
+     }
+}
+
+static void
+_smart_init(void)
+{
+   if (_e_smart) return;
+     {
+       static const Evas_Smart_Class sc =
+         {
+            "e_icon",
+              EVAS_SMART_CLASS_VERSION,
+              _smart_add,
+              _smart_del,
+              _smart_move,
+              _smart_resize,
+              _smart_show,
+              _smart_hide,
+              _smart_color_set,
+              _smart_clip_set,
+              _smart_clip_unset,
+              NULL,
+              NULL,
+              NULL,
+              NULL,
+               NULL,
+               NULL,
+               NULL
+         };
+       _e_smart = evas_smart_class_new(&sc);
+     }
+}
+
+static void
+_smart_add(Evas_Object *obj)
+{
+   Smart_Data *sd;
+
+   sd = calloc(1, sizeof(Smart_Data));
+   if (!sd) return;
+   sd->obj = evas_object_image_add(evas_object_evas_get(obj));
+   evas_object_image_scale_hint_set(sd->obj, EVAS_IMAGE_SCALE_HINT_STATIC);
+   sd->x = 0;
+   sd->y = 0;
+   sd->w = 0;
+   sd->h = 0;
+   sd->fill_inside = 1;
+   sd->scale_up = 1;
+   sd->scale_down = 1;
+   sd->size = 64;
+   sd->scale = 1.0;
+   evas_object_smart_member_add(sd->obj, obj);
+   evas_object_smart_data_set(obj, sd);
+}
+
+static void
+_smart_del(Evas_Object *obj)
+{
+   Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   evas_object_del(sd->obj);
+   free(sd);
+}
+
+static void
+_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if ((sd->x == x) && (sd->y == y)) return;
+   sd->x = x;
+   sd->y = y;
+   _smart_reconfigure(sd);
+}
+
+static void
+_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+   Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if ((sd->w == w) && (sd->h == h)) return;
+   sd->w = w;
+   sd->h = h;
+   _smart_reconfigure(sd);
+}
+
+static void
+_smart_show(Evas_Object *obj)
+{
+   Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   evas_object_show(sd->obj);
+}
+
+static void
+_smart_hide(Evas_Object *obj)
+{
+   Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   evas_object_hide(sd->obj);
+}
+
+static void
+_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
+{
+   Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   evas_object_color_set(sd->obj, r, g, b, a);
+}
+
+static void
+_smart_clip_set(Evas_Object *obj, Evas_Object * clip)
+{
+   Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   evas_object_clip_set(sd->obj, clip);
+}
+
+static void
+_smart_clip_unset(Evas_Object *obj)
+{
+   Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   evas_object_clip_unset(sd->obj);
+}
+
+static void
+_els_smart_icon_flip_horizontal(Smart_Data *sd)
+{
+   unsigned int   *data;
+   unsigned int   *p1, *p2, tmp;
+   int             x, y, iw, ih;
+
+   evas_object_image_size_get(sd->obj, &iw, &ih);
+   data = evas_object_image_data_get(sd->obj, 1);
+
+   for (y = 0; y < ih; y++)
+     {
+        p1 = data + (y * iw);
+        p2 = data + ((y + 1) * iw) - 1;
+        for (x = 0; x < (iw >> 1); x++)
+          {
+             tmp = *p1;
+             *p1 = *p2;
+             *p2 = tmp;
+             p1++;
+             p2--;
+          }
+     }
+
+   evas_object_image_data_set(sd->obj, data);
+   evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
+   _smart_reconfigure(sd);
+}
+
+static void
+_els_smart_icon_flip_vertical(Smart_Data *sd)
+{
+   unsigned int   *data;
+   unsigned int   *p1, *p2, tmp;
+   int             x, y, iw, ih;
+
+   evas_object_image_size_get(sd->obj, &iw, &ih);
+   data = evas_object_image_data_get(sd->obj, 1);
+
+   for (y = 0; y < (ih >> 1); y++)
+     {
+        p1 = data + (y * iw);
+        p2 = data + ((ih - 1 - y) * iw);
+        for (x = 0; x < iw; x++)
+          {
+             tmp = *p1;
+             *p1 = *p2;
+             *p2 = tmp;
+             p1++;
+             p2++;
+          }
+     }
+
+   evas_object_image_data_set(sd->obj, data);
+   evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
+   _smart_reconfigure(sd);
+}
+
+static void
+_els_smart_icon_rotate_180(Smart_Data *sd)
+{
+   unsigned int   *data;
+   unsigned int   *p1, *p2, tmp;
+   int             x, hw, iw, ih;
+
+   evas_object_image_size_get(sd->obj, &iw, &ih);
+   data = evas_object_image_data_get(sd->obj, 1);
+
+   hw = iw * ih;
+   x = (hw / 2);
+   p1 = data;
+   p2 = data + hw - 1;
+   for (; --x > 0;)
+     {
+        tmp = *p1;
+        *p1 = *p2;
+        *p2 = tmp;
+        p1++;
+        p2--;
+     }
+   evas_object_image_data_set(sd->obj, data);
+   evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
+   _smart_reconfigure(sd);
+}
+
diff --git a/src/lib/els_icon.h b/src/lib/els_icon.h
new file mode 100644 (file)
index 0000000..b483305
--- /dev/null
@@ -0,0 +1,11 @@
+Evas_Object *_els_smart_icon_add              (Evas *evas);
+Eina_Bool    _els_smart_icon_file_key_set     (Evas_Object *obj, const char *file, const char *key);
+Eina_Bool    _els_smart_icon_file_edje_set    (Evas_Object *obj, const char *file, const char *part);
+void         _els_smart_icon_smooth_scale_set (Evas_Object *obj, int smooth);
+void         _els_smart_icon_size_get         (Evas_Object *obj, int *w, int *h);
+void         _els_smart_icon_fill_inside_set  (Evas_Object *obj, int fill_inside);
+void         _els_smart_icon_scale_up_set     (Evas_Object *obj, int scale_up);
+void         _els_smart_icon_scale_down_set   (Evas_Object *obj, int scale_down);
+void         _els_smart_icon_scale_size_set   (Evas_Object *obj, int size);
+void         _els_smart_icon_scale_set        (Evas_Object *obj, double scale);
+void         _els_smart_icon_orient_set       (Evas_Object *obj, Elm_Image_Orient orient);
diff --git a/src/lib/els_pan.c b/src/lib/els_pan.c
new file mode 100644 (file)
index 0000000..f1982fc
--- /dev/null
@@ -0,0 +1,275 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+#define SMART_NAME "elm_pan"
+#define API_ENTRY Smart_Data *sd; sd = evas_object_smart_data_get(obj); if ((!obj) || (!sd) || (evas_object_type_get(obj) && strcmp(evas_object_type_get(obj), SMART_NAME)))
+#define INTERNAL_ENTRY Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return;
+typedef struct _Smart_Data Smart_Data;
+
+struct _Smart_Data
+{
+   Evas_Object *smart_obj;
+   Evas_Object *child_obj;
+   Evas_Coord   x, y, w, h;
+   Evas_Coord   child_w, child_h, px, py;
+};
+
+/* local subsystem functions */
+static void _smart_child_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _smart_child_resize_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+static void _smart_reconfigure(Smart_Data *sd);
+static void _smart_add(Evas_Object *obj);
+static void _smart_del(Evas_Object *obj);
+static void _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+static void _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
+static void _smart_show(Evas_Object *obj);
+static void _smart_hide(Evas_Object *obj);
+static void _smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
+static void _smart_clip_set(Evas_Object *obj, Evas_Object * clip);
+static void _smart_clip_unset(Evas_Object *obj);
+static void _smart_init(void);
+
+/* local subsystem globals */
+static Evas_Smart *_smart = NULL;
+
+/* externally accessible functions */
+Evas_Object *
+_elm_smart_pan_add(Evas *evas)
+{
+   _smart_init();
+   return evas_object_smart_add(evas, _smart);
+}
+
+void
+_elm_smart_pan_child_set(Evas_Object *obj, Evas_Object *child)
+{
+   API_ENTRY return;
+   if (child == sd->child_obj) return;
+   if (sd->child_obj)
+     {
+       evas_object_clip_unset(sd->child_obj);
+       evas_object_smart_member_del(sd->child_obj);
+        evas_object_event_callback_del_full(sd->child_obj, EVAS_CALLBACK_FREE, _smart_child_del_hook, sd);
+       evas_object_event_callback_del_full(sd->child_obj, EVAS_CALLBACK_RESIZE, _smart_child_resize_hook, sd);
+       sd->child_obj = NULL;
+     }
+   if (child)
+     {
+       Evas_Coord w, h;
+       int r, g, b, a;
+
+       sd->child_obj = child;
+       evas_object_smart_member_add(sd->child_obj, sd->smart_obj);
+       evas_object_geometry_get(sd->child_obj, NULL, NULL, &w, &h);
+       sd->child_w = w;
+       sd->child_h = h;
+       evas_object_event_callback_add(child, EVAS_CALLBACK_FREE, _smart_child_del_hook, sd);
+       evas_object_event_callback_add(child, EVAS_CALLBACK_RESIZE, _smart_child_resize_hook, sd);
+       evas_object_color_get(sd->smart_obj, &r, &g, &b, &a);
+       evas_object_color_set(sd->child_obj, r, g, b, a);
+       evas_object_clip_set(sd->child_obj, evas_object_clip_get(sd->smart_obj));
+       if (evas_object_visible_get(sd->smart_obj)) evas_object_show(sd->child_obj);
+       else evas_object_hide(sd->child_obj);
+       _smart_reconfigure(sd);
+     }
+   evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
+}
+
+Evas_Object *
+_elm_smart_pan_child_get(Evas_Object *obj)
+{
+   API_ENTRY return NULL;
+   return sd->child_obj;
+}
+
+void
+_elm_smart_pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   API_ENTRY return;
+//   if (x > (sd->child_w - sd->w)) x = sd->child_w - sd->w;
+//   if (y > (sd->child_h - sd->h)) y = sd->child_h - sd->h;
+//   if (x < 0) x = 0;
+//   if (y < 0) y = 0;
+   if ((x == sd->px) && (y == sd->py)) return;
+   sd->px = x;
+   sd->py = y;
+   _smart_reconfigure(sd);
+   evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
+}
+
+void
+_elm_smart_pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+   API_ENTRY return;
+   if (x) *x = sd->px;
+   if (y) *y = sd->py;
+}
+
+void
+_elm_smart_pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+   API_ENTRY return;
+   if (x)
+     {
+       if (sd->w < sd->child_w) *x = sd->child_w - sd->w;
+       else *x = 0;
+     }
+   if (y)
+     {
+       if (sd->h < sd->child_h) *y = sd->child_h - sd->h;
+       else *y = 0;
+     }
+}
+
+void
+_elm_smart_pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
+{
+   API_ENTRY return;
+   if (w) *w = sd->child_w;
+   if (h) *h = sd->child_h;
+}
+
+/* local subsystem functions */
+static void
+_smart_child_del_hook(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Smart_Data *sd;
+
+   sd = data;
+   sd->child_obj = NULL;
+   evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
+}
+
+static void
+_smart_child_resize_hook(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Smart_Data *sd;
+   Evas_Coord w, h;
+
+   sd = data;
+   evas_object_geometry_get(sd->child_obj, NULL, NULL, &w, &h);
+   if ((w != sd->child_w) || (h != sd->child_h))
+     {
+       sd->child_w = w;
+       sd->child_h = h;
+       _smart_reconfigure(sd);
+     }
+   evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
+}
+
+static void
+_smart_reconfigure(Smart_Data *sd)
+{
+   evas_object_move(sd->child_obj, sd->x - sd->px, sd->y - sd->py);
+}
+
+static void
+_smart_add(Evas_Object *obj)
+{
+   Smart_Data *sd;
+
+   sd = calloc(1, sizeof(Smart_Data));
+   if (!sd) return;
+   sd->smart_obj = obj;
+   sd->x = 0;
+   sd->y = 0;
+   sd->w = 0;
+   sd->h = 0;
+   evas_object_smart_data_set(obj, sd);
+}
+
+static void
+_smart_del(Evas_Object *obj)
+{
+   INTERNAL_ENTRY;
+   _elm_smart_pan_child_set(obj, NULL);
+   free(sd);
+}
+
+static void
+_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   INTERNAL_ENTRY;
+   sd->x = x;
+   sd->y = y;
+   _smart_reconfigure(sd);
+}
+
+static void
+_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+   INTERNAL_ENTRY;
+   sd->w = w;
+   sd->h = h;
+   _smart_reconfigure(sd);
+   evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
+}
+
+static void
+_smart_show(Evas_Object *obj)
+{
+   INTERNAL_ENTRY;
+   evas_object_show(sd->child_obj);
+}
+
+static void
+_smart_hide(Evas_Object *obj)
+{
+   INTERNAL_ENTRY;
+   evas_object_hide(sd->child_obj);
+}
+
+static void
+_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
+{
+   INTERNAL_ENTRY;
+   evas_object_color_set(sd->child_obj, r, g, b, a);
+}
+
+static void
+_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
+{
+   INTERNAL_ENTRY;
+   evas_object_clip_set(sd->child_obj, clip);
+}
+
+static void
+_smart_clip_unset(Evas_Object *obj)
+{
+   INTERNAL_ENTRY;
+   evas_object_clip_unset(sd->child_obj);
+}
+
+/* never need to touch this */
+
+static void
+_smart_init(void)
+{
+   if (_smart) return;
+     {
+       static const Evas_Smart_Class sc =
+         {
+            SMART_NAME,
+              EVAS_SMART_CLASS_VERSION,
+              _smart_add,
+              _smart_del,
+              _smart_move,
+              _smart_resize,
+              _smart_show,
+              _smart_hide,
+              _smart_color_set,
+              _smart_clip_set,
+              _smart_clip_unset,
+              NULL,
+              NULL,
+              NULL,
+              NULL,
+              NULL,
+              NULL,
+              NULL
+         };
+       _smart = evas_smart_class_new(&sc);
+     }
+}
+
diff --git a/src/lib/els_pan.h b/src/lib/els_pan.h
new file mode 100644 (file)
index 0000000..a2ce00c
--- /dev/null
@@ -0,0 +1,7 @@
+Evas_Object *_elm_smart_pan_add            (Evas *evas);
+void         _elm_smart_pan_child_set      (Evas_Object *obj, Evas_Object *child);
+Evas_Object *_elm_smart_pan_child_get      (Evas_Object *obj);
+void         _elm_smart_pan_set            (Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+void         _elm_smart_pan_get            (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y);
+void         _elm_smart_pan_max_get        (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y);
+void         _elm_smart_pan_child_size_get (Evas_Object *obj, Evas_Coord *w, Evas_Coord *h);
diff --git a/src/lib/els_scroller.c b/src/lib/els_scroller.c
new file mode 100644 (file)
index 0000000..0af0fd4
--- /dev/null
@@ -0,0 +1,2447 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+#define SMART_NAME "els_scroller"
+#define API_ENTRY Smart_Data *sd; sd = evas_object_smart_data_get(obj); if ((!obj) || (!sd) || (evas_object_type_get(obj) && strcmp(evas_object_type_get(obj), SMART_NAME)))
+#define INTERNAL_ENTRY Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return;
+typedef struct _Smart_Data Smart_Data;
+
+#define EVTIME 1
+//#define SCROLLDBG 1
+
+struct _Smart_Data
+{
+   Evas_Coord   x, y, w, h;
+
+   Evas_Object *smart_obj;
+   Evas_Object *child_obj;
+   Evas_Object *pan_obj;
+   Evas_Object *edje_obj;
+   Evas_Object *event_obj;
+
+   Evas_Object *widget;
+   
+   Elm_Smart_Scroller_Policy hbar_flags, vbar_flags;
+
+   struct {
+      Evas_Coord x, y;
+      Evas_Coord sx, sy;
+      Evas_Coord dx, dy;
+      Evas_Coord bx, by;
+      Evas_Coord ax, ay;
+      Evas_Coord bx0, by0;
+      Evas_Coord b0x, b0y;
+      Evas_Coord b2x, b2y;
+      struct {
+        Evas_Coord    x, y;
+        double        timestamp;
+      } history[20];
+      double anim_start;
+      double anim_start2;
+      double anim_start3;
+      double onhold_vx, onhold_vy, onhold_tlast, onhold_vxe, onhold_vye;
+      Evas_Coord hold_x, hold_y;
+      Ecore_Animator *hold_animator;
+      Ecore_Animator *onhold_animator;
+      Ecore_Animator *momentum_animator;
+      Ecore_Animator *bounce_x_animator;
+      Ecore_Animator *bounce_y_animator;
+      Evas_Coord locked_x, locked_y;
+      int hdir, vdir;
+      unsigned char now : 1;
+      unsigned char cancelled : 1;
+      unsigned char hold : 1;
+      unsigned char hold_parent : 1;
+      unsigned char want_dragged : 1;
+      unsigned char dragged : 1;
+      unsigned char dragged_began : 1;
+      unsigned char dir_x : 1;
+      unsigned char dir_y : 1;
+      unsigned char locked : 1;
+      unsigned char bounce_x_hold : 1;
+      unsigned char bounce_y_hold : 1;
+   } down;
+
+   struct {
+      Evas_Coord w, h;
+   } child;
+   struct {
+      Evas_Coord x, y;
+   } step, page;
+
+   struct {
+      void (*set) (Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+      void (*get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y);
+      void (*max_get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y);
+      void (*child_size_get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y);
+   } pan_func;
+
+   struct {
+      struct {
+         Evas_Coord start, end;
+         double t_start, t_end;
+         Ecore_Animator *animator;
+      } x, y;
+   } scrollto;
+
+   double pagerel_h, pagerel_v;
+   Evas_Coord pagesize_h, pagesize_v;
+
+   unsigned char hbar_visible : 1;
+   unsigned char vbar_visible : 1;
+   unsigned char extern_pan : 1;
+   unsigned char one_dir_at_a_time : 1;
+   unsigned char hold : 1;
+   unsigned char freeze : 1;
+   unsigned char bouncemex : 1;
+   unsigned char bouncemey : 1;
+   unsigned char bounce_horiz : 1;
+   unsigned char bounce_vert : 1;
+};
+
+/* local subsystem functions */
+static void _smart_child_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _smart_pan_changed_hook(void *data, Evas_Object *obj, void *event_info);
+static void _smart_pan_pan_changed_hook(void *data, Evas_Object *obj, void *event_info);
+static void _smart_event_wheel(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _smart_event_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static int  _smart_hold_animator(void *data);
+static int  _smart_momentum_animator(void *data);
+static void _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static int  _smart_onhold_animator(void *data);
+static void _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _smart_event_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _smart_edje_drag_v_start(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _smart_edje_drag_v_stop(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _smart_edje_drag_v(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _smart_edje_drag_h_start(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _smart_edje_drag_h_stop(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _smart_edje_drag_h(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _smart_scrollbar_read(Smart_Data *sd);
+static void _smart_scrollbar_reset(Smart_Data *sd);
+static int  _smart_scrollbar_bar_h_visibility_adjust(Smart_Data *sd);
+static int  _smart_scrollbar_bar_v_visibility_adjust(Smart_Data *sd);
+static void _smart_scrollbar_bar_visibility_adjust(Smart_Data *sd);
+static void _smart_scrollbar_size_adjust(Smart_Data *sd);
+static void _smart_reconfigure(Smart_Data *sd);
+static void _smart_add(Evas_Object *obj);
+static void _smart_del(Evas_Object *obj);
+static void _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+static void _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
+static void _smart_show(Evas_Object *obj);
+static void _smart_hide(Evas_Object *obj);
+static void _smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
+static void _smart_clip_set(Evas_Object *obj, Evas_Object *clip);
+static void _smart_clip_unset(Evas_Object *obj);
+static void _smart_init(void);
+
+/* local subsystem globals */
+static Evas_Smart *_smart = NULL;
+
+/* externally accessible functions */
+Evas_Object *
+elm_smart_scroller_add(Evas *evas)
+{
+   _smart_init();
+   return evas_object_smart_add(evas, _smart);
+}
+
+void
+elm_smart_scroller_child_set(Evas_Object *obj, Evas_Object *child)
+{
+   Evas_Coord w, h;
+   Evas_Object *o;
+
+   API_ENTRY return;
+   if (sd->child_obj)
+     {
+       _elm_smart_pan_child_set(sd->pan_obj, NULL);
+       evas_object_event_callback_del_full(sd->child_obj, EVAS_CALLBACK_DEL, _smart_child_del_hook, sd);
+     }
+
+   sd->child_obj = child;
+   if (!child) return;
+
+   if (!sd->pan_obj)
+     {
+       o = _elm_smart_pan_add(evas_object_evas_get(obj));
+       sd->pan_obj = o;
+       evas_object_smart_callback_add(o, "changed", _smart_pan_changed_hook, sd);
+       evas_object_smart_callback_add(o, "pan_changed", _smart_pan_pan_changed_hook, sd);
+       evas_object_show(o);
+       edje_object_part_swallow(sd->edje_obj, "elm.swallow.content", o);
+     }
+
+   sd->pan_func.set = _elm_smart_pan_set;
+   sd->pan_func.get = _elm_smart_pan_get;
+   sd->pan_func.max_get = _elm_smart_pan_max_get;
+   sd->pan_func.child_size_get = _elm_smart_pan_child_size_get;
+
+   evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, _smart_child_del_hook, sd);
+   _elm_smart_pan_child_set(sd->pan_obj, sd->child_obj);
+   sd->pan_func.child_size_get(sd->pan_obj, &w, &h);
+   sd->child.w = w;
+   sd->child.h = h;
+   _smart_scrollbar_size_adjust(sd);
+   _smart_scrollbar_reset(sd);
+}
+
+void
+elm_smart_scroller_extern_pan_set(Evas_Object *obj, Evas_Object *pan,
+                            void (*pan_set) (Evas_Object *obj, Evas_Coord x, Evas_Coord y),
+                            void (*pan_get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y),
+                            void (*pan_max_get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y),
+                            void (*pan_child_size_get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y))
+{
+   API_ENTRY return;
+
+   elm_smart_scroller_child_set(obj, NULL);
+   if (sd->extern_pan)
+     {
+       if (sd->pan_obj)
+         {
+            edje_object_part_unswallow(sd->edje_obj, sd->pan_obj);
+            sd->pan_obj = NULL;
+         }
+     }
+   else
+     {
+       if (sd->pan_obj)
+         {
+            evas_object_del(sd->pan_obj);
+            sd->pan_obj = NULL;
+         }
+     }
+   if (!pan)
+     {
+       sd->extern_pan = 0;
+       return;
+     }
+
+   sd->pan_obj = pan;
+   sd->pan_func.set = pan_set;
+   sd->pan_func.get = pan_get;
+   sd->pan_func.max_get = pan_max_get;
+   sd->pan_func.child_size_get = pan_child_size_get;
+   sd->extern_pan = 1;
+   evas_object_smart_callback_add(sd->pan_obj, "changed", _smart_pan_changed_hook, sd);
+   evas_object_smart_callback_add(sd->pan_obj, "pan_changed", _smart_pan_pan_changed_hook, sd);
+   edje_object_part_swallow(sd->edje_obj, "elm.swallow.content", sd->pan_obj);
+   evas_object_show(sd->pan_obj);
+}
+
+void
+elm_smart_scroller_custom_edje_file_set(Evas_Object *obj, char *file, char *group)
+{
+   API_ENTRY return;
+
+   edje_object_file_set(sd->edje_obj, file, group);
+   if (sd->pan_obj)
+     edje_object_part_swallow(sd->edje_obj, "elm.swallow.content", sd->pan_obj);
+   sd->vbar_visible = !sd->vbar_visible;
+   sd->hbar_visible = !sd->hbar_visible;
+   _smart_scrollbar_bar_visibility_adjust(sd);
+   if (sd->hbar_flags == ELM_SMART_SCROLLER_POLICY_ON)
+     edje_object_signal_emit(sd->edje_obj, "elm,action,show_always,hbar", "elm");
+   else if (sd->hbar_flags == ELM_SMART_SCROLLER_POLICY_OFF)
+     edje_object_signal_emit(sd->edje_obj, "elm,action,hide,hbar", "elm");
+   else
+     edje_object_signal_emit(sd->edje_obj, "elm,action,show_notalways,hbar", "elm");
+   if (sd->vbar_flags == ELM_SMART_SCROLLER_POLICY_ON)
+     edje_object_signal_emit(sd->edje_obj, "elm,action,show_always,vbar", "elm");
+   else if (sd->vbar_flags == ELM_SMART_SCROLLER_POLICY_OFF)
+     edje_object_signal_emit(sd->edje_obj, "elm,action,hide,vbar", "elm");
+   else
+     edje_object_signal_emit(sd->edje_obj, "elm,action,show_notalways,vbar", "elm");
+}
+
+static void
+_smart_anim_start(Evas_Object *obj)
+{
+   evas_object_smart_callback_call(obj, "animate,start", NULL);
+}
+
+static void
+_smart_anim_stop(Evas_Object *obj)
+{
+   evas_object_smart_callback_call(obj, "animate,stop", NULL);
+}
+
+static void
+_smart_drag_start(Evas_Object *obj)
+{
+   evas_object_smart_callback_call(obj, "drag,start", NULL);
+}
+
+static void
+_smart_drag_stop(Evas_Object *obj)
+{
+   evas_object_smart_callback_call(obj, "drag,stop", NULL);
+}
+
+static int
+_smart_scrollto_x_animator(void *data)
+{
+   Smart_Data *sd = data;
+   Evas_Coord px, py;
+   double t, tt;
+
+   t = ecore_loop_time_get();
+   tt = (t - sd->scrollto.x.t_start) / (sd->scrollto.x.t_end - sd->scrollto.x.t_start);
+   tt = 1.0 - tt;
+   tt = 1.0 - (tt * tt);
+   sd->pan_func.get(sd->pan_obj, &px, &py);
+   px = (sd->scrollto.x.start * (1.0 - tt)) +
+     (sd->scrollto.x.end * tt);
+   if (t >= sd->scrollto.x.t_end)
+     {
+        px = sd->scrollto.x.end;
+        elm_smart_scroller_child_pos_set(sd->smart_obj, px, py);
+        sd->scrollto.x.animator = NULL;
+        if (!sd->scrollto.y.animator)
+          _smart_anim_stop(sd->smart_obj);
+        return 0;
+     }
+   elm_smart_scroller_child_pos_set(sd->smart_obj, px, py);
+   return 1;
+}
+
+static void
+_smart_scrollto_x(Smart_Data *sd, double t_in, Evas_Coord pos_x)
+{
+   Evas_Coord px, py, x, y, w, h;
+   double t;
+
+   if (sd->freeze) return;
+   if (t_in <= 0.0)
+     {
+        elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+        elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
+        x = pos_x;
+        elm_smart_scroller_child_region_show(sd->smart_obj, x, y, w, h);
+        return;
+     }
+   t = ecore_loop_time_get();
+   sd->pan_func.get(sd->pan_obj, &px, &py);
+   sd->scrollto.x.start = px;
+   sd->scrollto.x.end = pos_x;
+   sd->scrollto.x.t_start = t;
+   sd->scrollto.x.t_end = t + t_in;
+   elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+   elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
+   elm_smart_scroller_child_region_show(sd->smart_obj, x, y, w, h);
+   if (!sd->scrollto.x.animator)
+     {
+        if (!sd->scrollto.y.animator)
+          _smart_anim_start(sd->smart_obj);
+        sd->scrollto.x.animator = ecore_animator_add(_smart_scrollto_x_animator, sd);
+     }
+   if (sd->down.bounce_x_animator)
+     {
+        ecore_animator_del(sd->down.bounce_x_animator);
+        sd->down.bounce_x_animator = NULL;
+     }
+   sd->bouncemex = 0;
+}
+
+static int
+_smart_scrollto_y_animator(void *data)
+{
+   Smart_Data *sd = data;
+   Evas_Coord px, py;
+   double t, tt;
+
+   t = ecore_loop_time_get();
+   tt = (t - sd->scrollto.y.t_start) / (sd->scrollto.y.t_end - sd->scrollto.y.t_start);
+   tt = 1.0 - tt;
+   tt = 1.0 - (tt * tt);
+   sd->pan_func.get(sd->pan_obj, &px, &py);
+   py = (sd->scrollto.y.start * (1.0 - tt)) +
+     (sd->scrollto.y.end * tt);
+   if (t >= sd->scrollto.y.t_end)
+     {
+        py = sd->scrollto.y.end;
+        elm_smart_scroller_child_pos_set(sd->smart_obj, px, py);
+        sd->scrollto.y.animator = NULL;
+        if (!sd->scrollto.x.animator)
+          _smart_anim_stop(sd->smart_obj);
+        return 0;
+     }
+   elm_smart_scroller_child_pos_set(sd->smart_obj, px, py);
+
+   return 1;
+}
+
+static void
+_smart_scrollto_y(Smart_Data *sd, double t_in, Evas_Coord pos_y)
+{
+   Evas_Coord px, py, x, y, w, h;
+   double t;
+
+   if (sd->freeze) return;
+   if (t_in <= 0.0)
+     {
+        elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+        elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
+        y = pos_y;
+        elm_smart_scroller_child_region_show(sd->smart_obj, x, y, w, h);
+        return;
+     }
+   t = ecore_loop_time_get();
+   sd->pan_func.get(sd->pan_obj, &px, &py);
+   sd->scrollto.y.start = py;
+   sd->scrollto.y.end = pos_y;
+   sd->scrollto.y.t_start = t;
+   sd->scrollto.y.t_end = t + t_in;
+   elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+   elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
+   elm_smart_scroller_child_region_show(sd->smart_obj, x, y, w, h);
+   if (!sd->scrollto.y.animator)
+     {
+        if (!sd->scrollto.x.animator)
+          _smart_anim_start(sd->smart_obj);
+        sd->scrollto.y.animator = ecore_animator_add(_smart_scrollto_y_animator, sd);
+     }
+   if (sd->down.bounce_y_animator)
+     {
+        ecore_animator_del(sd->down.bounce_y_animator);
+        sd->down.bounce_y_animator = NULL;
+     }
+   sd->bouncemey = 0;
+}
+
+static Eina_Bool
+_smart_do_page(Smart_Data *sd)
+{
+   if ((sd->pagerel_h == 0.0) && (sd->pagesize_h == 0) &&
+       (sd->pagerel_v == 0.0) && (sd->pagesize_v == 0))
+     return 0;
+   return 1;
+}
+
+static Evas_Coord
+_smart_page_x_get(Smart_Data *sd, int offset)
+{
+   Evas_Coord x, y, w, h, cw, ch;
+
+   elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+   elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
+   sd->pan_func.child_size_get(sd->pan_obj, &cw, &ch);
+
+   x += offset;
+
+   if (sd->pagerel_h > 0.0)
+     {
+        x = x + (w * sd->pagerel_h * 0.5);
+        x = x / (w * sd->pagerel_h);
+        x = x * (w * sd->pagerel_h);
+     }
+   else if (sd->pagesize_h > 0)
+     {
+        x = x + (sd->pagesize_h * 0.5);
+        x = x / (sd->pagesize_h);
+        x = x * (sd->pagesize_h);
+     }
+   if (x < 0) x = 0;
+   else if ((x + w) > cw) x = cw - w;
+   return x;
+}
+
+static Evas_Coord
+_smart_page_y_get(Smart_Data *sd, int offset)
+{
+   Evas_Coord x, y, w, h, cw, ch;
+
+   elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+   elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
+   sd->pan_func.child_size_get(sd->pan_obj, &cw, &ch);
+
+   y += offset;
+
+   if (sd->pagerel_v > 0.0)
+     {
+        y = y + (h * sd->pagerel_v * 0.5);
+        y = y / (h * sd->pagerel_v);
+        y = y * (h * sd->pagerel_v);
+     }
+   else if (sd->pagesize_v > 0)
+     {
+        y = y + (sd->pagesize_v * 0.5);
+        y = y / (sd->pagesize_v);
+        y = y * (sd->pagesize_v);
+     }
+   if (y < 0) y = 0;
+   else if ((y + h) > ch) y = ch - h;
+   return y;
+}
+
+static void
+_smart_page_adjust(Smart_Data *sd)
+{
+   Evas_Coord x, y, w, h;
+
+   if (!_smart_do_page(sd)) return;
+
+   elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
+
+   x = _smart_page_x_get(sd, 0);
+   y = _smart_page_y_get(sd, 0);
+
+   elm_smart_scroller_child_region_show(sd->smart_obj, x, y, w, h);
+}
+
+static int
+_smart_bounce_x_animator(void *data)
+{
+   Smart_Data *sd;
+   Evas_Coord x, y, dx;
+   double t, p, dt;
+
+   sd = data;
+   t = ecore_loop_time_get();
+   dt = t - sd->down.anim_start2;
+   if (dt >= 0.0)
+     {
+       dt = dt / _elm_config->thumbscroll_bounce_friction;
+       if (dt > 1.0) dt = 1.0;
+       p = 1.0 - ((1.0 - dt) * (1.0 - dt));
+        elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+        dx = sd->down.b2x - sd->down.bx;
+       dx = (dx * p);
+       x = sd->down.bx + dx;
+        if (!sd->down.cancelled)
+          elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+        if (dt >= 1.0)
+          {
+             if (sd->down.momentum_animator)
+               sd->down.bounce_x_hold = 1;
+             sd->down.bounce_x_animator = NULL;
+             sd->bouncemex = 0;
+             return 0;
+          }
+     }
+   return 1;
+}
+
+static int
+_smart_bounce_y_animator(void *data)
+{
+   Smart_Data *sd;
+   Evas_Coord x, y, dy;
+   double t, p, dt;
+
+   sd = data;
+   t = ecore_loop_time_get();
+   dt = t - sd->down.anim_start3;
+   if (dt >= 0.0)
+     {
+       dt = dt / _elm_config->thumbscroll_bounce_friction;
+       if (dt > 1.0) dt = 1.0;
+       p = 1.0 - ((1.0 - dt) * (1.0 - dt));
+        elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+        dy = sd->down.b2y - sd->down.by;
+       dy = (dy * p);
+       y = sd->down.by + dy;
+        if (!sd->down.cancelled)
+          elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+        if (dt >= 1.0)
+          {
+             if (sd->down.momentum_animator)
+               sd->down.bounce_y_hold = 1;
+             sd->down.bounce_y_animator = NULL;
+             sd->bouncemey = 0;
+             return 0;
+          }
+     }
+   return 1;
+}
+
+#define LEFT 0
+#define RIGHT 1
+#define UP 2
+#define DOWN 3
+static Eina_Bool
+can_scroll(Smart_Data *sd, int dir)
+{
+   Evas_Coord mx = 0, my = 0, px = 0, py = 0;
+
+   sd->pan_func.max_get(sd->pan_obj, &mx, &my);
+   sd->pan_func.get(sd->pan_obj, &px, &py);
+   switch (dir)
+     {
+     case LEFT:
+        if (px > 0) return 1;
+        break;
+     case RIGHT:
+        if (px < mx) return 1;
+        break;
+     case UP:
+        if (py > 0) return 1;
+        break;
+     case DOWN:
+        if (py < my) return 1;
+        break;
+     default:
+        break;
+     }
+   return 0;
+}
+
+static int
+_smart_momentum_animator(void *data)
+{
+   Smart_Data *sd;
+   double t, dt, p;
+   Evas_Coord x, y, dx, dy, px, py;
+
+   sd = data;
+   t = ecore_loop_time_get();
+   dt = t - sd->down.anim_start;
+   if (dt >= 0.0)
+     {
+        /*
+        if (sd->down.hold_parent)
+          {
+             if ((sd->down.dir_x) && !can_scroll(sd, sd->down.hdir))
+               {
+                  sd->down.dir_x = 0;
+               }
+             if ((sd->down.dir_y) && !can_scroll(sd, sd->down.vdir))
+               {
+                  sd->down.dir_y = 0;
+               }
+          }
+        if ((!sd->down.dir_x) && (!sd->down.dir_y))
+          {
+             sd->down.cancelled = 1;
+          }
+         */
+       dt = dt / _elm_config->thumbscroll_friction;
+       if (dt > 1.0) dt = 1.0;
+       p = 1.0 - ((1.0 - dt) * (1.0 - dt));
+       dx = (sd->down.dx * _elm_config->thumbscroll_friction * p);
+       dy = (sd->down.dy * _elm_config->thumbscroll_friction * p);
+        sd->down.ax = dx;
+        sd->down.ay = dy;
+       x = sd->down.sx - dx;
+       y = sd->down.sy - dy;
+        elm_smart_scroller_child_pos_get(sd->smart_obj, &px, &py);
+        if ((sd->down.bounce_x_animator) ||
+            (sd->down.bounce_x_hold))
+          {
+             sd->down.bx = sd->down.bx0 - dx + sd->down.b0x;
+             x = px;
+          }
+        if ((sd->down.bounce_y_animator) ||
+            (sd->down.bounce_y_hold))
+          {
+             sd->down.by = sd->down.by0 - dy + sd->down.b0y;
+             y = py;
+          }
+       elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+       if (dt >= 1.0)
+         {
+             _smart_anim_stop(sd->smart_obj);
+            sd->down.momentum_animator = NULL;
+             sd->down.bounce_x_hold = 0;
+             sd->down.bounce_y_hold = 0;
+             sd->down.ax = 0;
+             sd->down.ay = 0;
+            return 0;
+         }
+     }
+   return 1;
+}
+
+static void
+bounce_eval(Smart_Data *sd)
+{
+   Evas_Coord mx, my, px, py, bx, by, b2x, b2y;
+
+   if (sd->freeze) return;
+   if ((!sd->bouncemex) && (!sd->bouncemey)) return;
+   if (sd->down.now) return; // down bounce while still held down
+   if (sd->down.onhold_animator)
+     {
+        ecore_animator_del(sd->down.onhold_animator);
+        sd->down.onhold_animator = NULL;
+     }
+   if (sd->down.hold_animator)
+     {
+        ecore_animator_del(sd->down.hold_animator);
+        sd->down.hold_animator = NULL;
+     }
+   sd->pan_func.max_get(sd->pan_obj, &mx, &my);
+   sd->pan_func.get(sd->pan_obj, &px, &py);
+   bx = px;
+   by = py;
+   if (px < 0) px = 0;
+   if (px > mx) px = mx;
+   if (py < 0) py = 0;
+   if (py > my) py = my;
+   b2x = px;
+   b2y = py;
+   if ((!sd->widget) || 
+       (!elm_widget_drag_child_locked_x_get(sd->widget)))
+     {
+        if (!sd->down.bounce_x_animator)
+          {
+             if (sd->bouncemex)
+               {
+                  if (sd->scrollto.x.animator)
+                    {
+                       ecore_animator_del(sd->scrollto.x.animator);
+                       sd->scrollto.x.animator = NULL;
+                    }
+                  sd->down.bounce_x_animator = ecore_animator_add(_smart_bounce_x_animator, sd);
+                  sd->down.anim_start2 = ecore_loop_time_get();
+                  sd->down.bx = bx;
+                  sd->down.bx0 = bx;
+                  sd->down.b2x = b2x;
+                  if (sd->down.momentum_animator) sd->down.b0x = sd->down.ax;
+                  else sd->down.b0x = 0;
+               }
+          }
+     }
+   if ((!sd->widget) || 
+       (!elm_widget_drag_child_locked_y_get(sd->widget)))
+     {
+        if (!sd->down.bounce_y_animator)
+          {
+             if (sd->bouncemey)
+               {
+                  if (sd->scrollto.y.animator)
+                    {
+                       ecore_animator_del(sd->scrollto.y.animator);
+                       sd->scrollto.y.animator = NULL;
+                    }
+                  sd->down.bounce_y_animator = ecore_animator_add(_smart_bounce_y_animator, sd);
+                  sd->down.anim_start3 = ecore_loop_time_get();
+                  sd->down.by = by;
+                  sd->down.by0 = by;
+                  sd->down.b2y = b2y;
+                  if (sd->down.momentum_animator) sd->down.b0y = sd->down.ay;
+                  else sd->down.b0y = 0;
+               }
+          }
+     }
+}
+
+void
+elm_smart_scroller_child_pos_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   Evas_Coord mx = 0, my = 0, px, py;
+   double vx, vy;
+
+   API_ENTRY return;
+   // FIXME: allow for bounce outside of range
+   sd->pan_func.max_get(sd->pan_obj, &mx, &my);
+   if (mx > 0) vx = (double)x / (double)mx;
+   else vx = 0.0;
+   if (vx < 0.0) vx = 0.0;
+   else if (vx > 1.0) vx = 1.0;
+   if (my > 0) vy = (double)y / (double)my;
+   else vy = 0.0;
+   if (vy < 0.0) vy = 0.0;
+   else if (vy > 1.0) vy = 1.0;
+   edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.vbar", 0.0, vy);
+   edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.hbar", vx, 0.0);
+   sd->pan_func.get(sd->pan_obj, &px, &py);
+   if (!_elm_config->thumbscroll_bounce_enable)
+     {
+        if (x < 0) x = 0;
+        if (x > mx) x = mx;
+        if (y < 0) y = 0;
+        if (y > my) y = my;
+     }
+
+   if (!sd->bounce_horiz)
+     {
+        if (x < 0) x = 0;
+        if (x > mx) x = mx;
+     }
+   if (!sd->bounce_vert)
+     {
+        if (y < 0) y = 0;
+        if (y > my) y = my;
+     }
+
+   sd->pan_func.set(sd->pan_obj, x, y);
+   if ((px != x) || (py != y))
+     edje_object_signal_emit(sd->edje_obj, "elm,action,scroll", "elm");
+   if (!sd->down.bounce_x_animator)
+     {
+        if ((x < 0) || (x > mx))
+          {
+             sd->bouncemex = 1;
+             bounce_eval(sd);
+          }
+     }
+   if (!sd->down.bounce_y_animator)
+     {
+        if ((y < 0) || (y > my))
+          {
+             sd->bouncemey = 1;
+             bounce_eval(sd);
+          }
+     }
+   if ((x != px) || (y != py))
+     {
+        evas_object_smart_callback_call(obj, "scroll", NULL);
+     }
+   if ((x != px)/* && (!sd->bouncemex)*/)
+     {
+        if (x == 0)
+          evas_object_smart_callback_call(obj, "edge,left", NULL);
+        if (x == mx)
+          evas_object_smart_callback_call(obj, "edge,right", NULL);
+     }
+   if ((y != py)/* && (!sd->bouncemey)*/)
+     {
+        if (y == 0)
+          evas_object_smart_callback_call(obj, "edge,top", NULL);
+        if (y == my)
+          evas_object_smart_callback_call(obj, "edge,bottom", NULL);
+     }
+}
+
+void
+elm_smart_scroller_child_pos_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+   API_ENTRY return;
+   sd->pan_func.get(sd->pan_obj, x, y);
+}
+
+void
+elm_smart_scroller_child_region_show(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
+{
+   Evas_Coord mx = 0, my = 0, cw = 0, ch = 0, px = 0, py = 0, nx, ny;
+
+   API_ENTRY return;
+   sd->pan_func.max_get(sd->pan_obj, &mx, &my);
+   sd->pan_func.child_size_get(sd->pan_obj, &cw, &ch);
+   sd->pan_func.get(sd->pan_obj, &px, &py);
+
+   nx = px;
+   if (x < px) nx = x;
+   else if ((x + w) > (px + (cw - mx)))
+     {
+       nx = x + w - (cw - mx);
+       if (nx > x) nx = x;
+     }
+   ny = py;
+   if (y < py) ny = y;
+   else if ((y + h) > (py + (ch - my)))
+     {
+       ny = y + h - (ch - my);
+       if (ny > y) ny = y;
+     }
+   if ((nx == px) && (ny == py)) return;
+   if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) ||
+       (sd->scrollto.x.animator) || (sd->scrollto.y.animator))
+     {
+        _smart_anim_stop(sd->smart_obj);
+     }
+   if (sd->scrollto.x.animator)
+     {
+        ecore_animator_del(sd->scrollto.x.animator);
+        sd->scrollto.x.animator = NULL;
+     }
+   if (sd->scrollto.y.animator)
+     {
+        ecore_animator_del(sd->scrollto.y.animator);
+        sd->scrollto.y.animator = NULL;
+     }
+   if (sd->down.bounce_x_animator)
+     {
+        ecore_animator_del(sd->down.bounce_x_animator);
+        sd->down.bounce_x_animator = NULL;
+        sd->bouncemex = 0;
+     }
+   if (sd->down.bounce_y_animator)
+     {
+        ecore_animator_del(sd->down.bounce_y_animator);
+        sd->down.bounce_y_animator = NULL;
+        sd->bouncemey = 0;
+     }
+   if (sd->down.hold_animator)
+     {
+        ecore_animator_del(sd->down.hold_animator);
+        sd->down.hold_animator = NULL;
+        _smart_drag_stop(sd->smart_obj);
+     }
+   if (sd->down.momentum_animator)
+     {
+        ecore_animator_del(sd->down.momentum_animator);
+        sd->down.momentum_animator = NULL;
+        sd->down.bounce_x_hold = 0;
+        sd->down.bounce_y_hold = 0;
+        sd->down.ax = 0;
+        sd->down.ay = 0;
+     }
+   elm_smart_scroller_child_pos_set(obj, nx, ny);
+}
+
+void
+elm_smart_scroller_child_viewport_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
+{
+   API_ENTRY return;
+   edje_object_calc_force(sd->edje_obj);
+   evas_object_geometry_get(sd->pan_obj, NULL, NULL, w, h);
+}
+
+void
+elm_smart_scroller_step_size_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   API_ENTRY return;
+   if (x < 1) x = 1;
+   if (y < 1) y = 1;
+   sd->step.x = x;
+   sd->step.y = y;
+   _smart_scrollbar_size_adjust(sd);
+}
+
+void
+elm_smart_scroller_step_size_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+   API_ENTRY return;
+   if (x) *x = sd->step.x;
+   if (y) *y = sd->step.y;
+}
+
+void
+elm_smart_scroller_page_size_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   API_ENTRY return;
+   sd->page.x = x;
+   sd->page.y = y;
+   _smart_scrollbar_size_adjust(sd);
+}
+
+void
+elm_smart_scroller_page_size_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+   API_ENTRY return;
+   if (x) *x = sd->page.x;
+   if (y) *y = sd->page.y;
+}
+
+void
+elm_smart_scroller_policy_set(Evas_Object *obj, Elm_Smart_Scroller_Policy hbar, Elm_Smart_Scroller_Policy vbar)
+{
+   API_ENTRY return;
+   if ((sd->hbar_flags == hbar) && (sd->vbar_flags == vbar)) return;
+   sd->hbar_flags = hbar;
+   sd->vbar_flags = vbar;
+   if (sd->hbar_flags == ELM_SMART_SCROLLER_POLICY_ON)
+     edje_object_signal_emit(sd->edje_obj, "elm,action,show_always,hbar", "elm");
+   else if (sd->hbar_flags == ELM_SMART_SCROLLER_POLICY_OFF)
+     edje_object_signal_emit(sd->edje_obj, "elm,action,hide,hbar", "elm");
+   else
+     edje_object_signal_emit(sd->edje_obj, "elm,action,show_notalways,hbar", "elm");
+   if (sd->vbar_flags == ELM_SMART_SCROLLER_POLICY_ON)
+     edje_object_signal_emit(sd->edje_obj, "elm,action,show_always,vbar", "elm");
+   else if (sd->vbar_flags == ELM_SMART_SCROLLER_POLICY_OFF)
+     edje_object_signal_emit(sd->edje_obj, "elm,action,hide,vbar", "elm");
+   else
+     edje_object_signal_emit(sd->edje_obj, "elm,action,show_notalways,vbar", "elm");
+   _smart_scrollbar_size_adjust(sd);
+}
+
+void
+elm_smart_scroller_policy_get(Evas_Object *obj, Elm_Smart_Scroller_Policy *hbar, Elm_Smart_Scroller_Policy *vbar)
+{
+   API_ENTRY return;
+   if (hbar) *hbar = sd->hbar_flags;
+   if (vbar) *vbar = sd->vbar_flags;
+}
+
+Evas_Object *
+elm_smart_scroller_edje_object_get(Evas_Object *obj)
+{
+   API_ENTRY return NULL;
+   return sd->edje_obj;
+}
+
+void
+elm_smart_scroller_single_dir_set(Evas_Object *obj, Eina_Bool single_dir)
+{
+   API_ENTRY return;
+   sd->one_dir_at_a_time = single_dir;
+}
+
+Eina_Bool
+elm_smart_scroller_single_dir_get(Evas_Object *obj)
+{
+   API_ENTRY return EINA_FALSE;
+   return sd->one_dir_at_a_time;
+}
+
+void
+elm_smart_scroller_object_theme_set(Evas_Object *parent, Evas_Object *obj, const char *clas, const char *group, const char *style)
+{
+   API_ENTRY return;
+   _elm_theme_object_set(parent, sd->edje_obj, clas, group, style);
+   if (sd->pan_obj)
+     edje_object_part_swallow(sd->edje_obj, "elm.swallow.content", sd->pan_obj);
+   sd->vbar_visible = !sd->vbar_visible;
+   sd->hbar_visible = !sd->hbar_visible;
+   _smart_scrollbar_bar_visibility_adjust(sd);
+}
+
+void
+elm_smart_scroller_hold_set(Evas_Object *obj, Eina_Bool hold)
+{
+   API_ENTRY return;
+   sd->hold = hold;
+}
+
+void
+elm_smart_scroller_freeze_set(Evas_Object *obj, Eina_Bool freeze)
+{
+   API_ENTRY return;
+   sd->freeze = freeze;
+   if (sd->freeze)
+     {
+        if (sd->down.onhold_animator)
+          {
+             ecore_animator_del(sd->down.onhold_animator);
+             sd->down.onhold_animator = NULL;
+          }
+     }
+}
+
+void
+elm_smart_scroller_bounce_allow_set(Evas_Object *obj, Eina_Bool horiz, Eina_Bool vert)
+{
+   API_ENTRY return;
+   sd->bounce_horiz = horiz;
+   sd->bounce_vert = vert;
+}
+
+void
+elm_smart_scroller_bounce_allow_get(const Evas_Object *obj, Eina_Bool *horiz, Eina_Bool *vert)
+{
+   API_ENTRY return;
+   *horiz = sd->bounce_horiz;
+   *vert = sd->bounce_vert;
+}
+
+void
+elm_smart_scroller_paging_set(Evas_Object *obj, double pagerel_h, double pagerel_v, Evas_Coord pagesize_h, Evas_Coord pagesize_v)
+{
+   API_ENTRY return;
+   sd->pagerel_h = pagerel_h;
+   sd->pagerel_v = pagerel_v;
+   sd->pagesize_h = pagesize_h;
+   sd->pagesize_v = pagesize_v;
+   _smart_page_adjust(sd);
+}
+
+void
+elm_smart_scroller_region_bring_in(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
+{
+   Evas_Coord mx = 0, my = 0, cw = 0, ch = 0, px = 0, py = 0, nx, ny;
+
+   API_ENTRY return;
+   sd->pan_func.max_get(sd->pan_obj, &mx, &my);
+   sd->pan_func.child_size_get(sd->pan_obj, &cw, &ch);
+   sd->pan_func.get(sd->pan_obj, &px, &py);
+
+   nx = px;
+   if (x < px) nx = x;
+   else if ((x + w) > (px + (cw - mx)))
+     {
+       nx = x + w - (cw - mx);
+       if (nx > x) nx = x;
+     }
+   ny = py;
+   if (y < py) ny = y;
+   else if ((y + h) > (py + (ch - my)))
+     {
+       ny = y + h - (ch - my);
+       if (ny > y) ny = y;
+     }
+   if ((nx == px) && (ny == py)) return;
+   if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) ||
+       (sd->scrollto.x.animator) || (sd->scrollto.y.animator))
+     {
+        _smart_anim_stop(sd->smart_obj);
+     }
+   if (sd->scrollto.x.animator)
+     {
+        ecore_animator_del(sd->scrollto.x.animator);
+        sd->scrollto.x.animator = NULL;
+     }
+   if (sd->scrollto.y.animator)
+     {
+        ecore_animator_del(sd->scrollto.y.animator);
+        sd->scrollto.y.animator = NULL;
+     }
+   if (sd->down.bounce_x_animator)
+     {
+        ecore_animator_del(sd->down.bounce_x_animator);
+        sd->down.bounce_x_animator = NULL;
+        sd->bouncemex = 0;
+     }
+   if (sd->down.bounce_y_animator)
+     {
+        ecore_animator_del(sd->down.bounce_y_animator);
+        sd->down.bounce_y_animator = NULL;
+        sd->bouncemey = 0;
+     }
+   if (sd->down.hold_animator)
+     {
+        ecore_animator_del(sd->down.hold_animator);
+        sd->down.hold_animator = NULL;
+        _smart_drag_stop(sd->smart_obj);
+     }
+   if (sd->down.momentum_animator)
+     {
+        ecore_animator_del(sd->down.momentum_animator);
+        sd->down.momentum_animator = NULL;
+        sd->down.bounce_x_hold = 0;
+        sd->down.bounce_y_hold = 0;
+        sd->down.ax = 0;
+        sd->down.ay = 0;
+     }
+   x = nx;
+   if (x < 0) x = 0;
+   else if ((x + w) > cw) x = cw - w;
+   _smart_scrollto_x(sd, _elm_config->bring_in_scroll_friction, x);
+   y = ny;
+   if (y < 0) y = 0;
+   else if ((y + h) > ch) y = ch - h;
+   _smart_scrollto_y(sd, _elm_config->bring_in_scroll_friction, y);
+}
+
+void
+elm_smart_scroller_widget_set(Evas_Object *obj, Evas_Object *wid)
+{
+   API_ENTRY return;
+   sd->widget = wid;
+}
+
+/* local subsystem functions */
+static void
+_smart_edje_drag_v_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Smart_Data *sd;
+
+   sd = data;
+   _smart_scrollbar_read(sd);
+   _smart_drag_start(sd->smart_obj);
+}
+
+static void
+_smart_edje_drag_v_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Smart_Data *sd;
+
+   sd = data;
+   _smart_scrollbar_read(sd);
+   _smart_drag_stop(sd->smart_obj);
+}
+
+static void
+_smart_edje_drag_v(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Smart_Data *sd;
+
+   sd = data;
+   _smart_scrollbar_read(sd);
+}
+
+static void
+_smart_edje_drag_h_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Smart_Data *sd;
+
+   sd = data;
+   _smart_scrollbar_read(sd);
+   _smart_drag_start(sd->smart_obj);
+}
+
+static void
+_smart_edje_drag_h_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Smart_Data *sd;
+
+   sd = data;
+   _smart_scrollbar_read(sd);
+   _smart_drag_stop(sd->smart_obj);
+}
+
+static void
+_smart_edje_drag_h(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Smart_Data *sd;
+
+   sd = data;
+   _smart_scrollbar_read(sd);
+}
+
+static void
+_smart_child_del_hook(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Smart_Data *sd;
+
+   sd = data;
+   sd->child_obj = NULL;
+   _smart_scrollbar_size_adjust(sd);
+   _smart_scrollbar_reset(sd);
+}
+
+static void
+_smart_pan_changed_hook(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Evas_Coord x, y;
+   Evas_Coord w, h;
+   Smart_Data *sd;
+
+   sd = data;
+   sd->pan_func.get(sd->pan_obj, &x, &y);
+   sd->pan_func.child_size_get(sd->pan_obj, &w, &h);
+   if ((w != sd->child.w) || (h != sd->child.h))
+     {
+       sd->child.w = w;
+       sd->child.h = h;
+       _smart_scrollbar_size_adjust(sd);
+        evas_object_size_hint_min_set(sd->smart_obj, sd->child.w, sd->child.h);
+        elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+     }
+}
+
+static void
+_smart_pan_pan_changed_hook(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Evas_Coord x, y;
+   Smart_Data *sd;
+
+   sd = data;
+   sd->pan_func.get(sd->pan_obj, &x, &y);
+   if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) ||
+       (sd->scrollto.x.animator) || (sd->scrollto.y.animator))
+     {
+        _smart_anim_stop(sd->smart_obj);
+     }
+   if (sd->scrollto.x.animator)
+     {
+        ecore_animator_del(sd->scrollto.x.animator);
+        sd->scrollto.x.animator = NULL;
+     }
+   if (sd->scrollto.y.animator)
+     {
+        ecore_animator_del(sd->scrollto.y.animator);
+        sd->scrollto.y.animator = NULL;
+     }
+   if (sd->down.bounce_x_animator)
+     {
+        ecore_animator_del(sd->down.bounce_x_animator);
+        sd->down.bounce_x_animator = NULL;
+        sd->bouncemex = 0;
+     }
+   if (sd->down.bounce_y_animator)
+     {
+        ecore_animator_del(sd->down.bounce_y_animator);
+        sd->down.bounce_y_animator = NULL;
+        sd->bouncemey = 0;
+     }
+   elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+}
+
+static void
+_smart_event_wheel(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Evas_Event_Mouse_Wheel *ev;
+   Smart_Data *sd;
+   Evas_Coord x = 0, y = 0;
+
+   sd = data;
+   ev = event_info;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ;
+   if (evas_key_modifier_is_set(ev->modifiers, "Control") ||
+       evas_key_modifier_is_set(ev->modifiers, "Alt") ||
+       evas_key_modifier_is_set(ev->modifiers, "Shift") ||
+       evas_key_modifier_is_set(ev->modifiers, "Meta") ||
+       evas_key_modifier_is_set(ev->modifiers, "Hyper") ||
+       evas_key_modifier_is_set(ev->modifiers, "Super"))
+     return;
+   elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+   if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) ||
+       (sd->scrollto.x.animator) || (sd->scrollto.y.animator))
+     {
+        _smart_anim_stop(sd->smart_obj);
+     }
+   if (sd->scrollto.x.animator)
+     {
+        ecore_animator_del(sd->scrollto.x.animator);
+        sd->scrollto.x.animator = NULL;
+     }
+   if (sd->scrollto.y.animator)
+     {
+        ecore_animator_del(sd->scrollto.y.animator);
+        sd->scrollto.y.animator = NULL;
+     }
+   if (sd->down.bounce_x_animator)
+     {
+        ecore_animator_del(sd->down.bounce_x_animator);
+        sd->down.bounce_x_animator = NULL;
+        sd->bouncemex = 0;
+     }
+   if (sd->down.bounce_y_animator)
+     {
+        ecore_animator_del(sd->down.bounce_y_animator);
+        sd->down.bounce_y_animator = NULL;
+        sd->bouncemey = 0;
+     }
+   if (ev->direction == 0)
+     y += ev->z * sd->step.y;
+   else if (ev->direction == 1)
+     x += ev->z * sd->step.x;
+   elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+}
+
+static void
+_smart_event_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Evas_Event_Mouse_Down *ev;
+   Smart_Data *sd;
+   Evas_Coord x = 0, y = 0;
+
+   sd = data;
+   ev = event_info;
+//   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ;
+   if (_elm_config->thumbscroll_enable)
+     {
+        if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) ||
+            (sd->down.momentum_animator) || (sd->scrollto.x.animator) ||
+            (sd->scrollto.y.animator))
+          {
+             _smart_anim_stop(sd->smart_obj);
+          }
+        if (sd->scrollto.x.animator)
+          {
+             ecore_animator_del(sd->scrollto.x.animator);
+             sd->scrollto.x.animator = NULL;
+          }
+        if (sd->scrollto.y.animator)
+          {
+             ecore_animator_del(sd->scrollto.y.animator);
+             sd->scrollto.y.animator = NULL;
+          }
+        if (sd->down.bounce_x_animator)
+          {
+             ecore_animator_del(sd->down.bounce_x_animator);
+             sd->down.bounce_x_animator = NULL;
+             sd->bouncemex = 0;
+          }
+        if (sd->down.bounce_y_animator)
+          {
+             ecore_animator_del(sd->down.bounce_y_animator);
+             sd->down.bounce_y_animator = NULL;
+             sd->bouncemey = 0;
+          }
+       if (sd->down.hold_animator)
+         {
+            ecore_animator_del(sd->down.hold_animator);
+            sd->down.hold_animator = NULL;
+             _smart_drag_stop(sd->smart_obj);
+         }
+       if (sd->down.momentum_animator)
+         {
+            ecore_animator_del(sd->down.momentum_animator);
+            sd->down.momentum_animator = NULL;
+             sd->down.bounce_x_hold = 0;
+             sd->down.bounce_y_hold = 0;
+             sd->down.ax = 0;
+             sd->down.ay = 0;
+         }
+       if (ev->button == 1)
+         {
+            sd->down.now = 1;
+            sd->down.dragged = 0;
+            sd->down.dir_x = 0;
+            sd->down.dir_y = 0;
+            sd->down.x = ev->canvas.x;
+            sd->down.y = ev->canvas.y;
+            elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+            sd->down.sx = x;
+            sd->down.sy = y;
+            sd->down.locked = 0;
+            memset(&(sd->down.history[0]), 0, sizeof(sd->down.history[0]) * 20);
+#ifdef EVTIME
+            sd->down.history[0].timestamp = ev->timestamp / 1000.0;
+#else
+            sd->down.history[0].timestamp = ecore_loop_time_get();
+#endif
+            sd->down.history[0].x = ev->canvas.x;
+            sd->down.history[0].y = ev->canvas.y;
+         }
+        sd->down.dragged_began = 0;
+        sd->down.hold = 0;
+        sd->down.hold_parent = 0;
+        sd->down.cancelled = 0;
+     }
+}
+
+static int
+_smart_hold_animator(void *data)
+{
+   Smart_Data *sd = data;
+   Evas_Coord ox, oy;
+   
+   elm_smart_scroller_child_pos_get(sd->smart_obj, &ox, &oy);
+   if (sd->down.dir_x)
+     {
+        if ((!sd->widget) || 
+            (!elm_widget_drag_child_locked_x_get(sd->widget)))
+          {
+             ox = sd->down.hold_x;
+          }
+     }
+   if (sd->down.dir_y)
+     {
+        if ((!sd->widget) || 
+            (!elm_widget_drag_child_locked_y_get(sd->widget)))
+          {
+             oy = sd->down.hold_y;
+          }
+     }
+   elm_smart_scroller_child_pos_set(sd->smart_obj, ox, oy);
+   return 1;
+}
+
+static Eina_Bool
+_smart_event_post_up(void *data, Evas *e)
+{
+   Smart_Data *sd = data;
+   if (sd->widget)
+     {
+        if (sd->down.dragged)
+          {
+             elm_widget_drag_lock_x_set(sd->widget, 0);
+             elm_widget_drag_lock_y_set(sd->widget, 0);
+          }
+     }
+   return 1;
+}
+
+static void
+_smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Evas_Event_Mouse_Down *ev;
+   Smart_Data *sd;
+   Evas_Coord x = 0, y = 0, ox = 0, oy = 0;
+
+   sd = data;
+   ev = event_info;
+   sd->down.hold_parent = 0;
+//   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ;
+   evas_post_event_callback_push(e, _smart_event_post_up, sd);
+   // FIXME: respect elm_widget_scroll_hold_get of parent container
+   if (_elm_config->thumbscroll_enable)
+     {
+       if (ev->button == 1)
+         {
+             if (sd->down.onhold_animator)
+               {
+                  ecore_animator_del(sd->down.onhold_animator);
+                  sd->down.onhold_animator = NULL;
+               }
+            x = ev->canvas.x - sd->down.x;
+            y = ev->canvas.y - sd->down.y;
+             if (sd->down.dragged)
+               {
+                  _smart_drag_stop(sd->smart_obj);
+                  if ((!sd->hold) && (!sd->freeze))
+                    {
+                       double t, at, dt;
+                       int i;
+                       Evas_Coord ax, ay, dx, dy, vel;
+
+#ifdef EVTIME
+                       t = ev->timestamp / 1000.0;
+#else
+                       t = ecore_loop_time_get();
+#endif
+                       ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+                       ax = ev->canvas.x;
+                       ay = ev->canvas.y;
+                       at = 0.0;
+#ifdef SCROLLDBG
+                       printf("------ %i %i\n", ev->canvas.x, ev->canvas.y);
+#endif
+                       for (i = 0; i < 20; i++)
+                         {
+                            dt = t - sd->down.history[i].timestamp;
+                            if (dt > 0.2) break;
+#ifdef SCROLLDBG
+                            printf("H: %i %i @ %1.3f\n",
+                                   sd->down.history[i].x,
+                                   sd->down.history[i].y, dt);
+#endif
+                            at += dt;
+                            ax += sd->down.history[i].x;
+                            ay += sd->down.history[i].y;
+                         }
+                       ax /= (i + 1);
+                       ay /= (i + 1);
+                       at /= (i + 1);
+                       at *= 4.0;
+                       dx = ev->canvas.x - ax;
+                       dy = ev->canvas.y - ay;
+                       if (at > 0)
+                         {
+                            vel = sqrt((dx * dx) + (dy * dy)) / at;
+                            if ((_elm_config->thumbscroll_friction > 0.0) &&
+                                (vel > _elm_config->thumbscroll_momentum_threshhold) &&
+                                (!sd->freeze))
+                              {
+                                 sd->down.dx = ((double)dx / at);
+                                 sd->down.dy = ((double)dy / at);
+                                 ox = -sd->down.dx;
+                                 oy = -sd->down.dy;
+                                 if (!_smart_do_page(sd))
+                                   {
+                                      if (!sd->down.momentum_animator)
+                                        {
+                                           sd->down.momentum_animator = ecore_animator_add(_smart_momentum_animator, sd);
+                                           _smart_anim_start(sd->smart_obj);
+                                        }
+                                      sd->down.anim_start = ecore_loop_time_get();
+                                      elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+                                      sd->down.sx = x;
+                                      sd->down.sy = y;
+                                      sd->down.b0x = 0;
+                                      sd->down.b0y = 0;
+                                   }
+                              }
+                         }
+                       if (sd->down.hold_animator)
+                         {
+                            ecore_animator_del(sd->down.hold_animator);
+                            sd->down.hold_animator = NULL;
+                         }
+                    }
+                  evas_event_feed_hold(e, 0, ev->timestamp, ev->data);
+                  if (_smart_do_page(sd))
+                    {
+                       Evas_Coord pgx, pgy;
+
+                       elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+                       if ((!sd->widget) || 
+                           (!elm_widget_drag_child_locked_x_get(sd->widget)))
+                         {
+                            pgx = _smart_page_x_get(sd, ox);
+                            if (pgx != x) _smart_scrollto_x(sd, _elm_config->page_scroll_friction, pgx);
+                         }
+                       if ((!sd->widget) || 
+                           (!elm_widget_drag_child_locked_y_get(sd->widget)))
+                         {
+                            pgy = _smart_page_y_get(sd, oy);
+                            if (pgy != y) _smart_scrollto_y(sd, _elm_config->page_scroll_friction, pgy);
+                         }
+                    }
+              }
+             else
+               {
+                  if (_smart_do_page(sd))
+                    {
+                       Evas_Coord pgx, pgy;
+
+                       elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+                       if ((!sd->widget) || 
+                           (!elm_widget_drag_child_locked_x_get(sd->widget)))
+                         {
+                            pgx = _smart_page_x_get(sd, ox);
+                            if (pgx != x) _smart_scrollto_x(sd, _elm_config->page_scroll_friction, pgx);
+                         }
+                       if ((!sd->widget) || 
+                           (!elm_widget_drag_child_locked_y_get(sd->widget)))
+                         {
+                            pgy = _smart_page_y_get(sd, oy);
+                            if (pgy != y) _smart_scrollto_y(sd, _elm_config->page_scroll_friction, pgy);
+                         }
+                    }
+                  if (sd->down.hold_animator)
+                    {
+                       ecore_animator_del(sd->down.hold_animator);
+                       sd->down.hold_animator = NULL;
+                    }
+               }
+             if (sd->down.hold)
+               {
+                  ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+                  sd->down.hold = 0;
+               }
+             sd->down.dragged_began = 0;
+             sd->down.dir_x = 0;
+             sd->down.dir_y = 0;
+             sd->down.want_dragged = 0;
+            sd->down.dragged = 0;
+            sd->down.now = 0;
+             elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+             elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+             if (!_smart_do_page(sd))
+               bounce_eval(sd);
+         }
+     }
+}
+
+static int
+_smart_onhold_animator(void *data)
+{
+   Smart_Data *sd;
+   double t, td;
+   double vx, vy;
+   Evas_Coord x, y, ox, oy;
+
+   sd = data;
+   t = ecore_loop_time_get();
+   if (sd->down.onhold_tlast > 0.0)
+     {
+        td = t - sd->down.onhold_tlast;
+        vx = sd->down.onhold_vx * td * (double)_elm_config->thumbscroll_threshhold * 2.0;
+        vy = sd->down.onhold_vy * td * (double)_elm_config->thumbscroll_threshhold * 2.0;
+        elm_smart_scroller_child_pos_get(sd->smart_obj, &ox, &oy);
+        x = ox;
+        y = oy;
+        
+        if (sd->down.dir_x)
+          {
+             if ((!sd->widget) || 
+                 (!elm_widget_drag_child_locked_x_get(sd->widget)))
+               {
+                  sd->down.onhold_vxe += vx;
+                  x = ox + (int)sd->down.onhold_vxe;
+                  sd->down.onhold_vxe -= (int)sd->down.onhold_vxe;
+               }
+          }
+        
+        if (sd->down.dir_y)
+          {
+             if ((!sd->widget) || 
+                 (!elm_widget_drag_child_locked_y_get(sd->widget)))
+               {
+                  sd->down.onhold_vye += vy;
+                  y = oy + (int)sd->down.onhold_vye;
+                  sd->down.onhold_vye -= (int)sd->down.onhold_vye;
+               }
+          }
+        
+        elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+//        printf("scroll %i %i\n", sd->down.hold_x, sd->down.hold_y);
+     }
+   sd->down.onhold_tlast = t;
+   return 1;
+}
+
+static Eina_Bool
+_smart_event_post_move(void *data, Evas *e)
+{
+   Smart_Data *sd = data;
+   if (sd->down.want_dragged)
+     {
+        int start = 0;
+        
+        if (sd->down.hold_parent)
+          {
+             if ((sd->down.dir_x) && !can_scroll(sd, sd->down.hdir))
+               {
+                  sd->down.dir_x = 0;
+               }
+             if ((sd->down.dir_y) && !can_scroll(sd, sd->down.vdir))
+               {
+                  sd->down.dir_y = 0;
+               }
+          }
+        if (sd->down.dir_x)
+          {
+             if ((!sd->widget) || 
+                 (!elm_widget_drag_child_locked_x_get(sd->widget)))
+               {
+                  sd->down.want_dragged = 0;
+                  sd->down.dragged = 1;
+                  if (sd->widget)
+                    {
+                       elm_widget_drag_lock_x_set(sd->widget, 1);
+                    }
+                  start = 1;
+               }
+             else
+               sd->down.dir_x = 0;
+          }
+        if (sd->down.dir_y)
+          {
+             if ((!sd->widget) || 
+                 (!elm_widget_drag_child_locked_y_get(sd->widget)))
+               {
+                  sd->down.want_dragged = 0;
+                  sd->down.dragged = 1;
+                  if (sd->widget)
+                    {
+                       elm_widget_drag_lock_y_set(sd->widget, 1);
+                    }
+                  start = 1;
+               }
+             else
+               sd->down.dir_y = 0;
+          }
+        if ((!sd->down.dir_x) && (!sd->down.dir_y))
+          {
+             sd->down.cancelled = 1;
+          }
+        if (start) _smart_drag_start(sd->smart_obj);
+     }
+   return 1;
+}
+
+static void
+_smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Evas_Event_Mouse_Move *ev;
+   Smart_Data *sd;
+   Evas_Coord x = 0, y = 0;
+
+   sd = data;
+   ev = event_info;
+//   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->down.hold_parent = 1;
+   evas_post_event_callback_push(e, _smart_event_post_move, sd);
+   // FIXME: respect elm_widget_scroll_hold_get of parent container
+   if (_elm_config->thumbscroll_enable)
+     {
+       if (sd->down.now)
+         {
+             int dodir = 0;
+
+#ifdef SCROLLDBG
+             printf("::: %i %i\n", ev->cur.canvas.x, ev->cur.canvas.y);
+#endif
+            memmove(&(sd->down.history[1]), &(sd->down.history[0]),
+                    sizeof(sd->down.history[0]) * 19);
+#ifdef EVTIME
+            sd->down.history[0].timestamp = ev->timestamp / 1000.0;
+#else
+            sd->down.history[0].timestamp = ecore_loop_time_get();
+#endif
+            sd->down.history[0].x = ev->cur.canvas.x;
+            sd->down.history[0].y = ev->cur.canvas.y;
+
+             if (!sd->down.dragged_began)
+               {
+                  x = ev->cur.canvas.x - sd->down.x;
+                  y = ev->cur.canvas.y - sd->down.y;
+                  
+                  sd->down.hdir = -1;
+                  sd->down.vdir = -1;
+                    
+                  if      (x > 0) sd->down.hdir = LEFT;
+                  else if (x < 0) sd->down.hdir = RIGHT;
+                  if      (y > 0) sd->down.vdir = UP;
+                  else if (y < 0) sd->down.vdir = DOWN;
+                  
+                  if (x < 0) x = -x;
+                  if (y < 0) y = -y;
+             
+                  if ((sd->one_dir_at_a_time) &&
+                      (!((sd->down.dir_x) || (sd->down.dir_y))))
+                    {
+                       if (x > _elm_config->thumbscroll_threshhold)
+                         {
+                            if (x > (y * 2))
+                              {
+                                 sd->down.dir_x = 1;
+                                 sd->down.dir_y = 0;
+                                 dodir++;
+                              }
+                         }
+                       if (y > _elm_config->thumbscroll_threshhold)
+                         {
+                            if (y > (x * 2))
+                              {
+                                 sd->down.dir_x = 0;
+                                 sd->down.dir_y = 1;
+                                 dodir++;
+                              }
+                         }
+                       if (!dodir)
+                         {
+                            sd->down.dir_x = 1;
+                            sd->down.dir_y = 1;
+                         }
+                    }
+                  else
+                    {
+//                       can_scroll(sd, LEFT);
+//                       can_scroll(sd, RIGHT);
+//                       can_scroll(sd, UP);
+//                       can_scroll(sd, DOWN);
+                       sd->down.dir_x = 1;
+                       sd->down.dir_y = 1;
+                    }
+               }
+             if ((!sd->hold) && (!sd->freeze))
+               {
+                  if ((sd->down.dragged) ||
+                      (((x * x) + (y * y)) >
+                       (_elm_config->thumbscroll_threshhold *
+                        _elm_config->thumbscroll_threshhold)))
+                    {
+                       sd->down.dragged_began = 1;
+                       if (!sd->down.dragged)
+                         {
+                            sd->down.want_dragged = 1;
+                            ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+//                            evas_event_feed_hold(e, 1, ev->timestamp, ev->data);
+//                            _smart_drag_start(sd->smart_obj);
+                         }
+                       if (sd->down.dragged)
+                         {
+                            ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+                         }
+//                       ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+//                       sd->down.dragged = 1;
+                       if (sd->down.dir_x)
+                         x = sd->down.sx - (ev->cur.canvas.x - sd->down.x);
+                       else
+                         x = sd->down.sx;
+                       if (sd->down.dir_y)
+                         y = sd->down.sy - (ev->cur.canvas.y - sd->down.y);
+                       else
+                         y = sd->down.sy;
+                       if ((sd->down.dir_x) || (sd->down.dir_y))
+                         {
+                            if (!sd->down.locked)
+                              {
+                                 sd->down.locked_x = x;
+                                 sd->down.locked_y = y;
+                                 sd->down.locked = 1;
+                              }
+                            if (!((sd->down.dir_x) && (sd->down.dir_y)))
+                              {
+                                 if (sd->down.dir_x) y = sd->down.locked_y;
+                                 else x = sd->down.locked_x;
+                              }
+                         }
+                       sd->down.hold_x = x;
+                       sd->down.hold_y = y;
+                       if (!sd->down.hold_animator)
+                         sd->down.hold_animator = 
+                         ecore_animator_add(_smart_hold_animator, sd);
+//                       printf("a %i %i\n", sd->down.hold_x, sd->down.hold_y);
+//                       _smart_onhold_animator(sd);
+//                       elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+                    }
+                  else
+                    {
+                       if (sd->down.dragged_began)
+                         {
+                            ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+                            if (!sd->down.hold)
+                              {
+                                 sd->down.hold = 1;
+                                 evas_event_feed_hold(e, 1, ev->timestamp, ev->data);
+                              }
+                         }
+                    }
+              }
+             else if (!sd->freeze)
+               {
+                  Evas_Coord ex, ey, ew, eh;
+                  double vx = 0.0, vy = 0.0;
+
+                  evas_object_geometry_get(sd->event_obj, &ex, &ey, &ew, &eh);
+                  x = ev->cur.canvas.x - ex;
+                  y = ev->cur.canvas.y - ey;
+                  if (x < _elm_config->thumbscroll_threshhold)
+                    {
+                       if (_elm_config->thumbscroll_threshhold > 0.0)
+                         vx = -(double)(_elm_config->thumbscroll_threshhold - x) /
+                         _elm_config->thumbscroll_threshhold;
+                       else
+                         vx = -1.0;
+                    }
+                  else if (x > (ew - _elm_config->thumbscroll_threshhold))
+                    {
+                       if (_elm_config->thumbscroll_threshhold > 0.0)
+                         vx = (double)(_elm_config->thumbscroll_threshhold - (ew - x)) /
+                         _elm_config->thumbscroll_threshhold;
+                       else
+                         vx = 1.0;
+                    }
+                  if (y < _elm_config->thumbscroll_threshhold)
+                    {
+                       if (_elm_config->thumbscroll_threshhold > 0.0)
+                         vy = -(double)(_elm_config->thumbscroll_threshhold - y) /
+                         _elm_config->thumbscroll_threshhold;
+                       else
+                         vy = -1.0;
+                    }
+                  else if (y > (eh - _elm_config->thumbscroll_threshhold))
+                    {
+                       if (_elm_config->thumbscroll_threshhold > 0.0)
+                         vy = (double)(_elm_config->thumbscroll_threshhold - (eh - y)) /
+                         _elm_config->thumbscroll_threshhold;
+                       else
+                         vy = 1.0;
+                    }
+                  if ((vx != 0.0) || (vy != 0.0))
+                    {
+                       sd->down.onhold_vx = vx;
+                       sd->down.onhold_vy = vy;
+                       if (!sd->down.onhold_animator)
+                         {
+                            sd->down.onhold_vxe = 0.0;
+                            sd->down.onhold_vye = 0.0;
+                            sd->down.onhold_tlast = 0.0;
+                            sd->down.onhold_animator = ecore_animator_add(_smart_onhold_animator, sd);
+                         }
+//                       printf("b %i %i\n", sd->down.hold_x, sd->down.hold_y);
+                    }
+                  else
+                    {
+                       if (sd->down.onhold_animator)
+                         {
+                            ecore_animator_del(sd->down.onhold_animator);
+                            sd->down.onhold_animator = NULL;
+                         }
+                    }
+               }
+         }
+     }
+}
+
+static void
+_smart_event_key_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Evas_Event_Key_Down *ev;
+   Smart_Data *sd;
+   Evas_Coord x = 0, y = 0, vw = 0, vh = 0, mx = 0, my = 0;
+   int xch = 0, ych = 0;
+
+   sd = data;
+   ev = event_info;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
+   elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+   sd->pan_func.max_get(sd->pan_obj, &mx, &my);
+   evas_object_geometry_get(sd->pan_obj, NULL, NULL, &vw, &vh);
+   if (!strcmp(ev->keyname, "Left"))
+     {
+        x -= sd->step.x;
+        xch = 1;
+     }
+   else if (!strcmp(ev->keyname, "Right"))
+     {
+        x += sd->step.x;
+        xch = 1;
+     }
+   else if (!strcmp(ev->keyname, "Up"))
+     {
+        y -= sd->step.y;
+        ych = 1;
+     }
+   else if (!strcmp(ev->keyname, "Home"))
+     {
+        y = 0;
+        ych = 1;
+     }
+   else if (!strcmp(ev->keyname, "End"))
+     {
+        y = my;
+        ych = 1;
+     }
+   else if (!strcmp(ev->keyname, "Down"))
+     {
+        y += sd->step.y;
+        ych = 1;
+     }
+   else if (!strcmp(ev->keyname, "Prior"))
+     {
+       if (sd->page.y < 0)
+         y -= -(sd->page.y * vh) / 100;
+       else
+         y -= sd->page.y;
+        ych = 1;
+     }
+   else if (!strcmp(ev->keyname, "Next"))
+     {
+       if (sd->page.y < 0)
+         y += -(sd->page.y * vh) / 100;
+       else
+         y += sd->page.y;
+        ych = 1;
+     }
+   if (xch)
+     {
+        if (sd->scrollto.x.animator)
+          {
+             ecore_animator_del(sd->scrollto.x.animator);
+             sd->scrollto.x.animator = NULL;
+          }
+        if (sd->down.bounce_x_animator)
+          {
+             ecore_animator_del(sd->down.bounce_x_animator);
+             sd->down.bounce_x_animator = NULL;
+             sd->bouncemex = 0;
+          }
+     }
+   if (ych)
+     {
+        if (sd->scrollto.y.animator)
+          {
+             ecore_animator_del(sd->scrollto.y.animator);
+             sd->scrollto.y.animator = NULL;
+          }
+        if (sd->down.bounce_y_animator)
+          {
+             ecore_animator_del(sd->down.bounce_y_animator);
+             sd->down.bounce_y_animator = NULL;
+             sd->bouncemey = 0;
+          }
+     }
+
+   elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+}
+
+static void
+_smart_scrollbar_read(Smart_Data *sd)
+{
+   Evas_Coord x, y, mx = 0, my = 0, px, py;
+   double vx, vy;
+
+   edje_object_part_drag_value_get(sd->edje_obj, "elm.dragable.vbar", NULL, &vy);
+   edje_object_part_drag_value_get(sd->edje_obj, "elm.dragable.hbar", &vx, NULL);
+   sd->pan_func.max_get(sd->pan_obj, &mx, &my);
+   x = vx * (double)mx;
+   y = vy * (double)my;
+   sd->pan_func.get(sd->pan_obj, &px, &py);
+   sd->pan_func.set(sd->pan_obj, x, y);
+   if ((px != x) || (py != y))
+     edje_object_signal_emit(sd->edje_obj, "elm,action,scroll", "elm");
+}
+
+static void
+_smart_scrollbar_reset(Smart_Data *sd)
+{
+   Evas_Coord px = 0, py = 0;
+
+   edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
+   edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
+   if ((!sd->child_obj) && (!sd->extern_pan))
+     {
+       edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
+       edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
+     }
+   sd->pan_func.get(sd->pan_obj, &px, &py);
+   sd->pan_func.set(sd->pan_obj, 0, 0);
+   if ((px != 0) || (py != 0))
+     edje_object_signal_emit(sd->edje_obj, "elm,action,scroll", "elm");
+}
+
+static int
+_smart_scrollbar_bar_v_visibility_adjust(Smart_Data *sd)
+{
+   int scroll_v_vis_change = 0;
+   Evas_Coord w, h, vw, vh;
+
+   w = sd->child.w;
+   h = sd->child.h;
+   evas_object_geometry_get(sd->pan_obj, NULL, NULL, &vw, &vh);
+   if (sd->vbar_visible)
+     {
+       if (sd->vbar_flags == ELM_SMART_SCROLLER_POLICY_AUTO)
+         {
+            if ((sd->child_obj) || (sd->extern_pan))
+              {
+                 if (h <= vh)
+                   {
+                      scroll_v_vis_change = 1;
+                      sd->vbar_visible = 0;
+                   }
+              }
+            else
+              {
+                 scroll_v_vis_change = 1;
+                 sd->vbar_visible = 0;
+              }
+         }
+       else if (sd->vbar_flags == ELM_SMART_SCROLLER_POLICY_OFF)
+         {
+            scroll_v_vis_change = 1;
+            sd->vbar_visible = 0;
+         }
+     }
+   else
+     {
+       if (sd->vbar_flags == ELM_SMART_SCROLLER_POLICY_AUTO)
+         {
+            if ((sd->child_obj) || (sd->extern_pan))
+              {
+                 if (h > vh)
+                   {
+                      scroll_v_vis_change = 1;
+                      sd->vbar_visible = 1;
+                   }
+              }
+         }
+       else if (sd->vbar_flags == ELM_SMART_SCROLLER_POLICY_ON)
+         {
+            scroll_v_vis_change = 1;
+            sd->vbar_visible = 1;
+         }
+     }
+   if (scroll_v_vis_change)
+     {
+        if (sd->vbar_flags != ELM_SMART_SCROLLER_POLICY_OFF)
+          {
+             if (sd->vbar_visible)
+               edje_object_signal_emit(sd->edje_obj, "elm,action,show,vbar", "elm");
+             else
+               edje_object_signal_emit(sd->edje_obj, "elm,action,hide,vbar", "elm");
+             edje_object_message_signal_process(sd->edje_obj);
+             _smart_scrollbar_size_adjust(sd);
+          }
+        else
+          edje_object_signal_emit(sd->edje_obj, "elm,action,hide,vbar", "elm");
+     }
+   return scroll_v_vis_change;
+}
+
+static int
+_smart_scrollbar_bar_h_visibility_adjust(Smart_Data *sd)
+{
+   int scroll_h_vis_change = 0;
+   Evas_Coord w, h, vw, vh;
+
+   w = sd->child.w;
+   h = sd->child.h;
+   evas_object_geometry_get(sd->pan_obj, NULL, NULL, &vw, &vh);
+   if (sd->hbar_visible)
+     {
+       if (sd->hbar_flags == ELM_SMART_SCROLLER_POLICY_AUTO)
+         {
+            if ((sd->child_obj) || (sd->extern_pan))
+              {
+                 if (w <= vw)
+                   {
+                      scroll_h_vis_change = 1;
+                      sd->hbar_visible = 0;
+                   }
+              }
+            else
+              {
+                 scroll_h_vis_change = 1;
+                 sd->hbar_visible = 0;
+              }
+         }
+       else if (sd->hbar_flags == ELM_SMART_SCROLLER_POLICY_OFF)
+         {
+            scroll_h_vis_change = 1;
+            sd->hbar_visible = 0;
+         }
+     }
+   else
+     {
+       if (sd->hbar_flags == ELM_SMART_SCROLLER_POLICY_AUTO)
+         {
+            if ((sd->child_obj) || (sd->extern_pan))
+              {
+                 if (w > vw)
+                   {
+                      scroll_h_vis_change = 1;
+                      sd->hbar_visible = 1;
+                   }
+              }
+         }
+       else if (sd->hbar_flags == ELM_SMART_SCROLLER_POLICY_ON)
+         {
+            scroll_h_vis_change = 1;
+            sd->hbar_visible = 1;
+         }
+     }
+   if (scroll_h_vis_change)
+     {
+        if (sd->hbar_flags != ELM_SMART_SCROLLER_POLICY_OFF)
+          {
+             if (sd->hbar_visible)
+               edje_object_signal_emit(sd->edje_obj, "elm,action,show,hbar", "elm");
+             else
+               edje_object_signal_emit(sd->edje_obj, "elm,action,hide,hbar", "elm");
+             edje_object_message_signal_process(sd->edje_obj);
+             _smart_scrollbar_size_adjust(sd);
+          }
+        else
+          edje_object_signal_emit(sd->edje_obj, "elm,action,hide,hbar", "elm");
+       _smart_scrollbar_size_adjust(sd);
+     }
+   return scroll_h_vis_change;
+}
+
+static void
+_smart_scrollbar_bar_visibility_adjust(Smart_Data *sd)
+{
+   int changed = 0;
+
+   changed |= _smart_scrollbar_bar_h_visibility_adjust(sd);
+   changed |= _smart_scrollbar_bar_v_visibility_adjust(sd);
+   if (changed)
+     {
+       _smart_scrollbar_bar_h_visibility_adjust(sd);
+       _smart_scrollbar_bar_v_visibility_adjust(sd);
+     }
+}
+
+static void
+_smart_scrollbar_size_adjust(Smart_Data *sd)
+{
+   if ((sd->child_obj) || (sd->extern_pan))
+     {
+       Evas_Coord x, y, w, h, mx = 0, my = 0, vw = 0, vh = 0, px, py;
+       double vx, vy, size;
+
+       edje_object_part_geometry_get(sd->edje_obj, "elm.swallow.content",
+                                     NULL, NULL, &vw, &vh);
+       w = sd->child.w;
+       if (w < 1) w = 1;
+       size = (double)vw / (double)w;
+       if (size > 1.0)
+         {
+            size = 1.0;
+            edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
+         }
+       edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.hbar", size, 1.0);
+
+       h = sd->child.h;
+       if (h < 1) h = 1;
+       size = (double)vh / (double)h;
+       if (size > 1.0)
+         {
+            size = 1.0;
+            edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
+         }
+       edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.vbar", 1.0, size);
+
+       edje_object_part_drag_value_get(sd->edje_obj, "elm.dragable.hbar", &vx, NULL);
+       edje_object_part_drag_value_get(sd->edje_obj, "elm.dragable.vbar", NULL, &vy);
+       sd->pan_func.max_get(sd->pan_obj, &mx, &my);
+       x = vx * mx;
+       y = vy * my;
+
+       edje_object_part_drag_step_set(sd->edje_obj, "elm.dragable.hbar", (double)sd->step.x / (double)w, 0.0);
+       edje_object_part_drag_step_set(sd->edje_obj, "elm.dragable.vbar", 0.0, (double)sd->step.y / (double)h);
+       if (sd->page.x > 0)
+         edje_object_part_drag_page_set(sd->edje_obj, "elm.dragable.hbar", (double)sd->page.x / (double)w, 0.0);
+       else
+         edje_object_part_drag_page_set(sd->edje_obj, "elm.dragable.hbar", -((double)sd->page.x * ((double)vw / (double)w)) / 100.0, 0.0);
+       if (sd->page.y > 0)
+         edje_object_part_drag_page_set(sd->edje_obj, "elm.dragable.vbar", 0.0, (double)sd->page.y / (double)h);
+       else
+         edje_object_part_drag_page_set(sd->edje_obj, "elm.dragable.vbar", 0.0, -((double)sd->page.y * ((double)vh / (double)h)) / 100.0);
+
+       sd->pan_func.get(sd->pan_obj, &px, &py);
+        if (vx != mx) x = px;
+        if (vy != my) y = py;
+       sd->pan_func.set(sd->pan_obj, x, y);
+//     if ((px != 0) || (py != 0))
+//       edje_object_signal_emit(sd->edje_obj, "elm,action,scroll", "elm");
+     }
+   else
+     {
+       Evas_Coord px = 0, py = 0;
+
+       edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
+       edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
+       sd->pan_func.get(sd->pan_obj, &px, &py);
+       sd->pan_func.set(sd->pan_obj, 0, 0);
+       if ((px != 0) || (py != 0))
+         edje_object_signal_emit(sd->edje_obj, "elm,action,scroll", "elm");
+     }
+   _smart_scrollbar_bar_visibility_adjust(sd);
+}
+
+static void
+_smart_reconfigure(Smart_Data *sd)
+{
+   evas_object_move(sd->edje_obj, sd->x, sd->y);
+   evas_object_resize(sd->edje_obj, sd->w, sd->h);
+   evas_object_move(sd->event_obj, sd->x, sd->y);
+   evas_object_resize(sd->event_obj, sd->w, sd->h);
+   _smart_scrollbar_size_adjust(sd);
+}
+
+static void
+_smart_add(Evas_Object *obj)
+{
+   Smart_Data *sd;
+   Evas_Object *o;
+
+   sd = calloc(1, sizeof(Smart_Data));
+   if (!sd) return;
+   evas_object_smart_data_set(obj, sd);
+
+   sd->smart_obj = obj;
+   sd->x = 0;
+   sd->y = 0;
+   sd->w = 0;
+   sd->h = 0;
+   sd->step.x = 32;
+   sd->step.y = 32;
+   sd->page.x = -50;
+   sd->page.y = -50;
+   sd->hbar_flags = ELM_SMART_SCROLLER_POLICY_AUTO;
+   sd->vbar_flags = ELM_SMART_SCROLLER_POLICY_AUTO;
+   sd->hbar_visible = 1;
+   sd->vbar_visible = 1;
+
+   sd->bounce_horiz = 1;
+   sd->bounce_vert = 1;
+
+   sd->one_dir_at_a_time = 1;
+
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN, _smart_event_key_down, sd);
+   evas_object_propagate_events_set(obj, 0);
+
+   o = edje_object_add(evas_object_evas_get(obj));
+   sd->edje_obj = o;
+   // FIXME: null parent obj ... :(
+   _elm_theme_object_set(NULL, o, "scroller", "base", "default");
+   edje_object_signal_callback_add(o, "drag", "elm.dragable.vbar", _smart_edje_drag_v, sd);
+   edje_object_signal_callback_add(o, "drag,start", "elm.dragable.vbar", _smart_edje_drag_v_start, sd);
+   edje_object_signal_callback_add(o, "drag,stop", "elm.dragable.vbar", _smart_edje_drag_v_stop, sd);
+   edje_object_signal_callback_add(o, "drag,step", "elm.dragable.vbar", _smart_edje_drag_v, sd);
+   edje_object_signal_callback_add(o, "drag,page", "elm.dragable.vbar", _smart_edje_drag_v, sd);
+   edje_object_signal_callback_add(o, "drag", "elm.dragable.hbar", _smart_edje_drag_h, sd);
+   edje_object_signal_callback_add(o, "drag,start", "elm.dragable.hbar", _smart_edje_drag_h_start, sd);
+   edje_object_signal_callback_add(o, "drag,stop", "elm.dragable.hbar", _smart_edje_drag_h_stop, sd);
+   edje_object_signal_callback_add(o, "drag,step", "elm.dragable.hbar", _smart_edje_drag_h, sd);
+   edje_object_signal_callback_add(o, "drag,page", "elm.dragable.hbar", _smart_edje_drag_h, sd);
+   evas_object_smart_member_add(o, obj);
+
+   o = evas_object_rectangle_add(evas_object_evas_get(obj));
+   sd->event_obj = o;
+   evas_object_color_set(o, 0, 0, 0, 0);
+   evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_WHEEL, _smart_event_wheel, sd);
+   evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _smart_event_mouse_down, sd);
+   evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _smart_event_mouse_up, sd);
+   evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE, _smart_event_mouse_move, sd);
+   evas_object_smart_member_add(o, obj);
+   evas_object_repeat_events_set(o, 1);
+
+   sd->pan_func.set = _elm_smart_pan_set;
+   sd->pan_func.get = _elm_smart_pan_get;
+   sd->pan_func.max_get = _elm_smart_pan_max_get;
+   sd->pan_func.child_size_get = _elm_smart_pan_child_size_get;
+
+   _smart_scrollbar_reset(sd);
+}
+
+static void
+_smart_del(Evas_Object *obj)
+{
+   INTERNAL_ENTRY;
+   elm_smart_scroller_child_set(obj, NULL);
+   if (!sd->extern_pan) evas_object_del(sd->pan_obj);
+   evas_object_del(sd->edje_obj);
+   evas_object_del(sd->event_obj);
+   if (sd->down.hold_animator) ecore_animator_del(sd->down.hold_animator);
+   if (sd->down.onhold_animator) ecore_animator_del(sd->down.onhold_animator);
+   if (sd->down.momentum_animator) ecore_animator_del(sd->down.momentum_animator);
+   if (sd->down.bounce_x_animator) ecore_animator_del(sd->down.bounce_x_animator);
+   if (sd->down.bounce_y_animator) ecore_animator_del(sd->down.bounce_y_animator);
+   if (sd->scrollto.x.animator) ecore_animator_del(sd->scrollto.x.animator);
+   if (sd->scrollto.y.animator) ecore_animator_del(sd->scrollto.y.animator);
+   free(sd);
+   evas_object_smart_data_set(obj, NULL);
+}
+
+static void
+_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   INTERNAL_ENTRY;
+   sd->x = x;
+   sd->y = y;
+   _smart_reconfigure(sd);
+}
+
+static void
+_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+   INTERNAL_ENTRY;
+   sd->w = w;
+   sd->h = h;
+   _smart_reconfigure(sd);
+}
+
+static void
+_smart_show(Evas_Object *obj)
+{
+   INTERNAL_ENTRY;
+   evas_object_show(sd->edje_obj);
+   evas_object_show(sd->event_obj);
+}
+
+static void
+_smart_hide(Evas_Object *obj)
+{
+   INTERNAL_ENTRY;
+   evas_object_hide(sd->edje_obj);
+   evas_object_hide(sd->event_obj);
+}
+
+static void
+_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
+{
+   INTERNAL_ENTRY;
+   evas_object_color_set(sd->edje_obj, r, g, b, a);
+}
+
+static void
+_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
+{
+   INTERNAL_ENTRY;
+   evas_object_clip_set(sd->edje_obj, clip);
+   evas_object_clip_set(sd->event_obj, clip);
+}
+
+static void
+_smart_clip_unset(Evas_Object *obj)
+{
+   INTERNAL_ENTRY;
+   evas_object_clip_unset(sd->edje_obj);
+   evas_object_clip_unset(sd->event_obj);
+}
+
+/* never need to touch this */
+
+static void
+_smart_init(void)
+{
+   if (_smart) return;
+     {
+       static const Evas_Smart_Class sc =
+         {
+            SMART_NAME,
+              EVAS_SMART_CLASS_VERSION,
+              _smart_add,
+              _smart_del,
+              _smart_move,
+              _smart_resize,
+              _smart_show,
+              _smart_hide,
+              _smart_color_set,
+              _smart_clip_set,
+              _smart_clip_unset,
+              NULL,
+              NULL,
+              NULL,
+              NULL,
+               NULL,
+               NULL,
+               NULL
+         };
+       _smart = evas_smart_class_new(&sc);
+     }
+}
+
diff --git a/src/lib/els_scroller.h b/src/lib/els_scroller.h
new file mode 100644 (file)
index 0000000..4a4acc4
--- /dev/null
@@ -0,0 +1,33 @@
+typedef enum _Elm_Smart_Scroller_Policy
+{
+   ELM_SMART_SCROLLER_POLICY_AUTO,
+   ELM_SMART_SCROLLER_POLICY_ON,
+   ELM_SMART_SCROLLER_POLICY_OFF
+}
+Elm_Smart_Scroller_Policy;
+
+Evas_Object *elm_smart_scroller_add             (Evas *evas);
+void elm_smart_scroller_child_set               (Evas_Object *obj, Evas_Object *child);
+void elm_smart_scroller_extern_pan_set          (Evas_Object *obj, Evas_Object *pan, void (*pan_set) (Evas_Object *obj, Evas_Coord x, Evas_Coord y), void (*pan_get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y), void (*pan_max_get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y), void (*pan_child_size_get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y));
+void elm_smart_scroller_custom_edje_file_set    (Evas_Object *obj, char *file, char *group);
+void elm_smart_scroller_child_pos_set           (Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+void elm_smart_scroller_child_pos_get           (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y);
+void elm_smart_scroller_child_region_show       (Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
+void elm_smart_scroller_child_viewport_size_get (Evas_Object *obj, Evas_Coord *w, Evas_Coord *h);
+void elm_smart_scroller_step_size_set           (Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+void elm_smart_scroller_step_size_get           (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y);
+void elm_smart_scroller_page_size_set           (Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+void elm_smart_scroller_page_size_get           (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y);
+void elm_smart_scroller_policy_set              (Evas_Object *obj, Elm_Smart_Scroller_Policy hbar, Elm_Smart_Scroller_Policy vbar);
+void elm_smart_scroller_policy_get              (Evas_Object *obj, Elm_Smart_Scroller_Policy *hbar, Elm_Smart_Scroller_Policy *vbar);
+Evas_Object *elm_smart_scroller_edje_object_get (Evas_Object *obj);
+void elm_smart_scroller_single_dir_set          (Evas_Object *obj, Eina_Bool single_dir);
+Eina_Bool elm_smart_scroller_single_dir_get     (Evas_Object *obj);
+void elm_smart_scroller_object_theme_set        (Evas_Object *parent, Evas_Object *obj, const char *clas, const char *group, const char *style);
+void elm_smart_scroller_hold_set                (Evas_Object *obj, Eina_Bool hold);
+void elm_smart_scroller_freeze_set              (Evas_Object *obj, Eina_Bool freeze);
+void elm_smart_scroller_bounce_allow_set        (Evas_Object *obj, Eina_Bool horiz, Eina_Bool vert);
+void elm_smart_scroller_bounce_allow_get        (const Evas_Object *obj, Eina_Bool *horiz, Eina_Bool *vert);
+void elm_smart_scroller_paging_set              (Evas_Object *obj, double pagerel_h, double pagerel_v, Evas_Coord pagesize_h, Evas_Coord pagesize_v);
+void elm_smart_scroller_region_bring_in         (Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
+void elm_smart_scroller_widget_set              (Evas_Object *obj, Evas_Object *wid);
diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am
new file mode 100644 (file)
index 0000000..d489245
--- /dev/null
@@ -0,0 +1,5 @@
+AUTOMAKE_OPTIONS     = 1.4 foreign
+MAINTAINERCLEANFILES = Makefile.in
+
+SUBDIRS = \
+test_entry
diff --git a/src/modules/test_entry/Makefile.am b/src/modules/test_entry/Makefile.am
new file mode 100644 (file)
index 0000000..bea3972
--- /dev/null
@@ -0,0 +1,31 @@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_builddir) \
+-I$(top_srcdir) \
+-I$(top_srcdir)/src/lib \
+-I$(top_builddir)/src/lib \
+-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
+-DPACKAGE_LIB_DIR=\"$(libdir)\" \
+@ELEMENTARY_CFLAGS@ \
+@ELEMENTARY_X_CFLAGS@ \
+@ELEMENTARY_FB_CFLAGS@ \
+@ELEMENTARY_WIN32_CFLAGS@ \
+@ELEMENTARY_WINCE_CFLAGS@ \
+@ELEMENTARY_EDBUS_CFLAGS@ \
+@ELEMENTARY_EFREET_CFLAGS@
+
+if ELEMENTARY_WINDOWS_BUILD
+AM_CPPFLAGS += -DELEMENTARY_BUILD
+endif
+
+pkgdir = $(libdir)/elementary/modules/test_entry/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = mod.c
+
+module_la_LIBADD = $(top_builddir)/src/lib/libelementary.la
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
diff --git a/src/modules/test_entry/mod.c b/src/modules/test_entry/mod.c
new file mode 100644 (file)
index 0000000..acf2990
--- /dev/null
@@ -0,0 +1,33 @@
+#include <Elementary.h>
+
+// module api funcs needed
+EAPI int
+elm_modapi_init(void *m)
+{
+   return 1; // succeed always
+}
+
+EAPI int
+elm_modapi_shutdown(void *m)
+{
+   return 1; // succeed always
+}
+
+// module fucns for the specific module type
+EAPI void
+obj_hook(Evas_Object *obj)
+{
+   printf("hook: %p\n", obj);
+}
+
+EAPI void
+obj_unhook(Evas_Object *obj)
+{
+   printf("unhook: %p\n", obj);
+}
+
+EAPI void
+obj_longpress(Evas_Object *obj)
+{
+   printf("longpress: %p\n", obj);
+}