REVERT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

this breaks theme api. so NO! come back with a version that doesn't
break it.



SVN revision: 70679
This commit is contained in:
Carsten Haitzler 2012-05-03 01:19:05 +00:00
parent 0018a167ff
commit c0f2f4be91
86 changed files with 17188 additions and 20054 deletions

View File

@ -569,7 +569,7 @@ group { name: "elm/bubble/bottom_right/default";
type: SWALLOW;
description { state: "default" 0.0;
fixed: 1 1;
visible: 0;
visible: 0.0;
align: 1.0 1.0;
aspect: 1.0 1.0;
aspect_preference: VERTICAL;

View File

@ -32,7 +32,7 @@ group { name: "elm/button/base/default";
}
}
}
part { name: "elm.swallow.icon";
part { name: "elm.swallow.content";
type: SWALLOW;
description { state: "default" 0.0;
fixed: 1 0;
@ -69,7 +69,7 @@ group { name: "elm/button/base/default";
scale: 1;
description { state: "default" 0.0;
visible: 0;
rel1.to_x: "elm.swallow.icon";
rel1.to_x: "elm.swallow.content";
rel1.relative: 1.0 0.0;
rel1.offset: 0 4;
rel2.offset: -5 -5;
@ -227,9 +227,9 @@ group { name: "elm/button/base/default";
script {
new st[31];
new Float:vl;
get_state(PART:"elm.swallow.icon", st, 30, vl);
get_state(PART:"elm.swallow.content", st, 30, vl);
if (!strcmp(st, "icononly"))
set_state(PART:"elm.swallow.icon", "visible", 0.0);
set_state(PART:"elm.swallow.content", "visible", 0.0);
get_state(PART:"elm.text", st, 30, vl);
if (!strcmp(st, "disabled") || (!strcmp(st, "disabled_visible")))
set_state(PART:"elm.text", "disabled_visible", 0.0);
@ -243,9 +243,9 @@ group { name: "elm/button/base/default";
script {
new st[31];
new Float:vl;
get_state(PART:"elm.swallow.icon", st, 30, vl);
get_state(PART:"elm.swallow.content", st, 30, vl);
if (!strcmp(st, "visible"))
set_state(PART:"elm.swallow.icon", "icononly", 0.0);
set_state(PART:"elm.swallow.content", "icononly", 0.0);
set_state(PART:"elm.text", "default", 0.0);
get_state(PART:"elm.text", st, 30, vl);
if (!strcmp(st, "default") || (!strcmp(st, "visible")))
@ -262,16 +262,16 @@ group { name: "elm/button/base/default";
new Float:vl;
get_state(PART:"elm.text", st, 30, vl);
if (!strcmp(st, "visible"))
set_state(PART:"elm.swallow.icon", "visible", 0.0);
set_state(PART:"elm.swallow.content", "visible", 0.0);
else
set_state(PART:"elm.swallow.icon", "icononly", 0.0);
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.icon";
target: "elm.swallow.content";
}
program { name: "disable";
signal: "elm,state,disabled";
@ -359,7 +359,7 @@ group { name: "elm/button/base/hoversel_vertical/default";
align: 0.0 0.5;
}
}
part { name: "elm.swallow.icon";
part { name: "elm.swallow.content";
type: SWALLOW;
description { state: "default" 0.0;
fixed: 1 0;
@ -406,7 +406,7 @@ group { name: "elm/button/base/hoversel_vertical/default";
scale: 1;
description { state: "default" 0.0;
visible: 0;
rel1.to_x: "elm.swallow.icon";
rel1.to_x: "elm.swallow.content";
rel1.relative: 1.0 0.0;
rel1.offset: 0 4;
rel2.offset: -5 -5;
@ -541,9 +541,9 @@ group { name: "elm/button/base/hoversel_vertical/default";
script {
new st[31];
new Float:vl;
get_state(PART:"elm.swallow.icon", st, 30, vl);
get_state(PART:"elm.swallow.content", st, 30, vl);
if (!strcmp(st, "icononly"))
set_state(PART:"elm.swallow.icon", "visible", 0.0);
set_state(PART:"elm.swallow.content", "visible", 0.0);
set_state(PART:"elm.text", "visible", 0.0);
}
}
@ -553,9 +553,9 @@ group { name: "elm/button/base/hoversel_vertical/default";
script {
new st[31];
new Float:vl;
get_state(PART:"elm.swallow.icon", st, 30, vl);
get_state(PART:"elm.swallow.content", st, 30, vl);
if (!strcmp(st, "visible"))
set_state(PART:"elm.swallow.icon", "icononly", 0.0);
set_state(PART:"elm.swallow.content", "icononly", 0.0);
set_state(PART:"elm.text", "default", 0.0);
}
}
@ -567,16 +567,16 @@ group { name: "elm/button/base/hoversel_vertical/default";
new Float:vl;
get_state(PART:"elm.text", st, 30, vl);
if (!strcmp(st, "visible"))
set_state(PART:"elm.swallow.icon", "visible", 0.0);
set_state(PART:"elm.swallow.content", "visible", 0.0);
else
set_state(PART:"elm.swallow.icon", "icononly", 0.0);
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.icon";
target: "elm.swallow.content";
}
program { name: "disable";
signal: "elm,state,disabled";
@ -644,7 +644,7 @@ group { name: "elm/button/base/hoversel_vertical_entry/default";
color: 255 255 255 255;
}
}
part { name: "elm.swallow.icon";
part { name: "elm.swallow.content";
type: SWALLOW;
description { state: "default" 0.0;
visible: 0;
@ -688,7 +688,7 @@ group { name: "elm/button/base/hoversel_vertical_entry/default";
scale: 1;
clip_to: "textvis";
description { state: "default" 0.0;
rel1.to_x: "elm.swallow.icon";
rel1.to_x: "elm.swallow.content";
rel1.relative: 1.0 0.0;
rel1.offset: 0 4;
rel2.offset: -5 -5;
@ -750,9 +750,9 @@ group { name: "elm/button/base/hoversel_vertical_entry/default";
script {
new st[31];
new Float:vl;
get_state(PART:"elm.swallow.icon", st, 30, vl);
get_state(PART:"elm.swallow.content", st, 30, vl);
if (!strcmp(st, "icononly"))
set_state(PART:"elm.swallow.icon", "visible", 0.0);
set_state(PART:"elm.swallow.content", "visible", 0.0);
set_state(PART:"textvis", "visible", 0.0);
set_state(PART:"elm.text", "visible", 0.0);
}
@ -763,9 +763,9 @@ group { name: "elm/button/base/hoversel_vertical_entry/default";
script {
new st[31];
new Float:vl;
get_state(PART:"elm.swallow.icon", st, 30, vl);
get_state(PART:"elm.swallow.content", st, 30, vl);
if (!strcmp(st, "visible"))
set_state(PART:"elm.swallow.icon", "icononly", 0.0);
set_state(PART:"elm.swallow.content", "icononly", 0.0);
set_state(PART:"textvis", "default", 0.0);
set_state(PART:"elm.text", "default", 0.0);
}
@ -778,16 +778,16 @@ group { name: "elm/button/base/hoversel_vertical_entry/default";
new Float:vl;
get_state(PART:"textvis", st, 30, vl);
if (!strcmp(st, "visible"))
set_state(PART:"elm.swallow.icon", "visible", 0.0);
set_state(PART:"elm.swallow.content", "visible", 0.0);
else
set_state(PART:"elm.swallow.icon", "icononly", 0.0);
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.icon";
target: "elm.swallow.content";
}
}
}
@ -833,7 +833,7 @@ group { name: "elm/button/base/anchor";
}
}
}
part { name: "elm.swallow.icon";
part { name: "elm.swallow.content";
type: SWALLOW;
description { state: "default" 0.0;
fixed: 1 0;
@ -870,7 +870,7 @@ group { name: "elm/button/base/anchor";
scale: 1;
description { state: "default" 0.0;
visible: 0;
rel1.to_x: "elm.swallow.icon";
rel1.to_x: "elm.swallow.content";
rel1.relative: 1.0 0.0;
rel1.offset: 0 4;
rel2.offset: -5 -5;
@ -1020,9 +1020,9 @@ group { name: "elm/button/base/anchor";
script {
new st[31];
new Float:vl;
get_state(PART:"elm.swallow.icon", st, 30, vl);
get_state(PART:"elm.swallow.content", st, 30, vl);
if (!strcmp(st, "icononly"))
set_state(PART:"elm.swallow.icon", "visible", 0.0);
set_state(PART:"elm.swallow.content", "visible", 0.0);
get_state(PART:"elm.text", st, 30, vl);
if (!strcmp(st, "disabled") || (!strcmp(st, "disabled_visible")))
set_state(PART:"elm.text", "disabled_visible", 0.0);
@ -1036,9 +1036,9 @@ group { name: "elm/button/base/anchor";
script {
new st[31];
new Float:vl;
get_state(PART:"elm.swallow.icon", st, 30, vl);
get_state(PART:"elm.swallow.content", st, 30, vl);
if (!strcmp(st, "visible"))
set_state(PART:"elm.swallow.icon", "icononly", 0.0);
set_state(PART:"elm.swallow.content", "icononly", 0.0);
get_state(PART:"elm.text", st, 30, vl);
if (!strcmp(st, "default") || (!strcmp(st, "visible")))
set_state(PART:"elm.text", "default", 0.0);
@ -1054,16 +1054,16 @@ group { name: "elm/button/base/anchor";
new Float:vl;
get_state(PART:"elm.text", st, 30, vl);
if (!strcmp(st, "visible"))
set_state(PART:"elm.swallow.icon", "visible", 0.0);
set_state(PART:"elm.swallow.content", "visible", 0.0);
else
set_state(PART:"elm.swallow.icon", "icononly", 0.0);
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.icon";
target: "elm.swallow.content";
}
program { name: "disable";
signal: "elm,state,disabled";

View File

@ -56,7 +56,7 @@ group { name: "elm/check/base/default";
visible: 1;
}
}
part { name: "elm.swallow.icon";
part { name: "elm.swallow.content";
type: SWALLOW;
description { state: "default" 0.0;
fixed: 1 0;
@ -93,7 +93,7 @@ group { name: "elm/check/base/default";
scale: 1;
description { state: "default" 0.0;
visible: 0;
rel1.to_x: "elm.swallow.icon";
rel1.to_x: "elm.swallow.content";
rel1.relative: 1.0 0.0;
rel1.offset: 1 1;
rel2.relative: 1.0 1.0;
@ -177,13 +177,13 @@ group { name: "elm/check/base/default";
signal: "elm,state,icon,visible";
source: "elm";
action: STATE_SET "visible" 0.0;
target: "elm.swallow.icon";
target: "elm.swallow.content";
}
program { name: "icon_hide";
signal: "elm,state,icon,hidden";
source: "elm";
action: STATE_SET "default" 0.0;
target: "elm.swallow.icon";
target: "elm.swallow.content";
}
program { name: "disable";
signal: "elm,state,disabled";
@ -202,11 +202,11 @@ group { name: "elm/check/base/default";
else
set_state(PART:"elm.text", "disabled", 0.0);
get_state(PART:"elm.swallow.icon", st, 30, vl);
get_state(PART:"elm.swallow.content", st, 30, vl);
if (!strcmp(st, "visible"))
set_state(PART:"elm.swallow.icon", "disabled_visible", 0.0);
set_state(PART:"elm.swallow.content", "disabled_visible", 0.0);
else
set_state(PART:"elm.swallow.icon", "disabled", 0.0);
set_state(PART:"elm.swallow.content", "disabled", 0.0);
get_state(PART:"check", st, 30, vl);
if (!strcmp(st, "visible"))
@ -232,11 +232,11 @@ group { name: "elm/check/base/default";
else
set_state(PART:"elm.text", "default", 0.0);
get_state(PART:"elm.swallow.icon", st, 30, vl);
get_state(PART:"elm.swallow.content", st, 30, vl);
if (!strcmp(st, "visible"))
set_state(PART:"elm.swallow.icon", "visible", 0.0);
set_state(PART:"elm.swallow.content", "visible", 0.0);
else
set_state(PART:"elm.swallow.icon", "default", 0.0);
set_state(PART:"elm.swallow.content", "default", 0.0);
get_state(PART:"check", st, 30, vl);
if (!strcmp(st, "visible"))
@ -470,7 +470,7 @@ group { name: "elm/check/base/toggle";
}
}
}
part { name: "elm.swallow.icon";
part { name: "elm.swallow.content";
type: SWALLOW;
description { state: "default" 0.0;
fixed: 1 0;
@ -503,7 +503,7 @@ group { name: "elm/check/base/toggle";
scale: 1;
description { state: "default" 0.0;
visible: 0;
rel1.to_x: "elm.swallow.icon";
rel1.to_x: "elm.swallow.content";
rel1.relative: 1.0 0.0;
rel1.offset: 0 4;
rel2.to_x: "bg";
@ -614,13 +614,13 @@ group { name: "elm/check/base/toggle";
signal: "elm,state,icon,visible";
source: "elm";
action: STATE_SET "visible" 0.0;
target: "elm.swallow.icon";
target: "elm.swallow.content";
}
program { name: "icon_hide";
signal: "elm,state,icon,hidden";
source: "elm";
action: STATE_SET "default" 0.0;
target: "elm.swallow.icon";
target: "elm.swallow.content";
}
program { name: "disable";
signal: "elm,state,disabled";
@ -643,11 +643,11 @@ group { name: "elm/check/base/toggle";
else
set_state(PART:"elm.text", "disabled", 0.0);
get_state(PART:"elm.swallow.icon", st, 30, vl);
get_state(PART:"elm.swallow.content", st, 30, vl);
if (!strcmp(st, "visible"))
set_state(PART:"elm.swallow.icon", "disabled_visible", 0.0);
set_state(PART:"elm.swallow.content", "disabled_visible", 0.0);
else
set_state(PART:"elm.swallow.icon", "disabled", 0.0);
set_state(PART:"elm.swallow.content", "disabled", 0.0);
}
}
program { name: "enable";
@ -669,11 +669,11 @@ group { name: "elm/check/base/toggle";
else
set_state(PART:"elm.text", "default", 0.0);
get_state(PART:"elm.swallow.icon", st, 30, vl);
get_state(PART:"elm.swallow.content", st, 30, vl);
if (!strcmp(st, "visible"))
set_state(PART:"elm.swallow.icon", "visible", 0.0);
set_state(PART:"elm.swallow.content", "visible", 0.0);
else
set_state(PART:"elm.swallow.icon", "default", 0.0);
set_state(PART:"elm.swallow.content", "default", 0.0);
}
}
program { name: "to_rtl";

View File

@ -86,7 +86,6 @@ group {
description { state: "default" 0.0;
max: 15 9999;
min: 15 100;
fixed: 1 1;
rel1.relative: 0.0 0.5;
rel2.relative: 1.0 0.5;
image {
@ -580,7 +579,6 @@ group {
description { state: "default" 0.0;
max: 999 15;
min: 100 15;
fixed: 1 1;
rel1.relative: 0.5 0.0;
rel2.relative: 0.5 1.0;
image {

View File

@ -1,6 +1,6 @@
group {
name: "elm/player/base/default";
min: 365 60;
min: 290 26;
parts {
part {
@ -8,7 +8,6 @@ group {
name: "media_player/slider";
description {
fixed: 1 1;
rel2 {
relative: 1.0 0.0;
to_x: "media_player/forward";
@ -20,7 +19,6 @@ group {
name: "media_player/rewind";
description {
fixed: 1 1;
rel1 {
to_y: "media_player/slider";
offset: 42 0;

View File

@ -40,7 +40,7 @@ group { name: "elm/progressbar/horizontal/default";
}
}
}
part { name: "elm.swallow.icon";
part { name: "elm.swallow.content";
type: SWALLOW;
description { state: "default" 0.0;
visible: 0;
@ -71,10 +71,10 @@ group { name: "elm/progressbar/horizontal/default";
visible: 0;
fixed: 1 1;
align: 0.0 0.5;
rel1.to_x: "elm.swallow.icon";
rel1.to_x: "elm.swallow.content";
rel1.relative: 1.0 0.0;
rel1.offset: -1 4;
rel2.to_x: "elm.swallow.icon";
rel2.to_x: "elm.swallow.content";
rel2.relative: 1.0 1.0;
rel2.offset: -1 -5;
color: 0 0 0 255;
@ -303,13 +303,13 @@ group { name: "elm/progressbar/horizontal/default";
signal: "elm,state,icon,visible";
source: "elm";
action: STATE_SET "visible" 0.0;
target: "elm.swallow.icon";
target: "elm.swallow.content";
}
program { name: "icon_hide";
signal: "elm,state,icon,hidden";
source: "elm";
action: STATE_SET "default" 0.0;
target: "elm.swallow.icon";
target: "elm.swallow.content";
}
program { name: "units_show";
signal: "elm,state,units,visible";
@ -427,7 +427,7 @@ group { name: "elm/progressbar/vertical/default";
}
}
}
part { name: "elm.swallow.icon";
part { name: "elm.swallow.content";
type: SWALLOW;
description { state: "default" 0.0;
visible: 0;
@ -458,10 +458,10 @@ group { name: "elm/progressbar/vertical/default";
visible: 0;
fixed: 1 1;
align: 0.5 0.0;
rel1.to_y: "elm.swallow.icon";
rel1.to_y: "elm.swallow.content";
rel1.relative: 0.5 1.0;
rel1.offset: 0 -1;
rel2.to_y: "elm.swallow.icon";
rel2.to_y: "elm.swallow.content";
rel2.relative: 0.5 1.0;
rel2.offset: -1 -1;
color: 0 0 0 255;
@ -673,13 +673,13 @@ group { name: "elm/progressbar/vertical/default";
signal: "elm,state,icon,visible";
source: "elm";
action: STATE_SET "visible" 0.0;
target: "elm.swallow.icon";
target: "elm.swallow.content";
}
program { name: "icon_hide";
signal: "elm,state,icon,hidden";
source: "elm";
action: STATE_SET "default" 0.0;
target: "elm.swallow.icon";
target: "elm.swallow.content";
}
program { name: "units_show";
signal: "elm,state,units,visible";
@ -787,7 +787,7 @@ group { name: "elm/progressbar/horizontal/wheel";
visible: 0;
}
}
part { name: "elm.swallow.icon";
part { name: "elm.swallow.content";
type: SWALLOW;
description { state: "default" 0.0;
min: 0 0;

View File

@ -34,7 +34,7 @@ group { name: "elm/radio/base/default";
visible: 1;
}
}
part { name: "elm.swallow.icon";
part { name: "elm.swallow.content";
type: SWALLOW;
description { state: "default" 0.0;
fixed: 1 0;
@ -71,7 +71,7 @@ group { name: "elm/radio/base/default";
scale: 1;
description { state: "default" 0.0;
visible: 0;
rel1.to_x: "elm.swallow.icon";
rel1.to_x: "elm.swallow.content";
rel1.relative: 1.0 0.0;
rel1.offset: 1 1;
rel2.relative: 1.0 1.0;
@ -155,13 +155,13 @@ group { name: "elm/radio/base/default";
signal: "elm,state,icon,visible";
source: "elm";
action: STATE_SET "visible" 0.0;
target: "elm.swallow.icon";
target: "elm.swallow.content";
}
program { name: "icon_hide";
signal: "elm,state,icon,hidden";
source: "elm";
action: STATE_SET "default" 0.0;
target: "elm.swallow.icon";
target: "elm.swallow.content";
}
program { name: "disable";
signal: "elm,state,disabled";
@ -180,11 +180,11 @@ group { name: "elm/radio/base/default";
else
set_state(PART:"elm.text", "disabled", 0.0);
get_state(PART:"elm.swallow.icon", st, 30, vl);
get_state(PART:"elm.swallow.content", st, 30, vl);
if (!strcmp(st, "visible"))
set_state(PART:"elm.swallow.icon", "disabled_visible", 0.0);
set_state(PART:"elm.swallow.content", "disabled_visible", 0.0);
else
set_state(PART:"elm.swallow.icon", "disabled", 0.0);
set_state(PART:"elm.swallow.content", "disabled", 0.0);
}
}
program { name: "enable";
@ -204,11 +204,11 @@ group { name: "elm/radio/base/default";
else
set_state(PART:"elm.text", "default", 0.0);
get_state(PART:"elm.swallow.icon", st, 30, vl);
get_state(PART:"elm.swallow.content", st, 30, vl);
if (!strcmp(st, "visible"))
set_state(PART:"elm.swallow.icon", "visible", 0.0);
set_state(PART:"elm.swallow.content", "visible", 0.0);
else
set_state(PART:"elm.swallow.icon", "default", 0.0);
set_state(PART:"elm.swallow.content", "default", 0.0);
}
}
}

View File

@ -244,9 +244,6 @@ test_bg_options(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_
/* color choices ... this is ghetto, but we don't have a 'colorpicker'
* widget yet :( */
rd = elm_spinner_add(win);
elm_object_tooltip_text_set(rd, "The background's part being affected<br/>"
"here may be seen only if you enlarge<br/>"
"the window and mark the 'Center' radio.");
elm_object_style_set(rd, "vertical");
elm_spinner_min_max_set(rd, 1, 4);
elm_spinner_label_format_set(rd, "%.0f");

View File

@ -189,7 +189,7 @@ _del_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
elm_box_unpack(data, obj);
evas_object_move(obj, 0, 0);
evas_object_color_set(obj, 128, 64, 0, 128);
evas_object_del(obj);
// evas_object_del(obj);
}
void

View File

@ -161,7 +161,7 @@ EAPI extern Elm_Version *elm_version;
/* other includes */
// Tom Hacohen
#include <elc_ctxpopup.h> // OK
#include <elm_dayselector.h> // OK
#include <elc_dayselector.h> // OK
#include <elc_fileselector_button.h> // OK
#include <elc_fileselector_entry.h> // OK
#include <elc_fileselector.h> // OK

View File

@ -41,14 +41,12 @@ Elementary_Cursor.h
includesdir = $(includedir)/elementary-@VMAJ@
includesunstable_HEADERS = \
elm_widget.h \
elm_widget_container.h \
elm_widget_layout.h
elm_widget.h
includesunstabledir = $(includedir)/elementary-@VMAJ@
includesub_HEADERS = \
elc_ctxpopup.h \
elm_dayselector.h \
elc_dayselector.h \
elc_fileselector_button.h \
elc_fileselector_entry.h \
elc_fileselector.h \
@ -139,7 +137,7 @@ includesubdir = $(includedir)/elementary-@VMAJ@/
libelementary_la_SOURCES = \
elm_priv.h \
elc_ctxpopup.c \
elm_dayselector.c \
elc_dayselector.c \
elc_popup.c \
elc_fileselector_button.c \
elc_fileselector.c \
@ -162,7 +160,6 @@ elm_cnp.c \
elm_colorselector.c \
elm_config.c \
elm_conform.c \
elm_container.c \
elm_datetime.c \
elm_diskselector.c \
elm_entry.c \

View File

@ -0,0 +1,669 @@
#include <Elementary.h>
#include "elm_priv.h"
typedef struct _Widget_Data Widget_Data;
typedef struct _Elm_Dayselector_Item Elm_Dayselector_Item;
/* signals to edc */
#define ITEM_TYPE_WEEKDAY_DEFAULT "elm,type,weekday,default"
#define ITEM_TYPE_WEEKDAY_STYLE1 "elm,type,weekday,style1"
#define ITEM_TYPE_WEEKEND_DEFAULT "elm,type,weekend,default"
#define ITEM_TYPE_WEEKEND_STYLE1 "elm,type,weekend,style1"
#define ITEM_POS_LEFT "elm,pos,check,left"
#define ITEM_POS_RIGHT "elm,pos,check,right"
#define ITEM_POS_MIDDLE "elm,pos,check,middle"
struct _Widget_Data
{
Evas_Object *base;
Eina_List *items;
Elm_Dayselector_Day week_start;
Elm_Dayselector_Day weekend_start;
unsigned int weekend_len;
};
struct _Elm_Dayselector_Item
{
ELM_WIDGET_ITEM;
Elm_Dayselector_Day day;
const char *day_style;
};
static const char *widtype = NULL;
static void _del_hook(Evas_Object *obj);
static void _sizing_eval(Evas_Object* obj);
static void _dayselector_resize(void *data, Evas *e __UNUSED__,
Evas_Object *obj __UNUSED__, void *event_info __UNUSED__);
static void _disable_hook(Evas_Object *obj);
static Eina_Bool _focus_next_hook(const Evas_Object *obj,
Elm_Focus_Direction dir __UNUSED__,
Evas_Object **next __UNUSED__);
static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
static void _translate_hook(Evas_Object *obj);
static void _theme_hook(Evas_Object *obj);
static void _item_text_set_hook(Evas_Object *obj, const char *item,
const char *label);
static const char *_item_text_get_hook(const Evas_Object *obj,
const char *item);
static void _content_set_hook(Evas_Object *obj, const char *item,
Evas_Object *content);
static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *item);
static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *item);
static void _signal_emit_cb(void *data, Evas_Object *obj, const char *emission,
const char *source __UNUSED__);
static void _item_clicked_cb(void *data, Evas_Object *obj,
void *event_info __UNUSED__);
static Elm_Dayselector_Item * _item_find(const Evas_Object *obj,
Elm_Dayselector_Day day);
static void _items_style_set(Evas_Object *obj);
static void _update_items(Evas_Object *obj);
static void _create_items(Evas_Object *obj);
static const char SIG_CHANGED[] = "dayselector,changed";
static const char SIG_LANG_CHANGED[] = "language,changed";
static const Evas_Smart_Cb_Description _signals[] = {
{SIG_CHANGED, ""},
{SIG_LANG_CHANGED, ""},
{NULL, NULL}
};
static void
_del_hook(Evas_Object *obj)
{
Elm_Dayselector_Item *it;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
EINA_LIST_FREE(wd->items, it)
{
wd->items = eina_list_remove(wd->items, it);
eina_stringshare_del(it->day_style);
elm_widget_item_free(it);
}
free(wd);
}
static void
_sizing_eval(Evas_Object* obj)
{
Evas_Coord min_w = -1, min_h = -1;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
elm_coords_finger_size_adjust(ELM_DAYSELECTOR_MAX, &min_w, 1, &min_h);
edje_object_size_min_restricted_calc(wd->base, &min_w, &min_h, min_w, min_h);
elm_coords_finger_size_adjust(ELM_DAYSELECTOR_MAX, &min_w, 1, &min_h);
evas_object_size_hint_min_set(obj, min_w, min_h);
}
static void
_dayselector_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
{
_sizing_eval(data);
}
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->base, "elm,state,disabled", "elm");
else
edje_object_signal_emit(wd->base, "elm,state,enabled", "elm");
}
static Eina_Bool
_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir __UNUSED__,
Evas_Object **next __UNUSED__)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
/* TODO: Focus switch support to Elm_widget_Item is not supported yet.*/
return EINA_FALSE;
}
static void
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
edje_object_mirrored_set(wd->base, rtl);
}
static void
_translate_hook(Evas_Object *obj)
{
Eina_List *l;
Elm_Dayselector_Item *it;
struct tm time_daysel;
time_t t;
char buf[1024];
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
t = time(NULL);
localtime_r(&t, &time_daysel);
EINA_LIST_FOREACH(wd->items, l, it)
{
time_daysel.tm_wday = it->day;
strftime(buf, sizeof(buf), "%a", &time_daysel);
elm_object_text_set(VIEW(it), buf);
}
evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL);
}
static void
_theme_hook(Evas_Object *obj)
{
Eina_List *l;
Elm_Dayselector_Item *it;
char buf[1024];
unsigned int loc;
Widget_Data* wd = elm_widget_data_get(obj);
if (!wd) return;
_elm_widget_mirrored_reload(obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_elm_theme_object_set(obj, wd->base, "dayselector", "base",
elm_widget_style_get(obj));
EINA_LIST_FOREACH(wd->items, l, it)
{
snprintf(buf, sizeof(buf), "dayselector/%s", elm_object_style_get(obj));
elm_object_style_set(VIEW(it), buf);
loc = (ELM_DAYSELECTOR_MAX - wd->week_start + it->day) % ELM_DAYSELECTOR_MAX;
snprintf(buf, sizeof(buf), "day%d,visible", loc);
edje_object_signal_emit(wd->base, buf, "elm");
snprintf(buf, sizeof(buf), "day%d", loc);
edje_object_part_swallow(wd->base, buf, VIEW(it));
}
_update_items(obj);
_sizing_eval(obj);
}
static void
_item_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj,
void *event_info __UNUSED__)
{
ELM_CHECK_WIDTYPE(data, widtype);
Eina_List *l;
Elm_Dayselector_Item *it;
char buf[1024];
unsigned int loc = 0;
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return;
EINA_LIST_FOREACH(wd->items, l, it)
{
if (obj == VIEW(it))
{
wd->items = eina_list_remove(wd->items, it);
eina_stringshare_del(it->day_style);
evas_object_smart_callback_del(VIEW(it), "changed", _item_clicked_cb);
evas_object_event_callback_del(VIEW(it), EVAS_CALLBACK_DEL, _item_del_cb);
edje_object_part_unswallow(wd->base, VIEW(it));
loc = (ELM_DAYSELECTOR_MAX - wd->week_start + it->day) % ELM_DAYSELECTOR_MAX;
snprintf(buf, sizeof(buf), "day%d,default", loc);
edje_object_signal_emit(wd->base, buf, "elm");
elm_widget_item_free(it);
_sizing_eval(obj);
break;
}
}
}
static void
_signal_emit_cb(void *data, Evas_Object *obj, const char *emission, const char *source __UNUSED__)
{
Eina_List *l;
Elm_Dayselector_Item *it;
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return;
EINA_LIST_FOREACH(wd->items, l, it)
{
if (obj == VIEW(it))
{
eina_stringshare_replace(&it->day_style, emission);
return ;
}
}
}
static void
_item_text_set_hook(Evas_Object *obj, const char *item, const char *label)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Eina_List *l;
Elm_Dayselector_Item *it;
char buf[1024];
Widget_Data *wd = elm_widget_data_get(obj);
if (item && !strcmp(item, "default")) return;
if (!wd) return;
EINA_LIST_FOREACH(wd->items, l, it)
{
snprintf(buf, sizeof(buf), "day%d", it->day);
if (!strncmp(buf, item, sizeof(buf)))
{
elm_object_text_set(VIEW(it), label);
_sizing_eval(obj);
break;
}
}
}
static const char *
_item_text_get_hook(const Evas_Object *obj, const char *item)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Eina_List *l;
Elm_Dayselector_Item *it;
char buf[1024];
Widget_Data *wd = elm_widget_data_get(obj);
if (item && !strcmp(item, "default")) return NULL;
if (!wd) return NULL;
EINA_LIST_FOREACH(wd->items, l, it)
{
snprintf(buf, sizeof(buf), "day%d", it->day);
if (!strncmp(buf, item, sizeof(buf)))
return elm_object_text_get(VIEW(it));
}
return NULL;
}
static void
_content_set_hook(Evas_Object *obj, const char *item, Evas_Object *content)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Eina_List *l;
Elm_Dayselector_Item *it;
char buf[1024];
unsigned int idx, loc;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd || !content) return;
if (item && !strcmp(item, "default")) return;
if (strcmp(elm_object_widget_type_get(content), "check")) return;
EINA_LIST_FOREACH(wd->items, l, it)
{
snprintf(buf, sizeof(buf), "day%d", it->day);
if (!strncmp(buf, item, sizeof(buf)))
{
if (VIEW(it)) evas_object_del(VIEW(it));
break;
}
}
for (idx = 0; idx < ELM_DAYSELECTOR_MAX; idx++)
{
snprintf(buf, sizeof(buf), "day%d", idx);
if (!strncmp(buf, item, sizeof(buf)))
{
it = elm_widget_item_new(obj, Elm_Dayselector_Item);
if (!it) continue;
VIEW(it) = content;
it->day = idx;
wd->items = eina_list_append(wd->items, it);
elm_widget_sub_object_add(obj, content);
loc = (ELM_DAYSELECTOR_MAX - wd->week_start + idx) % ELM_DAYSELECTOR_MAX;
snprintf(buf, sizeof(buf), "day%d", loc);
edje_object_part_swallow(wd->base, buf, VIEW(it));
snprintf(buf, sizeof(buf), "day%d,visible", loc);
edje_object_signal_emit(wd->base, buf, "elm");
evas_object_smart_callback_add(VIEW(it), "changed", _item_clicked_cb, obj);
evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_DEL, _item_del_cb, obj);
elm_object_signal_callback_add(VIEW(it), ITEM_TYPE_WEEKDAY_DEFAULT, "", _signal_emit_cb, obj);
elm_object_signal_callback_add(VIEW(it), ITEM_TYPE_WEEKDAY_STYLE1, "", _signal_emit_cb, obj);
elm_object_signal_callback_add(VIEW(it), ITEM_TYPE_WEEKEND_DEFAULT, "", _signal_emit_cb, obj);
elm_object_signal_callback_add(VIEW(it), ITEM_TYPE_WEEKEND_STYLE1, "", _signal_emit_cb, obj);
_sizing_eval(obj);
_update_items(obj);
break;
}
}
}
static Evas_Object *
_content_get_hook(const Evas_Object *obj, const char *item)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Eina_List *l;
Elm_Dayselector_Item *it;
char buf[1024];
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
if (item && !strcmp(item, "default")) return NULL;
EINA_LIST_FOREACH(wd->items, l, it)
{
snprintf(buf, sizeof(buf), "day%d", it->day);
if (!strncmp(buf, item, sizeof(buf))) return VIEW(it);
}
return NULL;
}
static Evas_Object *
_content_unset_hook(Evas_Object *obj, const char *item)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Eina_List *l;
Elm_Dayselector_Item *it;
Evas_Object *content;
char buf[1024];
unsigned int loc;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
if (item && !strcmp(item, "default")) return NULL;
EINA_LIST_FOREACH(wd->items, l, it)
{
snprintf(buf, sizeof(buf), "day%d", it->day);
if (!strncmp(buf, item, sizeof(buf)))
{
content = VIEW(it);
wd->items = eina_list_remove(wd->items, it);
elm_widget_sub_object_del(obj, VIEW(it));
evas_object_smart_callback_del(VIEW(it), "changed", _item_clicked_cb);
evas_object_event_callback_del(VIEW(it), EVAS_CALLBACK_DEL, _item_del_cb);
edje_object_part_unswallow(wd->base, VIEW(it));
loc = (ELM_DAYSELECTOR_MAX - wd->week_start + it->day) % ELM_DAYSELECTOR_MAX;
snprintf(buf, sizeof(buf), "day%d,default", loc);
edje_object_signal_emit(wd->base, buf, "elm");
_sizing_eval(obj);
return content;
}
}
return NULL;
}
static void
_item_clicked_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
{
Eina_List *l;
Elm_Dayselector_Item *it;
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return;
EINA_LIST_FOREACH(wd->items, l, it)
{
if (obj != VIEW(it)) continue;
evas_object_smart_callback_call(data, SIG_CHANGED, (void *)it->day);
return;
}
}
static Elm_Dayselector_Item *
_item_find(const Evas_Object *obj, Elm_Dayselector_Day day)
{
Eina_List *l;
Elm_Dayselector_Item *it;
Widget_Data* wd = elm_widget_data_get(obj);
if (!wd) return NULL;
EINA_LIST_FOREACH(wd->items, l, it)
if (day == it->day) return it;
return NULL;
}
static void
_items_style_set(Evas_Object *obj)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Eina_List *l;
Elm_Dayselector_Item *it;
unsigned int weekend_last;
Widget_Data* wd = elm_widget_data_get(obj);
if (!wd) return;
weekend_last = wd->weekend_start + wd->weekend_len - 1;
if (weekend_last >= ELM_DAYSELECTOR_MAX)
weekend_last = weekend_last % ELM_DAYSELECTOR_MAX;
EINA_LIST_FOREACH(wd->items, l, it)
{
if (weekend_last >= wd->weekend_start)
{
if ((it->day >= wd->weekend_start) && (it->day <= weekend_last))
eina_stringshare_replace(&it->day_style,
ITEM_TYPE_WEEKEND_DEFAULT);
else
eina_stringshare_replace(&it->day_style,
ITEM_TYPE_WEEKDAY_DEFAULT);
}
else
{
if ((it->day >= wd->weekend_start) || (it->day <= weekend_last))
eina_stringshare_replace(&it->day_style,
ITEM_TYPE_WEEKEND_DEFAULT);
else
eina_stringshare_replace(&it->day_style,
ITEM_TYPE_WEEKDAY_DEFAULT);
}
}
}
static void
_update_items(Evas_Object *obj)
{
Eina_List *l;
Elm_Dayselector_Item *it;
unsigned int last_day;
Eina_Bool rtl;
Widget_Data* wd = elm_widget_data_get(obj);
if (!wd) return;
last_day = wd->week_start + ELM_DAYSELECTOR_MAX - 1;
if (last_day >= ELM_DAYSELECTOR_MAX)
last_day = last_day % ELM_DAYSELECTOR_MAX;
rtl = elm_widget_mirrored_get(obj);
EINA_LIST_FOREACH(wd->items, l, it)
{
elm_object_signal_emit(VIEW(it), it->day_style, "");
if (it->day == wd->week_start)
{
if (rtl) elm_object_signal_emit(VIEW(it), ITEM_POS_RIGHT, "elm");
else elm_object_signal_emit(VIEW(it), ITEM_POS_LEFT, "elm");
}
else if (it->day == last_day)
{
if (rtl) elm_object_signal_emit(VIEW(it), ITEM_POS_LEFT, "elm");
else elm_object_signal_emit(VIEW(it), ITEM_POS_RIGHT, "elm");
}
else
elm_object_signal_emit(VIEW(it), ITEM_POS_MIDDLE, "elm");
}
}
static void
_create_items(Evas_Object *obj)
{
Elm_Dayselector_Item *it;
struct tm time_daysel;
time_t t;
char buf[1024];
unsigned int idx, loc;
Widget_Data* wd = elm_widget_data_get(obj);
if (!wd) return;
t = time(NULL);
localtime_r(&t, &time_daysel);
for (idx = 0; idx < ELM_DAYSELECTOR_MAX; idx++)
{
it = elm_widget_item_new(obj, Elm_Dayselector_Item);
if (!it) continue;
VIEW(it) = elm_check_add(wd->base);
elm_widget_sub_object_add(obj, VIEW(it));
wd->items = eina_list_append(wd->items, it);
elm_object_style_set(VIEW(it), "dayselector/default");
time_daysel.tm_wday = idx;
strftime(buf, sizeof(buf), "%a", &time_daysel);
elm_object_text_set(VIEW(it), buf);
it->day = idx;
loc = (ELM_DAYSELECTOR_MAX - wd->week_start + idx) % ELM_DAYSELECTOR_MAX;
snprintf(buf, sizeof(buf), "day%d", loc);
edje_object_part_swallow(wd->base, buf, VIEW(it));
snprintf(buf, sizeof(buf), "day%d,visible", idx);
edje_object_signal_emit(wd->base, buf, "elm");
evas_object_smart_callback_add(VIEW(it), "changed", _item_clicked_cb,
obj);
evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_DEL,
_item_del_cb, obj);
elm_object_signal_callback_add(VIEW(it), ITEM_TYPE_WEEKDAY_DEFAULT, "",
_signal_emit_cb, obj);
elm_object_signal_callback_add(VIEW(it), ITEM_TYPE_WEEKDAY_STYLE1, "",
_signal_emit_cb, obj);
elm_object_signal_callback_add(VIEW(it), ITEM_TYPE_WEEKEND_DEFAULT, "",
_signal_emit_cb, obj);
elm_object_signal_callback_add(VIEW(it), ITEM_TYPE_WEEKEND_STYLE1, "",
_signal_emit_cb, obj);
}
_items_style_set(obj);
_update_items(obj);
}
EAPI Evas_Object *
elm_dayselector_add(Evas_Object *parent)
{
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
ELM_SET_WIDTYPE(widtype, "dayselector");
elm_widget_type_set(obj, widtype);
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);
elm_widget_focus_next_hook_set(obj, _focus_next_hook);
elm_widget_translate_hook_set(obj, _translate_hook);
elm_widget_text_set_hook_set(obj, _item_text_set_hook);
elm_widget_text_get_hook_set(obj, _item_text_get_hook);
elm_widget_content_set_hook_set(obj, _content_set_hook);
elm_widget_content_get_hook_set(obj, _content_get_hook);
elm_widget_content_unset_hook_set(obj, _content_unset_hook);
wd->base = edje_object_add(e);
_elm_theme_object_set(obj, wd->base, "dayselector", "base", "default");
elm_object_style_set(wd->base, "dayselector");
elm_widget_resize_object_set(obj, wd->base);
wd->week_start = _elm_config->week_start;
wd->weekend_start = _elm_config->weekend_start;
wd->weekend_len = _elm_config->weekend_len;
printf("%d %d %d\n", wd->week_start, wd->weekend_start, wd->weekend_len);
_create_items(obj);
evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
_dayselector_resize, obj);
evas_object_smart_callbacks_descriptions_set(obj, _signals);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_sizing_eval(obj);
return obj;
}
EAPI void
elm_dayselector_day_selected_set(Evas_Object *obj, Elm_Dayselector_Day day, Eina_Bool selected)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data* wd = elm_widget_data_get(obj);
if (!wd) return;
elm_check_state_set(VIEW(_item_find(obj, day)), selected);
}
EAPI Eina_Bool
elm_dayselector_day_selected_get(const Evas_Object *obj, Elm_Dayselector_Day day)
{
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data* wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return elm_check_state_get(VIEW(_item_find(obj, day)));
}
EAPI void
elm_dayselector_week_start_set(Evas_Object *obj, Elm_Dayselector_Day day)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Eina_List *l;
Elm_Dayselector_Item *it;
char buf[1024];
unsigned int loc;
Widget_Data* wd = elm_widget_data_get(obj);
if (!wd) return;
wd->week_start = day;
EINA_LIST_FOREACH(wd->items, l, it)
{
loc = (ELM_DAYSELECTOR_MAX - wd->week_start + it->day) % ELM_DAYSELECTOR_MAX;
snprintf(buf, sizeof(buf), "day%d", loc);
edje_object_part_swallow(wd->base, buf, VIEW(it));
}
_update_items(obj);
}
EAPI Elm_Dayselector_Day
elm_dayselector_week_start_get(const Evas_Object *obj)
{
ELM_CHECK_WIDTYPE(obj, widtype) ELM_DAYSELECTOR_MAX;
Widget_Data* wd = elm_widget_data_get(obj);
if (!wd) return ELM_DAYSELECTOR_MAX;
return wd->week_start;
}
EAPI void
elm_dayselector_weekend_start_set(Evas_Object *obj, Elm_Dayselector_Day day)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data* wd = elm_widget_data_get(obj);
if (!wd) return;
wd->weekend_start = day;
_items_style_set(obj);
_update_items(obj);
}
EAPI Elm_Dayselector_Day
elm_dayselector_weekend_start_get(const Evas_Object *obj)
{
ELM_CHECK_WIDTYPE(obj, widtype) ELM_DAYSELECTOR_MAX;
Widget_Data* wd = elm_widget_data_get(obj);
if (!wd) return ELM_DAYSELECTOR_MAX;
return wd->weekend_start;
}
EAPI void
elm_dayselector_weekend_length_set(Evas_Object *obj, unsigned int length)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data* wd = elm_widget_data_get(obj);
if (!wd) return;
wd->weekend_len = length;
_items_style_set(obj);
_update_items(obj);
}
EAPI unsigned int
elm_dayselector_weekend_length_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->weekend_len;
}

View File

@ -51,13 +51,9 @@
* the elm_object_part_content_set/get APIs thus providing a way to handle
* the different check styles for individual days.
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for dayselector objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* @li @c "dayselector,changed" - when the user changes the state of a day.
* @li @c "language,changed" - the program's language changed
* The widget emits the following signals:
* @li "dayselector,changed" - when the user changes the state of a day.
* @li "language,changed" - the program's language changed
*
* Available styles for dayselector are:
* @li default

File diff suppressed because it is too large Load Diff

View File

@ -31,11 +31,8 @@
* library, the second form of view will display preview thumbnails
* of files which it supports.
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for file selector objects.
* Smart callbacks one can register to:
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* - @c "selected" - the user has clicked on a file (when not in
* folders-only mode) or directory (when in folders-only mode)
* - @c "directory,open" - the list has been populated with new

View File

@ -1,20 +1,13 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_button.h"
static const char FILESELECTOR_BUTTON_SMART_NAME[] = "elm_fileselector_button";
typedef struct _Widget_Data Widget_Data;
typedef struct _Elm_Fileselector_Button_Smart_Data \
Elm_Fileselector_Button_Smart_Data;
struct _Elm_Fileselector_Button_Smart_Data
struct _Widget_Data
{
Elm_Button_Smart_Data base;
Evas_Object *fs, *fsw;
const char *window_title;
Evas_Coord w, h;
Evas_Object *self, *btn, *fs, *fsw;
const char *window_title;
Evas_Coord w, h;
struct
{
const char *path;
@ -22,396 +15,507 @@ struct _Elm_Fileselector_Button_Smart_Data
Eina_Bool folder_only : 1;
Eina_Bool is_save : 1;
} fsd;
Eina_Bool inwin_mode : 1;
Eina_Bool inwin_mode : 1;
};
#define DEFAULT_WINDOW_TITLE "Select a file"
#define ELM_FILESELECTOR_BUTTON_DATA_GET(o, sd) \
Elm_Fileselector_Button_Smart_Data * sd = evas_object_smart_data_get(o)
static const char *widtype = NULL;
#define ELM_FILESELECTOR_BUTTON_DATA_GET_OR_RETURN(o, ptr) \
ELM_FILESELECTOR_BUTTON_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define ELM_FILESELECTOR_BUTTON_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_FILESELECTOR_BUTTON_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_FILESELECTOR_BUTTON_CHECK(obj) \
if (!obj || !elm_widget_type_check \
((obj), FILESELECTOR_BUTTON_SMART_NAME, __func__)) \
return
static void _del_pre_hook(Evas_Object *obj);
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 _button_clicked(void *data,
Evas_Object *obj,
void *event_info);
static void _on_focus_hook(void *data,
Evas_Object *obj);
static void _selection_done(void *data,
Evas_Object *obj,
void *event_info);
static void _activate(Widget_Data *wd);
static const char SIG_FILE_CHOSEN[] = "file,chosen";
static const Evas_Smart_Cb_Description _smart_callbacks[] = {
{SIG_FILE_CHOSEN, "s"},
{NULL, NULL}
static const Evas_Smart_Cb_Description _signals[] = {
{SIG_FILE_CHOSEN, "s"},
{NULL, NULL}
};
EVAS_SMART_SUBCLASS_NEW
(FILESELECTOR_BUTTON_SMART_NAME, _elm_fileselector_button,
Elm_Button_Smart_Class, Elm_Button_Smart_Class, elm_button_smart_class_get,
_smart_callbacks);
static Eina_Bool
_elm_fileselector_button_smart_theme(Evas_Object *obj)
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->btn, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_changed_size_hints, obj);
evas_object_smart_callback_del(wd->btn, "clicked", _button_clicked);
}
static void
_del_hook(Evas_Object *obj)
{
Evas_Object *win;
Widget_Data *wd;
wd = elm_widget_data_get(obj);
if (!wd) return;
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))
elm_widget_focus_steal(wd->btn);
}
static void
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
elm_widget_mirrored_set(wd->btn, rtl);
elm_widget_mirrored_set(wd->fs, rtl);
}
static void
_theme_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
char buf[4096];
const char *style;
if (!wd) return;
_elm_widget_mirrored_reload(obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd);
style = eina_stringshare_add(elm_widget_style_get(obj));
snprintf(buf, sizeof(buf), "fileselector_button/%s", style);
/* file selector button's style has an extra bit */
eina_stringshare_replace(&(ELM_WIDGET_DATA(sd)->style), buf);
if (!ELM_WIDGET_CLASS(_elm_fileselector_button_parent_sc)->theme(obj))
return EINA_FALSE;
eina_stringshare_replace(&(ELM_WIDGET_DATA(sd)->style), style);
eina_stringshare_del(style);
return EINA_TRUE;
snprintf(buf, sizeof(buf), "fileselector_button/%s",
elm_widget_style_get(obj));
elm_object_style_set(wd->btn, buf);
_sizing_eval(obj);
}
static void
_selection_done(void *data,
Evas_Object *obj __UNUSED__,
void *event_info)
_disable_hook(Evas_Object *obj)
{
Elm_Fileselector_Button_Smart_Data *sd = data;
const char *file = event_info;
Evas_Object *del;
if (file) eina_stringshare_replace(&sd->fsd.path, file);
del = sd->fsw;
sd->fs = NULL;
sd->fsw = NULL;
evas_object_del(del);
evas_object_smart_callback_call
(ELM_WIDGET_DATA(sd)->obj, SIG_FILE_CHOSEN, (void *)sd->fsd.path);
}
static Evas_Object *
_new_window_add(Elm_Fileselector_Button_Smart_Data *sd)
{
Evas_Object *win, *bg;
win = elm_win_add(NULL, "fileselector_button", ELM_WIN_DIALOG_BASIC);
elm_win_title_set(win, sd->window_title);
elm_win_autodel_set(win, EINA_TRUE);
evas_object_smart_callback_add(win, "delete,request", _selection_done, sd);
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, sd->w, sd->h);
return win;
}
static Evas_Object *
_parent_win_get(Evas_Object *obj)
{
while ((obj) && (strcmp(elm_widget_type_get(obj), "elm_win")))
obj = elm_object_parent_widget_get(obj);
return obj;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
elm_widget_disabled_set(wd->btn, elm_widget_disabled_get(obj));
}
static void
_activate(Elm_Fileselector_Button_Smart_Data *sd)
_sizing_eval(Evas_Object *obj)
{
Eina_Bool is_inwin = EINA_FALSE;
if (sd->fs) return;
if (sd->inwin_mode)
{
sd->fsw = _parent_win_get(ELM_WIDGET_DATA(sd)->obj);
if (!sd->fsw)
sd->fsw = _new_window_add(sd);
else
{
sd->fsw = elm_win_inwin_add(sd->fsw);
is_inwin = EINA_TRUE;
}
}
else
sd->fsw = _new_window_add(sd);
sd->fs = elm_fileselector_add(sd->fsw);
elm_widget_mirrored_set
(sd->fs, elm_widget_mirrored_get(ELM_WIDGET_DATA(sd)->obj));
elm_widget_mirrored_automatic_set(sd->fs, EINA_FALSE);
elm_fileselector_expandable_set(sd->fs, sd->fsd.expandable);
elm_fileselector_folder_only_set(sd->fs, sd->fsd.folder_only);
elm_fileselector_is_save_set(sd->fs, sd->fsd.is_save);
elm_fileselector_selected_set(sd->fs, sd->fsd.path);
evas_object_size_hint_weight_set
(sd->fs, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(sd->fs, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_smart_callback_add(sd->fs, "done", _selection_done, sd);
evas_object_show(sd->fs);
if (is_inwin)
{
elm_win_inwin_content_set(sd->fsw, sd->fs);
elm_win_inwin_activate(sd->fsw);
}
else
{
elm_win_resize_object_add(sd->fsw, sd->fs);
evas_object_show(sd->fsw);
}
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
_button_clicked(void *data,
_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
_activate_hook(Evas_Object *obj)
{
Widget_Data *wd;
wd = elm_widget_data_get(obj);
if (!wd) return;
_activate(wd);
}
static void
_button_clicked(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
{
_activate(data);
}
static void
_elm_fileselector_button_smart_add(Evas_Object *obj)
static Evas_Object *
_parent_win_get(Evas_Object *obj)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Fileselector_Button_Smart_Data);
while ((obj) && (strcmp(elm_widget_type_get(obj), "win")))
obj = elm_object_parent_widget_get(obj);
ELM_WIDGET_CLASS(_elm_fileselector_button_parent_sc)->base.add(obj);
return obj;
}
priv->window_title = eina_stringshare_add(DEFAULT_WINDOW_TITLE);
if (getenv("HOME")) priv->fsd.path = eina_stringshare_add(getenv("HOME"));
else priv->fsd.path = eina_stringshare_add("/");
static Evas_Object *
_new_window_add(Widget_Data *wd)
{
Evas_Object *win, *bg;
priv->fsd.expandable = _elm_config->fileselector_expand_enable;
priv->inwin_mode = _elm_config->inwin_dialogs_enable;
priv->w = 400;
priv->h = 400;
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);
evas_object_smart_callback_add(win, "delete,request", _selection_done, wd);
elm_widget_mirrored_automatic_set(obj, EINA_FALSE);
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_smart_callback_add(obj, "clicked", _button_clicked, priv);
_elm_fileselector_button_smart_theme(obj);
elm_widget_can_focus_set(obj, EINA_TRUE);
evas_object_resize(win, wd->w, wd->h);
return win;
}
static void
_elm_fileselector_button_smart_del(Evas_Object *obj)
_activate(Widget_Data *wd)
{
Evas_Object *win;
Eina_Bool is_inwin = EINA_FALSE;
ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd);
if (wd->fs) return;
if (sd->window_title) eina_stringshare_del(sd->window_title);
if (sd->fsd.path) eina_stringshare_del(sd->fsd.path);
if (sd->fs)
if (wd->inwin_mode)
{
win = evas_object_data_del(obj, "win");
evas_object_del(win);
}
wd->fsw = _parent_win_get(wd->self);
ELM_WIDGET_CLASS(_elm_fileselector_button_parent_sc)->base.del(obj);
if (!wd->fsw)
wd->fsw = _new_window_add(wd);
else
{
wd->fsw = elm_win_inwin_add(wd->fsw);
is_inwin = EINA_TRUE;
}
}
else
wd->fsw = _new_window_add(wd);
wd->fs = elm_fileselector_add(wd->fsw);
elm_widget_mirrored_set(wd->fs, elm_widget_mirrored_get(wd->self));
elm_widget_mirrored_automatic_set(wd->fs, EINA_FALSE);
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, wd);
evas_object_show(wd->fs);
if (is_inwin)
{
elm_win_inwin_content_set(wd->fsw, wd->fs);
elm_win_inwin_activate(wd->fsw);
}
else
{
elm_win_resize_object_add(wd->fsw, wd->fs);
evas_object_show(wd->fsw);
}
}
static void
_elm_fileselector_button_smart_set_user(Elm_Button_Smart_Class *sc)
_selection_done(void *data,
Evas_Object *obj __UNUSED__,
void *event_info)
{
ELM_WIDGET_CLASS(sc)->base.add = _elm_fileselector_button_smart_add;
ELM_WIDGET_CLASS(sc)->base.del = _elm_fileselector_button_smart_del;
const char *file = event_info;
Widget_Data *wd = data;
Evas_Object *del;
if (!wd) return;
ELM_WIDGET_CLASS(sc)->theme = _elm_fileselector_button_smart_theme;
if (file) eina_stringshare_replace(&wd->fsd.path, file);
sc->admits_autorepeat = EINA_FALSE;
del = wd->fsw;
wd->fs = NULL;
wd->fsw = NULL;
evas_object_del(del);
evas_object_smart_callback_call(wd->self, SIG_FILE_CHOSEN,
(void *)wd->fsd.path);
}
static void
_elm_fileselector_button_label_set(Evas_Object *obj, const char *item,
const char *label)
{
ELM_CHECK_WIDTYPE(obj, widtype);
if (item && strcmp(item, "default")) return;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
elm_object_text_set(wd->btn, label);
}
static const char *
_elm_fileselector_button_label_get(const Evas_Object *obj, const char *item)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (item && strcmp(item, "default")) return NULL;
if (!wd) return NULL;
return elm_object_text_get(wd->btn);
}
static void
_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
elm_object_part_content_set(wd->btn, part, content);
}
static Evas_Object *
_content_get_hook(const Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
return elm_object_part_content_get(wd->btn, part);
}
static Evas_Object *
_content_unset_hook(Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
return elm_object_part_content_unset(wd->btn, part);
}
EAPI Evas_Object *
elm_fileselector_button_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
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_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);
elm_widget_can_focus_set(obj, EINA_TRUE);
elm_widget_activate_hook_set(obj, _activate_hook);
elm_widget_text_set_hook_set(obj, _elm_fileselector_button_label_set);
elm_widget_text_get_hook_set(obj, _elm_fileselector_button_label_get);
elm_widget_content_set_hook_set(obj, _content_set_hook);
elm_widget_content_get_hook_set(obj, _content_get_hook);
elm_widget_content_unset_hook_set(obj, _content_unset_hook);
obj = evas_object_smart_add(e, _elm_fileselector_button_smart_class_new());
wd->self = obj;
wd->window_title = eina_stringshare_add(DEFAULT_WINDOW_TITLE);
if (getenv("HOME")) wd->fsd.path = eina_stringshare_add(getenv("HOME"));
else wd->fsd.path = eina_stringshare_add("/");
wd->fsd.expandable = _elm_config->fileselector_expand_enable;
wd->inwin_mode = _elm_config->inwin_dialogs_enable;
wd->w = 400;
wd->h = 400;
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
wd->btn = elm_button_add(parent);
elm_widget_mirrored_automatic_set(wd->btn, EINA_FALSE);
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, wd);
elm_widget_sub_object_add(obj, wd->btn);
_theme_hook(obj);
evas_object_smart_callbacks_descriptions_set(obj, _signals);
return obj;
}
EAPI void
elm_fileselector_button_window_title_set(Evas_Object *obj,
const char *title)
const char *title)
{
ELM_FILESELECTOR_BUTTON_CHECK(obj);
ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
eina_stringshare_replace(&sd->window_title, title);
if (!wd) return;
eina_stringshare_replace(&wd->window_title, title);
if (sd->fsw) elm_win_title_set(sd->fsw, sd->window_title);
if (wd->fsw)
elm_win_title_set(wd->fsw, wd->window_title);
}
EAPI const char *
elm_fileselector_button_window_title_get(const Evas_Object *obj)
{
ELM_FILESELECTOR_BUTTON_CHECK(obj) NULL;
ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
return sd->window_title;
if (!wd) return NULL;
return wd->window_title;
}
EAPI void
elm_fileselector_button_window_size_set(Evas_Object *obj,
Evas_Coord width,
Evas_Coord height)
Evas_Coord width,
Evas_Coord height)
{
ELM_FILESELECTOR_BUTTON_CHECK(obj);
ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
sd->w = width;
sd->h = height;
if (!wd) return;
wd->w = width;
wd->h = height;
if (sd->fsw) evas_object_resize(sd->fsw, sd->w, sd->h);
if (wd->fsw)
evas_object_resize(wd->fsw, wd->w, wd->h);
}
EAPI void
elm_fileselector_button_window_size_get(const Evas_Object *obj,
Evas_Coord *width,
Evas_Coord *height)
Evas_Coord *width,
Evas_Coord *height)
{
ELM_FILESELECTOR_BUTTON_CHECK(obj);
ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (width) *width = sd->w;
if (height) *height = sd->h;
if (!wd) return;
if (width) *width = wd->w;
if (height) *height = wd->h;
}
EAPI void
elm_fileselector_button_path_set(Evas_Object *obj,
const char *path)
const char *path)
{
ELM_FILESELECTOR_BUTTON_CHECK(obj);
ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
eina_stringshare_replace(&sd->fsd.path, path);
if (!wd) return;
eina_stringshare_replace(&wd->fsd.path, path);
if (sd->fs) elm_fileselector_selected_set(sd->fs, sd->fsd.path);
if (wd->fs)
elm_fileselector_selected_set(wd->fs, wd->fsd.path);
}
EAPI const char *
elm_fileselector_button_path_get(const Evas_Object *obj)
{
ELM_FILESELECTOR_BUTTON_CHECK(obj) NULL;
ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd);
return sd->fsd.path;
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
return wd->fsd.path;
}
EAPI void
elm_fileselector_button_expandable_set(Evas_Object *obj,
Eina_Bool value)
Eina_Bool value)
{
ELM_FILESELECTOR_BUTTON_CHECK(obj);
ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
sd->fsd.expandable = value;
if (!wd) return;
wd->fsd.expandable = value;
if (sd->fs) elm_fileselector_expandable_set(sd->fs, sd->fsd.expandable);
if (wd->fs)
elm_fileselector_expandable_set(wd->fs, wd->fsd.expandable);
}
EAPI Eina_Bool
elm_fileselector_button_expandable_get(const Evas_Object *obj)
{
ELM_FILESELECTOR_BUTTON_CHECK(obj) EINA_FALSE;
ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
return sd->fsd.expandable;
if (!wd) return EINA_FALSE;
return wd->fsd.expandable;
}
EAPI void
elm_fileselector_button_folder_only_set(Evas_Object *obj,
Eina_Bool value)
Eina_Bool value)
{
ELM_FILESELECTOR_BUTTON_CHECK(obj);
ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
sd->fsd.folder_only = value;
if (!wd) return;
wd->fsd.folder_only = value;
if (sd->fs) elm_fileselector_folder_only_set(sd->fs, sd->fsd.folder_only);
if (wd->fs)
elm_fileselector_folder_only_set(wd->fs, wd->fsd.folder_only);
}
EAPI Eina_Bool
elm_fileselector_button_folder_only_get(const Evas_Object *obj)
{
ELM_FILESELECTOR_BUTTON_CHECK(obj) EINA_FALSE;
ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
return sd->fsd.folder_only;
if (!wd) return EINA_FALSE;
return wd->fsd.folder_only;
}
EAPI void
elm_fileselector_button_is_save_set(Evas_Object *obj,
Eina_Bool value)
Eina_Bool value)
{
ELM_FILESELECTOR_BUTTON_CHECK(obj);
ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
sd->fsd.is_save = value;
if (!wd) return;
wd->fsd.is_save = value;
if (sd->fs) elm_fileselector_is_save_set(sd->fs, sd->fsd.is_save);
if (wd->fs)
elm_fileselector_is_save_set(wd->fs, wd->fsd.is_save);
}
EAPI Eina_Bool
elm_fileselector_button_is_save_get(const Evas_Object *obj)
{
ELM_FILESELECTOR_BUTTON_CHECK(obj) EINA_FALSE;
ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
return sd->fsd.is_save;
if (!wd) return EINA_FALSE;
return wd->fsd.is_save;
}
EAPI void
elm_fileselector_button_inwin_mode_set(Evas_Object *obj,
Eina_Bool value)
Eina_Bool value)
{
ELM_FILESELECTOR_BUTTON_CHECK(obj);
ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
sd->inwin_mode = value;
if (!wd) return;
wd->inwin_mode = value;
}
EAPI Eina_Bool
elm_fileselector_button_inwin_mode_get(const Evas_Object *obj)
{
ELM_FILESELECTOR_BUTTON_CHECK(obj) EINA_FALSE;
ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
return sd->inwin_mode;
if (!wd) return EINA_FALSE;
return wd->inwin_mode;
}

View File

@ -25,11 +25,7 @@
* @li @c "hoversel_vertical"
* @li @c "hoversel_vertical_entry"
*
* This widget inherits from the @ref Button one, so that all the
* functions acting on it also work for file selector button objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Button:
* Smart callbacks one can register to:
* - @c "file,chosen" - the user has selected a path, whose string
* pointer comes as the @c event_info data (a stringshared
* string)

View File

@ -1,195 +1,203 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_button.h"
static const char HOVERSEL_SMART_NAME[] = "elm_hoversel";
typedef struct _Widget_Data Widget_Data;
typedef struct _Elm_Hoversel_Item Elm_Hoversel_Item;
typedef struct _Elm_Hoversel_Smart_Data Elm_Hoversel_Smart_Data;
typedef struct _Elm_Hoversel_Item Elm_Hoversel_Item;
struct _Elm_Hoversel_Smart_Data
struct _Widget_Data
{
Elm_Button_Smart_Data base;
/* aggregates a hover */
Evas_Object *hover;
Evas_Object *hover_parent;
Eina_List *items;
Eina_Bool horizontal : 1;
Eina_Bool expanded : 1;
Evas_Object *btn, *hover;
Evas_Object *hover_parent;
Eina_List *items;
Eina_Bool horizontal : 1;
Eina_Bool expanded : 1;
};
struct _Elm_Hoversel_Item
{
ELM_WIDGET_ITEM;
const char *label;
const char *icon_file;
const char *icon_group;
const char *label;
const char *icon_file;
const char *icon_group;
Elm_Icon_Type icon_type;
Evas_Smart_Cb func;
};
#define ELM_HOVERSEL_DATA_GET(o, sd) \
Elm_Hoversel_Smart_Data * sd = evas_object_smart_data_get(o)
#define ELM_HOVERSEL_DATA_GET_OR_RETURN(o, ptr) \
ELM_HOVERSEL_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define ELM_HOVERSEL_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_HOVERSEL_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_HOVERSEL_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), HOVERSEL_SMART_NAME, __func__)) \
return
#define ELM_HOVERSEL_ITEM_CHECK(it) \
ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, ); \
ELM_HOVERSEL_CHECK(it->base.widget);
#define ELM_HOVERSEL_ITEM_CHECK_OR_RETURN(it, ...) \
ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
ELM_HOVERSEL_CHECK(it->base.widget) __VA_ARGS__;
static const char *widtype = NULL;
static void _del_pre_hook(Evas_Object *obj);
static void _del_hook(Evas_Object *obj);
static void _activate(Evas_Object *obj);
static void _activate_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 const char SIG_CLICKED[] = "clicked";
static const char SIG_SELECTED[] = "selected";
static const char SIG_DISMISSED[] = "dismissed";
static const Evas_Smart_Cb_Description _smart_callbacks[] = {
static const Evas_Smart_Cb_Description _signals[] = {
{SIG_CLICKED, ""},
{SIG_SELECTED, ""},
{SIG_DISMISSED, ""},
{NULL, NULL}
};
EVAS_SMART_SUBCLASS_NEW
(HOVERSEL_SMART_NAME, _elm_hoversel, Elm_Button_Smart_Class,
Elm_Button_Smart_Class, elm_button_smart_class_get, _smart_callbacks);
static Eina_Bool
_elm_hoversel_smart_theme(Evas_Object *obj)
static void
_del_pre_hook(Evas_Object *obj)
{
char buf[4096];
const char *style;
ELM_HOVERSEL_DATA_GET(obj, sd);
style = eina_stringshare_add(elm_widget_style_get(obj));
if (sd->horizontal)
snprintf(buf, sizeof(buf), "hoversel_horizontal/%s", style);
else
snprintf(buf, sizeof(buf), "hoversel_vertical/%s", style);
/* hoversel's style has an extra bit: orientation */
eina_stringshare_replace(&(ELM_WIDGET_DATA(sd)->style), buf);
if (!ELM_WIDGET_CLASS(_elm_hoversel_parent_sc)->theme(obj))
return EINA_FALSE;
eina_stringshare_replace(&(ELM_WIDGET_DATA(sd)->style), style);
eina_stringshare_del(style);
if (sd->hover)
elm_widget_mirrored_set(sd->hover, elm_widget_mirrored_get(obj));
Elm_Hoversel_Item *item;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_event_callback_del_full(wd->btn, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_changed_size_hints, obj);
elm_hoversel_hover_end(obj);
return EINA_TRUE;
elm_hoversel_hover_parent_set(obj, NULL);
EINA_LIST_FREE(wd->items, item)
{
eina_stringshare_del(item->label);
eina_stringshare_del(item->icon_file);
eina_stringshare_del(item->icon_group);
elm_widget_item_free(item);
}
}
static void
_on_hover_clicked(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_del_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
free(wd);
}
static void
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
elm_widget_mirrored_set(wd->btn, rtl);
elm_widget_mirrored_set(wd->hover, rtl);
}
static void
_theme_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
char buf[4096];
if (!wd) return;
_elm_widget_mirrored_reload(obj);
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);
elm_object_disabled_set(wd->btn, elm_widget_disabled_get(obj));
_mirrored_set(obj, elm_widget_mirrored_get(obj));
}
static void
_disable_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
elm_object_disabled_set(wd->btn, elm_widget_disabled_get(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_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
_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->btn);
}
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
_on_item_clicked(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_item_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
Elm_Hoversel_Item *item = data;
Evas_Object *obj2 = WIDGET(item);
elm_hoversel_hover_end(obj2);
if (item->func) item->func((void *)item->base.data, obj2, item);
evas_object_smart_callback_call(obj2, SIG_SELECTED, item);
elm_hoversel_hover_end(obj2);
}
static void
_activate(Evas_Object *obj)
{
const Elm_Hoversel_Item *item;
Widget_Data *wd = elm_widget_data_get(obj);
Evas_Object *bt, *bx, *ic;
const Eina_List *l;
const Elm_Hoversel_Item *item;
char buf[4096];
ELM_HOVERSEL_DATA_GET(obj, sd);
if (sd->expanded)
if (!wd) return;
if (wd->expanded)
{
elm_hoversel_hover_end(obj);
return;
}
sd->expanded = EINA_TRUE;
wd->expanded = EINA_TRUE;
if (elm_widget_disabled_get(obj)) return;
printf("creating hover!!\n");
sd->hover = elm_hover_add(sd->hover_parent);
elm_widget_mirrored_automatic_set(sd->hover, EINA_FALSE);
if (sd->horizontal)
snprintf(buf, sizeof(buf), "hoversel_horizontal/%s",
elm_widget_style_get(obj));
wd->hover = elm_hover_add(obj);
elm_widget_mirrored_automatic_set(wd->hover, EINA_FALSE);
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));
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);
elm_object_style_set(sd->hover, buf);
evas_object_smart_callback_add
(sd->hover, "clicked", _on_hover_clicked, obj);
elm_hover_target_set(sd->hover, obj);
/* hover's content */
bx = elm_box_add(sd->hover);
bx = elm_box_add(wd->hover);
elm_widget_mirrored_automatic_set(bx, EINA_FALSE);
elm_box_homogeneous_set(bx, EINA_TRUE);
elm_box_horizontal_set(bx, sd->horizontal);
elm_box_homogeneous_set(bx, 1);
if (sd->horizontal)
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 (sd->items, l, item)
EINA_LIST_FOREACH(wd->items, l, item)
{
bt = elm_button_add(bx);
bt = elm_button_add(wd->hover);
elm_widget_mirrored_automatic_set(bt, EINA_FALSE);
elm_widget_mirrored_set(bt, elm_widget_mirrored_get(obj));
elm_object_style_set(bt, buf);
elm_object_text_set(bt, item->label);
if (item->icon_file)
{
ic = elm_icon_add(obj);
@ -199,47 +207,103 @@ _activate(Evas_Object *obj)
else if (item->icon_type == ELM_ICON_STANDARD)
elm_icon_standard_set(ic, item->icon_file);
elm_object_part_content_set(bt, "icon", ic);
evas_object_show(ic);
}
evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(bx, bt);
evas_object_smart_callback_add(bt, "clicked", _on_item_clicked, item);
evas_object_smart_callback_add(bt, "clicked", _item_clicked, item);
evas_object_show(bt);
}
if (sd->horizontal)
elm_object_part_content_set(sd->hover, elm_hover_best_content_location_get
(sd->hover, ELM_HOVER_AXIS_HORIZONTAL), bx);
if (wd->horizontal)
elm_object_part_content_set(wd->hover,
elm_hover_best_content_location_get(wd->hover,
ELM_HOVER_AXIS_HORIZONTAL),
bx);
else
elm_object_part_content_set(sd->hover, elm_hover_best_content_location_get
(sd->hover, ELM_HOVER_AXIS_VERTICAL), bx);
elm_object_part_content_set(wd->hover,
elm_hover_best_content_location_get(wd->hover,
ELM_HOVER_AXIS_VERTICAL),
bx);
evas_object_show(bx);
evas_object_show(sd->hover);
evas_object_show(wd->hover);
evas_object_smart_callback_call(obj, SIG_CLICKED, NULL);
// if (wd->horizontal) evas_object_hide(wd->btn);
}
static void
_on_clicked(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_activate_hook(Evas_Object *obj)
{
_activate(obj);
}
static void
_button_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
_activate(data);
}
static void
_on_parent_del(void *data,
Evas *e __UNUSED__,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
ELM_HOVERSEL_DATA_GET(data, sd);
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return;
wd->hover_parent = NULL;
}
sd->hover_parent = NULL;
static void
_elm_hoversel_label_set(Evas_Object *obj, const char *item, const char *label)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (item && strcmp(item, "default")) return;
if (!wd) return;
elm_object_text_set(wd->btn, label);
}
static const char *
_item_text_get_hook(const Elm_Object_Item *it,
const char *part)
_elm_hoversel_label_get(const Evas_Object *obj, const char *item)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (item && strcmp(item, "default")) return NULL;
if ((!wd) || (!wd->btn)) return NULL;
return elm_object_text_get(wd->btn);
}
static void
_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
elm_object_part_content_set(wd->btn, part, content);
}
static Evas_Object *
_content_get_hook(const Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if ((!wd) || (!wd->btn)) return NULL;
return elm_object_part_content_get(wd->btn, part);
}
static Evas_Object *
_content_unset_hook(Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if ((!wd) || (!wd->btn)) return NULL;
return elm_object_part_content_unset(wd->btn, part);
}
static const char *
_item_text_get_hook(const Elm_Object_Item *it, const char *part)
{
if (part && strcmp(part, "default")) return NULL;
return ((Elm_Hoversel_Item *)it)->label;
@ -248,12 +312,12 @@ _item_text_get_hook(const Elm_Object_Item *it,
static Eina_Bool
_item_del_pre_hook(Elm_Object_Item *it)
{
Widget_Data *wd;
Elm_Hoversel_Item *item = (Elm_Hoversel_Item *)it;
ELM_HOVERSEL_DATA_GET_OR_RETURN_VAL(WIDGET(item), sd, EINA_FALSE);
wd = elm_widget_data_get(WIDGET(item));
if (!wd) return EINA_FALSE;
elm_hoversel_hover_end(WIDGET(item));
sd->items = eina_list_remove(sd->items, item);
wd->items = eina_list_remove(wd->items, item);
eina_stringshare_del(item->label);
eina_stringshare_del(item->icon_file);
eina_stringshare_del(item->icon_group);
@ -261,154 +325,121 @@ _item_del_pre_hook(Elm_Object_Item *it)
return EINA_TRUE;
}
static void
_elm_hoversel_smart_add(Evas_Object *obj)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Hoversel_Smart_Data);
ELM_WIDGET_CLASS(_elm_hoversel_parent_sc)->base.add(obj);
elm_widget_mirrored_automatic_set(obj, EINA_FALSE);
priv->expanded = EINA_FALSE;
evas_object_smart_callback_add(obj, "clicked", _on_clicked, obj);
_elm_hoversel_smart_theme(obj);
}
static void
_elm_hoversel_smart_del(Evas_Object *obj)
{
Elm_Hoversel_Item *item;
ELM_HOVERSEL_DATA_GET(obj, sd);
EINA_LIST_FREE (sd->items, item)
{
eina_stringshare_del(item->label);
eina_stringshare_del(item->icon_file);
eina_stringshare_del(item->icon_group);
elm_widget_item_free(item);
}
ELM_WIDGET_CLASS(_elm_hoversel_parent_sc)->base.del(obj);
}
static void
_elm_hoversel_smart_set_user(Elm_Button_Smart_Class *sc)
{
ELM_WIDGET_CLASS(sc)->base.add = _elm_hoversel_smart_add;
ELM_WIDGET_CLASS(sc)->base.del = _elm_hoversel_smart_del;
ELM_WIDGET_CLASS(sc)->theme = _elm_hoversel_smart_theme;
sc->admits_autorepeat = EINA_FALSE;
}
EAPI Evas_Object *
elm_hoversel_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
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);
elm_widget_activate_hook_set(obj, _activate_hook);
elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
elm_widget_can_focus_set(obj, EINA_TRUE);
elm_widget_text_set_hook_set(obj, _elm_hoversel_label_set);
elm_widget_text_get_hook_set(obj, _elm_hoversel_label_get);
elm_widget_content_set_hook_set(obj, _content_set_hook);
elm_widget_content_get_hook_set(obj, _content_get_hook);
elm_widget_content_unset_hook_set(obj, _content_unset_hook);
obj = evas_object_smart_add(e, _elm_hoversel_smart_class_new());
wd->btn = elm_button_add(parent);
elm_widget_mirrored_automatic_set(wd->btn, EINA_FALSE);
wd->expanded = EINA_FALSE;
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);
evas_object_smart_callbacks_descriptions_set(obj, _signals);
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
elm_widget_sub_object_add(obj, wd->btn);
elm_hoversel_hover_parent_set(obj, parent);
_theme_hook(obj);
return obj;
}
EAPI void
elm_hoversel_hover_parent_set(Evas_Object *obj,
Evas_Object *parent)
elm_hoversel_hover_parent_set(Evas_Object *obj, Evas_Object *parent)
{
ELM_HOVERSEL_CHECK(obj);
ELM_HOVERSEL_DATA_GET(obj, sd);
if (sd->hover_parent)
evas_object_event_callback_del_full
(sd->hover_parent, EVAS_CALLBACK_DEL, _on_parent_del, obj);
sd->hover_parent = parent;
if (sd->hover_parent)
evas_object_event_callback_add
(sd->hover_parent, EVAS_CALLBACK_DEL, _on_parent_del, obj);
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);
}
EAPI Evas_Object *
elm_hoversel_hover_parent_get(const Evas_Object *obj)
{
ELM_HOVERSEL_CHECK(obj) NULL;
ELM_HOVERSEL_DATA_GET(obj, sd);
return sd->hover_parent;
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
return wd->hover_parent;
}
EAPI void
elm_hoversel_horizontal_set(Evas_Object *obj,
Eina_Bool horizontal)
elm_hoversel_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
{
ELM_HOVERSEL_CHECK(obj);
ELM_HOVERSEL_DATA_GET(obj, sd);
sd->horizontal = !!horizontal;
_elm_hoversel_smart_theme(obj);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
wd->horizontal = !!horizontal;
}
EAPI Eina_Bool
elm_hoversel_horizontal_get(const Evas_Object *obj)
{
ELM_HOVERSEL_CHECK(obj) EINA_FALSE;
ELM_HOVERSEL_DATA_GET(obj, sd);
return sd->horizontal;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->horizontal;
}
EAPI void
elm_hoversel_hover_begin(Evas_Object *obj)
{
ELM_HOVERSEL_CHECK(obj);
ELM_HOVERSEL_DATA_GET(obj, sd);
if (sd->hover) return;
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->hover) return;
_activate(obj);
}
EAPI void
elm_hoversel_hover_end(Evas_Object *obj)
{
ELM_HOVERSEL_CHECK(obj);
ELM_HOVERSEL_DATA_GET(obj, sd);
if (!sd->hover) return;
sd->expanded = EINA_FALSE;
printf("deleting hover!!\n");
evas_object_del(sd->hover);
sd->hover = NULL;
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (!wd->hover) return;
wd->expanded = EINA_FALSE;
evas_object_del(wd->hover);
wd->hover = NULL;
evas_object_smart_callback_call(obj, SIG_DISMISSED, NULL);
}
EAPI Eina_Bool
elm_hoversel_expanded_get(const Evas_Object *obj)
{
ELM_HOVERSEL_CHECK(obj) EINA_FALSE;
ELM_HOVERSEL_DATA_GET(obj, sd);
return (sd->hover) ? EINA_TRUE : EINA_FALSE;
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;
}
EAPI void
@ -416,80 +447,61 @@ elm_hoversel_clear(Evas_Object *obj)
{
Elm_Object_Item *it;
Eina_List *l, *ll;
ELM_HOVERSEL_CHECK(obj);
ELM_HOVERSEL_DATA_GET(obj, sd);
EINA_LIST_FOREACH_SAFE (sd->items, l, ll, it)
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_widget_item_del(it);
_item_del_pre_hook(it);
elm_widget_item_free(it);
}
}
EAPI const Eina_List *
elm_hoversel_items_get(const Evas_Object *obj)
{
ELM_HOVERSEL_CHECK(obj) NULL;
ELM_HOVERSEL_DATA_GET(obj, sd);
return sd->items;
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
return wd->items;
}
EAPI Elm_Object_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_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_HOVERSEL_CHECK(obj) NULL;
ELM_HOVERSEL_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
Elm_Hoversel_Item *item = elm_widget_item_new(obj, Elm_Hoversel_Item);
if (!item) return NULL;
elm_widget_item_del_pre_hook_set(item, _item_del_pre_hook);
elm_widget_item_text_get_hook_set(item, _item_text_get_hook);
wd->items = eina_list_append(wd->items, item);
item->label = eina_stringshare_add(label);
item->icon_file = eina_stringshare_add(icon_file);
item->icon_type = icon_type;
item->func = func;
item->base.data = data;
sd->items = eina_list_append(sd->items, item);
return (Elm_Object_Item *)item;
}
EAPI void
elm_hoversel_item_icon_set(Elm_Object_Item *it,
const char *icon_file,
const char *icon_group,
Elm_Icon_Type icon_type)
elm_hoversel_item_icon_set(Elm_Object_Item *it, const char *icon_file, const char *icon_group, Elm_Icon_Type icon_type)
{
ELM_HOVERSEL_ITEM_CHECK_OR_RETURN(it);
ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
Elm_Hoversel_Item *item = (Elm_Hoversel_Item *)it;
eina_stringshare_replace(&item->icon_file, icon_file);
eina_stringshare_replace(&item->icon_group, icon_group);
item->icon_type = icon_type;
}
EAPI void
elm_hoversel_item_icon_get(const Elm_Object_Item *it,
const char **icon_file,
const char **icon_group,
Elm_Icon_Type *icon_type)
elm_hoversel_item_icon_get(const Elm_Object_Item *it, const char **icon_file, const char **icon_group, Elm_Icon_Type *icon_type)
{
ELM_HOVERSEL_ITEM_CHECK_OR_RETURN(it);
ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
Elm_Hoversel_Item *item = (Elm_Hoversel_Item *)it;
if (icon_file) *icon_file = item->icon_file;
if (icon_group) *icon_group = item->icon_group;
if (icon_type) *icon_type = item->icon_type;
}

View File

@ -12,16 +12,10 @@
* items in the hoversel menu (no more than 8), though is capable of many
* more.
*
* This widget inherits from the @ref Button one, so that all the
* functions acting on it also work for hoversel objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Button:
* - @c "clicked" - the user clicked the hoversel button and popped up
* the sel
* - @c "selected" - an item in the hoversel list is selected. event_info
* is the item
* - @c "dismissed" - the hover is dismissed
* 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
* "dismissed" - the hover is dismissed
*
* Default content parts of the hoversel widget that you can use for are:
* @li "icon" - An icon of the hoversel

View File

@ -1,57 +1,31 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_layout.h"
#ifdef HAVE_EMOTION
# include <Emotion.h>
#endif
static const char PLAYER_SMART_NAME[] = "elm_player";
typedef struct _Elm_Player_Smart_Data Elm_Player_Smart_Data;
struct _Elm_Player_Smart_Data
typedef struct _Widget_Data Widget_Data;
struct _Widget_Data
{
Elm_Layout_Smart_Data base;
Evas_Object *layout;
Evas_Object *video;
Evas_Object *emotion;
Evas_Object *video;
Evas_Object *emotion;
Evas_Object *forward;
Evas_Object *info;
Evas_Object *next;
Evas_Object *pause;
Evas_Object *play;
Evas_Object *prev;
Evas_Object *rewind;
Evas_Object *stop;
/* tracking those to ease disabling/enabling them back */
Evas_Object *forward;
Evas_Object *info;
Evas_Object *next;
Evas_Object *pause;
Evas_Object *play;
Evas_Object *prev;
Evas_Object *rewind;
Evas_Object *stop;
Evas_Object *slider;
Evas_Object *slider;
};
#define ELM_PLAYER_DATA_GET(o, sd) \
Elm_Player_Smart_Data * sd = evas_object_smart_data_get(o)
#define ELM_PLAYER_DATA_GET_OR_RETURN(o, ptr) \
ELM_PLAYER_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define ELM_PLAYER_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_PLAYER_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_PLAYER_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), PLAYER_SMART_NAME, __func__)) \
return
#ifdef HAVE_EMOTION
static const char *widtype = NULL;
static const char SIG_FORWARD_CLICKED[] = "forward,clicked";
static const char SIG_INFO_CLICKED[] = "info,clicked";
@ -61,52 +35,49 @@ static const char SIG_PLAY_CLICKED[] = "play,clicked";
static const char SIG_PREV_CLICKED[] = "prev,clicked";
static const char SIG_REWIND_CLICKED[] = "rewind,clicked";
static const char SIG_STOP_CLICKED[] = "stop,clicked";
static const Evas_Smart_Cb_Description _smart_callbacks[] = {
{ SIG_FORWARD_CLICKED, "" },
{ SIG_INFO_CLICKED, "" },
{ SIG_NEXT_CLICKED, "" },
{ SIG_PAUSE_CLICKED, "" },
{ SIG_PLAY_CLICKED, "" },
{ SIG_PREV_CLICKED, "" },
{ SIG_REWIND_CLICKED, "" },
{ SIG_STOP_CLICKED, "" },
{ NULL, NULL }
static const Evas_Smart_Cb_Description _signals[] = {
{ SIG_FORWARD_CLICKED, "" },
{ SIG_INFO_CLICKED, "" },
{ SIG_NEXT_CLICKED, "" },
{ SIG_PAUSE_CLICKED, "" },
{ SIG_PLAY_CLICKED, "" },
{ SIG_PREV_CLICKED, "" },
{ SIG_REWIND_CLICKED, "" },
{ SIG_STOP_CLICKED, "" },
{ NULL, NULL }
};
/* Inheriting from elm_layout. Besides, we need no more than what is
* there */
EVAS_SMART_SUBCLASS_NEW
(PLAYER_SMART_NAME, _elm_player, Elm_Layout_Smart_Class,
Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks);
static void _del_hook(Evas_Object *obj);
static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
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 Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src,
Evas_Callback_Type type, void *event_info);
#ifdef HAVE_EMOTION
static Eina_Bool
_elm_player_smart_event(Evas_Object *obj,
Evas_Object *src __UNUSED__,
Evas_Callback_Type type,
void *event_info)
_event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info)
{
Evas_Event_Key_Down *ev = event_info;
ELM_PLAYER_DATA_GET(obj, sd);
if (elm_widget_disabled_get(obj)) return EINA_FALSE;
if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
Evas_Event_Key_Down *ev = event_info;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
if (!sd->video) return EINA_FALSE;
if (elm_widget_disabled_get(obj)) return EINA_FALSE;
if (!wd->video) return EINA_FALSE;
if ((!strcmp(ev->keyname, "Left")) ||
((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
{
double current, last;
current = elm_video_play_position_get(sd->video);
last = elm_video_play_length_get(sd->video);
current = elm_video_play_position_get(wd->video);
last = elm_video_play_length_get(wd->video);
if (current < last)
{
current -= last / 100;
elm_video_play_position_set(sd->video, current);
current += last / 100;
elm_video_play_position_set(wd->video, current);
}
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
@ -117,14 +88,14 @@ _elm_player_smart_event(Evas_Object *obj,
{
double current, last;
current = elm_video_play_position_get(sd->video);
last = elm_video_play_length_get(sd->video);
current = elm_video_play_position_get(wd->video);
last = elm_video_play_length_get(wd->video);
if (current > 0)
{
current += last / 100;
current -= last / 100;
if (current < 0) current = 0;
elm_video_play_position_set(sd->video, current);
elm_video_play_position_set(wd->video, current);
}
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
@ -132,270 +103,329 @@ _elm_player_smart_event(Evas_Object *obj,
}
if (!strcmp(ev->keyname, "space"))
{
if (elm_video_is_playing_get(sd->video))
elm_video_pause(sd->video);
if (elm_video_is_playing_get(wd->video))
elm_video_pause(wd->video);
else
elm_video_play(sd->video);
elm_video_play(wd->video);
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
return EINA_TRUE;
}
fprintf(stderr, "keyname: '%s' not handle\n", ev->keyname);
return EINA_FALSE;
}
static Eina_Bool
_elm_player_smart_theme(Evas_Object *obj)
static void
_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
{
ELM_PLAYER_DATA_GET(obj, sd);
if (!ELM_WIDGET_CLASS(_elm_player_parent_sc)->theme(obj)) return EINA_FALSE;
#define UPDATE_THEME(Target, Name) \
if (Target) \
{ \
elm_object_style_set(Target, elm_widget_style_get(obj)); \
if (!elm_layout_content_set(obj, Name, Target)) \
evas_object_hide(Target); \
elm_object_disabled_set(Target, elm_widget_disabled_get(obj)); \
}
UPDATE_THEME(sd->forward, "media_player/forward");
UPDATE_THEME(sd->info, "media_player/info");
UPDATE_THEME(sd->next, "media_player/next");
UPDATE_THEME(sd->pause, "media_player/pause");
UPDATE_THEME(sd->play, "media_player/play");
UPDATE_THEME(sd->prev, "media_player/prev");
UPDATE_THEME(sd->rewind, "media_player/rewind");
UPDATE_THEME(sd->next, "media_player/next");
UPDATE_THEME(sd->slider, "media_player/slider");
elm_layout_sizing_eval(obj);
return EINA_TRUE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (elm_widget_focus_get(obj))
{
edje_object_signal_emit(wd->layout, "elm,action,focus", "elm");
evas_object_focus_set(wd->layout, EINA_TRUE);
}
else
{
edje_object_signal_emit(wd->layout, "elm,action,unfocus", "elm");
evas_object_focus_set(wd->layout, EINA_FALSE);
}
}
static void
_elm_player_smart_sizing_eval(Evas_Object *obj)
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
edje_object_mirrored_set(wd->layout, rtl);
}
static void
_theme_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
_elm_widget_mirrored_reload(obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_elm_theme_object_set(obj, wd->layout, "video", "base", elm_widget_style_get(obj));
edje_object_scale_set(wd->layout, elm_widget_scale_get(obj) *
_elm_config->scale);
#define UPDATE_THEME(Obj, Target, Layout, Name) \
if (Target) \
{ \
elm_object_style_set(Target, elm_widget_style_get(Obj)); \
if (!edje_object_part_swallow(Layout, Name, Target)) \
evas_object_hide(Target); \
elm_object_disabled_set(Target, elm_widget_disabled_get(Obj)); \
}
UPDATE_THEME(obj, wd->forward, wd->layout, "media_player/forward");
UPDATE_THEME(obj, wd->info, wd->layout, "media_player/info");
UPDATE_THEME(obj, wd->next, wd->layout, "media_player/next");
UPDATE_THEME(obj, wd->pause, wd->layout, "media_player/pause");
UPDATE_THEME(obj, wd->play, wd->layout, "media_player/play");
UPDATE_THEME(obj, wd->prev, wd->layout, "media_player/prev");
UPDATE_THEME(obj, wd->rewind, wd->layout, "media_player/rewind");
UPDATE_THEME(obj, wd->next, wd->layout, "media_player/next");
UPDATE_THEME(obj, wd->slider, wd->layout, "media_player/slider");
_sizing_eval(obj);
}
static void
_sizing_eval(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
Evas_Coord w, h;
ELM_PLAYER_DATA_GET(obj, sd);
edje_object_size_min_get(ELM_WIDGET_DATA(sd)->resize_obj, &w, &h);
edje_object_size_min_restricted_calc
(ELM_WIDGET_DATA(sd)->resize_obj, &w, &h, w, h);
if (!wd) return;
edje_object_size_min_get(wd->layout, &w, &h);
edje_object_size_min_restricted_calc(wd->layout, &w, &h, w, h);
evas_object_size_hint_min_set(obj, w, h);
}
static void
_update_slider(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_update_slider(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
Evas_Object *player = data;
Widget_Data *wd = elm_widget_data_get(player);
double pos, length;
Eina_Bool seekable;
ELM_PLAYER_DATA_GET(data, sd);
if (!wd) return ;
seekable = elm_video_is_seekable_get(wd->video);
length = elm_video_play_length_get(wd->video);
pos = elm_video_play_position_get(wd->video);
seekable = elm_video_is_seekable_get(sd->video);
length = elm_video_play_length_get(sd->video);
pos = elm_video_play_position_get(sd->video);
elm_object_disabled_set(sd->slider, !seekable);
elm_slider_min_max_set(sd->slider, 0, length);
elm_slider_value_set(sd->slider, pos);
elm_object_disabled_set(wd->slider, !seekable);
elm_slider_min_max_set(wd->slider, 0, length);
elm_slider_value_set(wd->slider, pos);
}
static void
_update_position(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_update_position(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
ELM_PLAYER_DATA_GET(data, sd);
Evas_Object *player = data;
Widget_Data *wd = elm_widget_data_get(player);
elm_video_play_position_set(sd->video, elm_slider_value_get(sd->slider));
if (!wd) return ;
elm_video_play_position_set(wd->video, elm_slider_value_get(wd->slider));
}
static void
_forward(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_forward(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
Evas_Object *player = data;
Widget_Data *wd = elm_widget_data_get(player);
double pos, length;
ELM_PLAYER_DATA_GET(data, sd);
if (!wd) return ;
pos = elm_video_play_position_get(sd->video);
length = elm_video_play_length_get(sd->video);
pos = elm_video_play_position_get(wd->video);
length = elm_video_play_length_get(wd->video);
pos += length * 0.3;
elm_video_play_position_set(sd->video, pos);
elm_video_play_position_set(wd->video, pos);
elm_layout_signal_emit(data, "elm,button,forward", "elm");
evas_object_smart_callback_call(data, SIG_FORWARD_CLICKED, NULL);
edje_object_signal_emit(wd->layout, "elm,button,forward", "elm");
evas_object_smart_callback_call(player, SIG_FORWARD_CLICKED, NULL);
}
static void
_info(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_info(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
elm_layout_signal_emit(data, "elm,button,info", "elm");
evas_object_smart_callback_call(data, SIG_INFO_CLICKED, NULL);
Evas_Object *player = data;
Widget_Data *wd = elm_widget_data_get(player);
if (!wd) return ;
edje_object_signal_emit(wd->layout, "elm,button,info", "elm");
evas_object_smart_callback_call(player, SIG_INFO_CLICKED, NULL);
}
static void
_next(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_next(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
Evas_Object *player = data;
Widget_Data *wd = elm_widget_data_get(player);
double pos, length;
ELM_PLAYER_DATA_GET(data, sd);
if (!wd) return ;
pos = elm_video_play_position_get(sd->video);
length = elm_video_play_length_get(sd->video);
pos = elm_video_play_position_get(wd->video);
length = elm_video_play_length_get(wd->video);
pos += length * 0.1;
elm_video_play_position_set(sd->video, pos);
elm_video_play_position_set(wd->video, pos);
elm_layout_signal_emit(data, "elm,button,next", "elm");
evas_object_smart_callback_call(data, SIG_NEXT_CLICKED, NULL);
edje_object_signal_emit(wd->layout, "elm,button,next", "elm");
evas_object_smart_callback_call(player, SIG_NEXT_CLICKED, NULL);
}
static void
_pause(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_pause(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
ELM_PLAYER_DATA_GET(data, sd);
Evas_Object *player = data;
Widget_Data *wd = elm_widget_data_get(player);
elm_layout_signal_emit(data, "elm,player,pause", "elm");
elm_video_pause(sd->video);
if (!wd) return ;
elm_layout_signal_emit(data, "elm,button,pause", "elm");
evas_object_smart_callback_call(data, SIG_PAUSE_CLICKED, NULL);
edje_object_signal_emit(wd->layout, "elm,player,pause", "elm");
elm_video_pause(wd->video);
edje_object_signal_emit(wd->layout, "elm,button,pause", "elm");
evas_object_smart_callback_call(player, SIG_PAUSE_CLICKED, NULL);
}
static void
_play(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_play(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
ELM_PLAYER_DATA_GET(data, sd);
Evas_Object *player = data;
Widget_Data *wd = elm_widget_data_get(player);
elm_video_play(sd->video);
elm_layout_signal_emit(data, "elm,button,play", "elm");
evas_object_smart_callback_call(data, SIG_PLAY_CLICKED, NULL);
if (!wd) return ;
elm_video_play(wd->video);
edje_object_signal_emit(wd->layout, "elm,button,play", "elm");
evas_object_smart_callback_call(player, SIG_PLAY_CLICKED, NULL);
}
static void
_prev(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_prev(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
Evas_Object *player = data;
Widget_Data *wd = elm_widget_data_get(player);
double pos, length;
ELM_PLAYER_DATA_GET(data, sd);
if (!wd) return ;
pos = elm_video_play_position_get(sd->video);
length = elm_video_play_length_get(sd->video);
pos = elm_video_play_position_get(wd->video);
length = elm_video_play_length_get(wd->video);
pos -= length * 0.1;
elm_video_play_position_set(sd->video, pos);
evas_object_smart_callback_call(data, SIG_PREV_CLICKED, NULL);
elm_layout_signal_emit(data, "elm,button,prev", "elm");
elm_video_play_position_set(wd->video, pos);
evas_object_smart_callback_call(player, SIG_PREV_CLICKED, NULL);
edje_object_signal_emit(wd->layout, "elm,button,prev", "elm");
}
static void
_rewind(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_rewind(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
ELM_PLAYER_DATA_GET(data, sd);
Evas_Object *player = data;
Widget_Data *wd = elm_widget_data_get(player);
elm_video_play_position_set(sd->video, 0);
elm_layout_signal_emit(data, "elm,button,rewind", "elm");
evas_object_smart_callback_call(data, SIG_REWIND_CLICKED, NULL);
if (!wd) return ;
elm_video_play_position_set(wd->video, 0);
edje_object_signal_emit(wd->layout, "elm,button,rewind", "elm");
evas_object_smart_callback_call(player, SIG_REWIND_CLICKED, NULL);
}
static void
_stop(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_stop(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
elm_layout_signal_emit(data, "elm,button,stop", "elm");
evas_object_smart_callback_call(data, SIG_STOP_CLICKED, NULL);
Evas_Object *player = data;
Widget_Data *wd = elm_widget_data_get(player);
if (!wd) return ;
edje_object_signal_emit(wd->layout, "elm,button,stop", "elm");
evas_object_smart_callback_call(player, SIG_STOP_CLICKED, NULL);
}
static void
_play_started(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_play_started(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
elm_layout_signal_emit(data, "elm,player,play", "elm");
Evas_Object *player = data;
Widget_Data *wd = elm_widget_data_get(player);
if (!wd) return ;
edje_object_signal_emit(wd->layout, "elm,player,play", "elm");
}
static void
_play_finished(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_play_finished(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
elm_layout_signal_emit(data, "elm,player,pause", "elm");
Evas_Object *player = data;
Widget_Data *wd = elm_widget_data_get(player);
if (!wd) return ;
edje_object_signal_emit(wd->layout, "elm,player,pause", "elm");
}
static void
_on_video_del(Elm_Player_Smart_Data *sd)
_cleanup_callback(Widget_Data *wd)
{
elm_object_disabled_set(sd->slider, EINA_TRUE);
elm_object_disabled_set(sd->forward, EINA_TRUE);
elm_object_disabled_set(sd->info, EINA_TRUE);
elm_object_disabled_set(sd->next, EINA_TRUE);
elm_object_disabled_set(sd->pause, EINA_TRUE);
elm_object_disabled_set(sd->play, EINA_TRUE);
elm_object_disabled_set(sd->prev, EINA_TRUE);
elm_object_disabled_set(sd->rewind, EINA_TRUE);
elm_object_disabled_set(sd->next, EINA_TRUE);
if (!wd || !wd->emotion) return;
sd->video = NULL;
sd->emotion = NULL;
evas_object_smart_callback_del(wd->emotion, "frame_decode",
_update_slider);
evas_object_smart_callback_del(wd->emotion, "frame_resize",
_update_slider);
evas_object_smart_callback_del(wd->emotion, "length_change",
_update_slider);
evas_object_smart_callback_del(wd->emotion, "position_update",
_update_slider);
evas_object_smart_callback_del(wd->emotion, "playback_started",
_play_started);
evas_object_smart_callback_del(wd->emotion, "playback_finished",
_play_finished);
elm_object_disabled_set(wd->slider, EINA_TRUE);
elm_object_disabled_set(wd->forward, EINA_TRUE);
elm_object_disabled_set(wd->info, EINA_TRUE);
elm_object_disabled_set(wd->next, EINA_TRUE);
elm_object_disabled_set(wd->pause, EINA_TRUE);
elm_object_disabled_set(wd->play, EINA_TRUE);
elm_object_disabled_set(wd->prev, EINA_TRUE);
elm_object_disabled_set(wd->rewind, EINA_TRUE);
elm_object_disabled_set(wd->next, EINA_TRUE);
wd->video = NULL;
wd->emotion = NULL;
}
static void
_video_del(void *data,
Evas *e __UNUSED__,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_track_video(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
_on_video_del(data);
_cleanup_callback(data);
}
static void
_del_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_smart_callback_del(wd->forward, "clicked", _forward);
evas_object_smart_callback_del(wd->info, "clicked", _info);
evas_object_smart_callback_del(wd->next, "clicked", _next);
evas_object_smart_callback_del(wd->pause, "clicked", _pause);
evas_object_smart_callback_del(wd->play, "clicked", _play);
evas_object_smart_callback_del(wd->prev, "clicked", _prev);
evas_object_smart_callback_del(wd->rewind, "clicked", _rewind);
evas_object_smart_callback_del(wd->next, "clicked", _next);
_cleanup_callback(wd);
free(wd);
}
static Evas_Object *
_player_button_add(Evas_Object *obj,
const char *name,
Evas_Smart_Cb func)
_player_button_add(Evas_Object *parent, Evas_Object *obj, Evas_Object *layout, const char *name, Evas_Smart_Cb func)
{
Evas_Object *ic;
Evas_Object *bt;
ic = elm_icon_add(obj);
ic = elm_icon_add(parent);
elm_icon_standard_set(ic, name);
evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
bt = elm_button_add(obj);
bt = elm_button_add(parent);
elm_widget_mirrored_automatic_set(bt, EINA_FALSE);
elm_object_part_content_set(bt, "icon", ic);
evas_object_size_hint_align_set(bt, 0.0, 0.0);
elm_object_style_set(bt, "anchor");
evas_object_smart_callback_add(bt, "clicked", func, obj);
elm_widget_sub_object_add(obj, bt);
if (!elm_layout_content_set(obj, name, bt))
{
elm_widget_sub_object_add(obj, bt);
evas_object_hide(bt);
}
if (!edje_object_part_swallow(layout, name, bt))
evas_object_hide(bt);
return bt;
}
@ -409,7 +439,6 @@ _double_to_time(double value)
pm = value / 60 - (ph * 60);
ps = value - (pm * 60);
pf = value * 100 - (ps * 100) - (pm * 60 * 100) - (ph * 60 * 60 * 100);
if (ph)
snprintf(buf, sizeof(buf), "%i:%02i:%02i.%02i",
ph, pm, ps, pf);
@ -424,156 +453,138 @@ _double_to_time(double value)
}
static void
_str_free(char *data)
_value_free(char *data)
{
eina_stringshare_del(data);
}
#endif
/* a video object is never parented by a player one, just tracked.
* treating this special case here and delegating other objects to own
* layout */
static Eina_Bool
_elm_player_smart_content_set(Evas_Object *obj,
const char *part,
Evas_Object *content)
#ifdef HAVE_EMOTION
static void
_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
{
if (part && strcmp(part, "video")) return;
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
double pos, length;
Eina_Bool seekable;
if (part && strcmp(part, "video"))
return ELM_CONTAINER_CLASS(_elm_player_parent_sc)->content_set
(obj, part, content);
if (!_elm_video_check(content)) return;
if (wd->video == content) return;
ELM_PLAYER_DATA_GET(obj, sd);
if (wd->video) evas_object_del(wd->video);
_cleanup_callback(wd);
if (!_elm_video_check(content)) return EINA_FALSE;
if (sd->video == content) return EINA_TRUE;
wd->video = content;
if (sd->video) evas_object_del(sd->video);
if (!wd->video)
{
wd->emotion = NULL;
return ;
}
sd->video = content;
elm_object_disabled_set(wd->slider, EINA_FALSE);
elm_object_disabled_set(wd->forward, EINA_FALSE);
elm_object_disabled_set(wd->info, EINA_FALSE);
elm_object_disabled_set(wd->next, EINA_FALSE);
elm_object_disabled_set(wd->pause, EINA_FALSE);
elm_object_disabled_set(wd->play, EINA_FALSE);
elm_object_disabled_set(wd->prev, EINA_FALSE);
elm_object_disabled_set(wd->rewind, EINA_FALSE);
elm_object_disabled_set(wd->next, EINA_FALSE);
if (!content) return EINA_TRUE;
wd->emotion = elm_video_emotion_get(wd->video);
emotion_object_priority_set(wd->emotion, EINA_TRUE);
evas_object_event_callback_add(wd->video, EVAS_CALLBACK_DEL,
_track_video, wd);
elm_object_disabled_set(sd->slider, EINA_FALSE);
elm_object_disabled_set(sd->forward, EINA_FALSE);
elm_object_disabled_set(sd->info, EINA_FALSE);
elm_object_disabled_set(sd->next, EINA_FALSE);
elm_object_disabled_set(sd->pause, EINA_FALSE);
elm_object_disabled_set(sd->play, EINA_FALSE);
elm_object_disabled_set(sd->prev, EINA_FALSE);
elm_object_disabled_set(sd->rewind, EINA_FALSE);
elm_object_disabled_set(sd->next, EINA_FALSE);
seekable = elm_video_is_seekable_get(wd->video);
length = elm_video_play_length_get(wd->video);
pos = elm_video_play_position_get(wd->video);
sd->emotion = elm_video_emotion_get(sd->video);
emotion_object_priority_set(sd->emotion, EINA_TRUE);
evas_object_event_callback_add
(sd->video, EVAS_CALLBACK_DEL, _video_del, sd);
elm_object_disabled_set(wd->slider, !seekable);
elm_slider_min_max_set(wd->slider, 0, length);
elm_slider_value_set(wd->slider, pos);
seekable = elm_video_is_seekable_get(sd->video);
length = elm_video_play_length_get(sd->video);
pos = elm_video_play_position_get(sd->video);
if (elm_video_is_playing_get(wd->video)) edje_object_signal_emit(wd->layout, "elm,player,play", "elm");
else edje_object_signal_emit(wd->layout, "elm,player,pause", "elm");
elm_object_disabled_set(sd->slider, !seekable);
elm_slider_min_max_set(sd->slider, 0, length);
elm_slider_value_set(sd->slider, pos);
if (elm_video_is_playing_get(sd->video))
elm_layout_signal_emit(obj, "elm,player,play", "elm");
else elm_layout_signal_emit(obj, "elm,player,pause", "elm");
evas_object_smart_callback_add(sd->emotion, "frame_decode",
evas_object_smart_callback_add(wd->emotion, "frame_decode",
_update_slider, obj);
evas_object_smart_callback_add(sd->emotion, "frame_resize",
evas_object_smart_callback_add(wd->emotion, "frame_resize",
_update_slider, obj);
evas_object_smart_callback_add(sd->emotion, "length_change",
evas_object_smart_callback_add(wd->emotion, "length_change",
_update_slider, obj);
evas_object_smart_callback_add(sd->emotion, "position_update",
evas_object_smart_callback_add(wd->emotion, "position_update",
_update_slider, obj);
evas_object_smart_callback_add(sd->emotion, "playback_started",
evas_object_smart_callback_add(wd->emotion, "playback_started",
_play_started, obj);
evas_object_smart_callback_add(sd->emotion, "playback_finished",
evas_object_smart_callback_add(wd->emotion, "playback_finished",
_play_finished, obj);
/* FIXME: track info from video */
return EINA_TRUE;
}
static void
_elm_player_smart_add(Evas_Object *obj)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Player_Smart_Data);
ELM_WIDGET_CLASS(_elm_player_parent_sc)->base.add(obj);
elm_layout_theme_set(obj, "player", "base", elm_widget_style_get(obj));
priv->forward = _player_button_add(obj, "media_player/forward", _forward);
priv->info = _player_button_add(obj, "media_player/info", _info);
priv->next = _player_button_add(obj, "media_player/next", _next);
priv->pause = _player_button_add(obj, "media_player/pause", _pause);
priv->play = _player_button_add(obj, "media_player/play", _play);
priv->prev = _player_button_add(obj, "media_player/prev", _prev);
priv->rewind = _player_button_add(obj, "media_player/rewind", _rewind);
priv->stop = _player_button_add(obj, "media_player/stop", _stop);
priv->slider = elm_slider_add(obj);
elm_slider_indicator_format_function_set
(priv->slider, _double_to_time, _str_free);
elm_slider_units_format_function_set
(priv->slider, _double_to_time, _str_free);
elm_slider_min_max_set(priv->slider, 0, 0);
elm_slider_value_set(priv->slider, 0);
elm_object_disabled_set(priv->slider, EINA_TRUE);
evas_object_size_hint_align_set(priv->slider, EVAS_HINT_FILL, 0.5);
evas_object_size_hint_weight_set
(priv->slider, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_layout_content_set(obj, "media_player/slider", priv->slider);
evas_object_smart_callback_add
(priv->slider, "changed", _update_position, obj);
elm_layout_sizing_eval(obj);
elm_widget_can_focus_set(obj, EINA_TRUE);
}
#endif
static void
_elm_player_smart_set_user(Elm_Layout_Smart_Class *sc)
{
#ifdef HAVE_EMOTION
ELM_WIDGET_CLASS(sc)->base.add = _elm_player_smart_add;
ELM_WIDGET_CLASS(sc)->event = _elm_player_smart_event;
ELM_WIDGET_CLASS(sc)->theme = _elm_player_smart_theme;
ELM_CONTAINER_CLASS(sc)->content_set = _elm_player_smart_content_set;
sc->sizing_eval = _elm_player_smart_sizing_eval;
#endif
}
EAPI Evas_Object *
elm_player_add(Evas_Object *parent)
{
#ifdef HAVE_EMOTION
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
ELM_SET_WIDTYPE(widtype, "player");
elm_widget_type_set(obj, "player");
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, EINA_TRUE);
elm_widget_event_hook_set(obj, _event_hook);
elm_widget_content_set_hook_set(obj, _content_set_hook);
/* TODO: add content_unset and content_get hook */
e = evas_object_evas_get(parent);
if (!e) return NULL;
wd->layout = edje_object_add(e);
_elm_theme_object_set(obj, wd->layout, "player", "base", "default");
elm_widget_resize_object_set(obj, wd->layout);
elm_widget_sub_object_add(obj, wd->layout);
evas_object_show(wd->layout);
evas_object_size_hint_weight_set(wd->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
obj = evas_object_smart_add(e, _elm_player_smart_class_new());
wd->forward = _player_button_add(parent, obj, wd->layout, "media_player/forward", _forward);
wd->info = _player_button_add(parent, obj, wd->layout, "media_player/info", _info);
wd->next = _player_button_add(parent, obj, wd->layout, "media_player/next", _next);
wd->pause = _player_button_add(parent, obj, wd->layout, "media_player/pause", _pause);
wd->play = _player_button_add(parent, obj, wd->layout, "media_player/play", _play);
wd->prev = _player_button_add(parent, obj, wd->layout, "media_player/prev", _prev);
wd->rewind = _player_button_add(parent, obj, wd->layout, "media_player/rewind", _rewind);
wd->stop = _player_button_add(parent, obj, wd->layout, "media_player/stop", _stop);
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
wd->slider = elm_slider_add(parent);
elm_widget_sub_object_add(obj, wd->slider);
elm_slider_indicator_format_function_set(wd->slider, _double_to_time, _value_free);
elm_slider_units_format_function_set(wd->slider, _double_to_time, _value_free);
elm_slider_min_max_set(wd->slider, 0, 0);
elm_slider_value_set(wd->slider, 0);
elm_object_disabled_set(wd->slider, EINA_TRUE);
evas_object_size_hint_align_set(wd->slider, EVAS_HINT_FILL, 0.5);
evas_object_size_hint_weight_set(wd->slider, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
edje_object_part_swallow(wd->layout, "media_player/slider", wd->slider);
evas_object_smart_callback_add(wd->slider, "changed", _update_position, obj);
wd->emotion = NULL;
wd->video = NULL;
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_sizing_eval(obj);
return obj;
#else
(void) parent;
return NULL;
#endif
}

View File

@ -1,512 +1,443 @@
#include <Elementary.h>
#include <math.h>
#include "elm_priv.h"
#include "elm_widget_layout.h"
static const char ACTIONSLIDER_SMART_NAME[] = "elm_actionslider";
typedef struct _Widget_Data Widget_Data;
typedef struct _Elm_Actionslider_Smart_Data Elm_Actionslider_Smart_Data;
struct _Elm_Actionslider_Smart_Data
struct _Widget_Data
{
Elm_Layout_Smart_Data base;
Evas_Object *drag_button_base;
Elm_Actionslider_Pos magnet_position, enabled_position;
Ecore_Animator *button_animator;
double final_position;
Eina_Bool mouse_down : 1;
Evas_Object *as; // actionslider
Evas_Object *drag_button_base;
Elm_Actionslider_Pos magnet_position, enabled_position;
const char *text_left, *text_right, *text_center;
const char *indicator_label;
Ecore_Animator *button_animator;
double final_position;
Eina_Bool mouse_down : 1;
};
static const Elm_Layout_Part_Alias_Description _text_aliases[] =
{
{"indicator", "elm.text.indicator"},
{"left", "elm.text.left"},
{"right", "elm.text.right"},
{"center", "elm.text.center"},
{NULL, NULL}
};
static const char *widtype = NULL;
static const char SIG_CHANGED[] = "pos_changed";
static const char SIG_SELECTED[] = "selected";
static const Evas_Smart_Cb_Description _smart_callbacks[] =
static const Evas_Smart_Cb_Description _signals[] =
{
{SIG_CHANGED, ""},
{SIG_SELECTED, ""},
{NULL, NULL}
{SIG_CHANGED, ""},
{SIG_SELECTED, ""},
{NULL, NULL}
};
#define ELM_ACTIONSLIDER_DATA_GET(o, sd) \
Elm_Actionslider_Smart_Data * sd = evas_object_smart_data_get(o)
#define ELM_ACTIONSLIDER_DATA_GET_OR_RETURN(o, ptr) \
ELM_ACTIONSLIDER_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define ELM_ACTIONSLIDER_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_ACTIONSLIDER_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_ACTIONSLIDER_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), ACTIONSLIDER_SMART_NAME, \
__func__)) \
return
/* Inheriting from elm_layout. Besides, we need no more than what is
* there */
EVAS_SMART_SUBCLASS_NEW
(ACTIONSLIDER_SMART_NAME, _elm_actionslider, Elm_Layout_Smart_Class,
Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks);
static void
_del_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->drag_button_base)
{
evas_object_del(wd->drag_button_base);
wd->drag_button_base = NULL;
}
if (wd->text_left) eina_stringshare_del(wd->text_left);
if (wd->text_right) eina_stringshare_del(wd->text_right);
if (wd->text_center) eina_stringshare_del(wd->text_center);
if (wd->indicator_label) eina_stringshare_del(wd->indicator_label);
free(wd);
}
static Elm_Actionslider_Pos
_get_pos_by_orientation(const Evas_Object *obj,
Elm_Actionslider_Pos pos)
_get_pos_by_orientation(const Evas_Object *obj, Elm_Actionslider_Pos pos)
{
if (elm_widget_mirrored_get(obj))
{
switch (pos)
{
case ELM_ACTIONSLIDER_LEFT:
pos = ELM_ACTIONSLIDER_RIGHT;
break;
pos = ELM_ACTIONSLIDER_RIGHT;
break;
case ELM_ACTIONSLIDER_RIGHT:
pos = ELM_ACTIONSLIDER_LEFT;
break;
pos = ELM_ACTIONSLIDER_LEFT;
break;
default:
break;
break;
}
}
return pos;
}
static void
_elm_actionslider_smart_sizing_eval(Evas_Object *obj)
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
Widget_Data *wd = elm_widget_data_get(obj);
double pos;
if (!wd) return;
if (edje_object_mirrored_get(wd->as) == rtl)
return;
edje_object_mirrored_set(wd->as, rtl);
if (!elm_widget_mirrored_get(obj))
{
edje_object_part_text_escaped_set(wd->as, "elm.text.left", wd->text_left);
edje_object_part_text_escaped_set(wd->as, "elm.text.right", wd->text_right);
}
else
{
edje_object_part_text_escaped_set(wd->as, "elm.text.left", wd->text_right);
edje_object_part_text_escaped_set(wd->as, "elm.text.right", wd->text_left);
}
edje_object_part_drag_value_get(wd->as, "elm.drag_button_base", &pos, NULL);
edje_object_part_drag_value_set(wd->as, "elm.drag_button_base", 1.0 - pos, 0.5);
}
static void
_sizing_eval(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
Evas_Coord minw = -1, minh = -1;
ELM_ACTIONSLIDER_DATA_GET(obj, sd);
if (!wd) return;
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
evas_object_size_hint_min_set(sd->drag_button_base, minw, minh);
evas_object_size_hint_max_set(sd->drag_button_base, -1, -1);
evas_object_size_hint_min_set(wd->drag_button_base, minw, minh);
evas_object_size_hint_max_set(wd->drag_button_base, -1, -1);
minw = -1;
minh = -1;
elm_coords_finger_size_adjust(3, &minw, 1, &minh);
edje_object_size_min_restricted_calc
(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh);
edje_object_size_min_restricted_calc(wd->as, &minw, &minh, minw, minh);
evas_object_size_hint_min_set(obj, minw, minh);
evas_object_size_hint_max_set(obj, -1, -1);
}
static void
_mirroredness_change_eval(Evas_Object *obj)
_theme_hook(Evas_Object *obj)
{
double pos;
char *left;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
_elm_widget_mirrored_reload(obj);
if (!edje_object_part_swallow_get(wd->as, "elm.drag_button_base"))
edje_object_part_unswallow(wd->as, wd->drag_button_base);
ELM_ACTIONSLIDER_DATA_GET(obj, sd);
_elm_theme_object_set(obj, wd->as, "actionslider",
"base", elm_widget_style_get(obj));
_elm_theme_object_set(obj, wd->drag_button_base, "actionslider",
"drag_button", elm_widget_style_get(obj));
edje_object_part_swallow(wd->as, "elm.drag_button_base", wd->drag_button_base);
left = (char *)elm_layout_text_get(obj, "elm.text.left");
if (left) left = strdup(left);
elm_layout_text_set
(obj, "elm.text.left", elm_layout_text_get(obj, "elm.text.right"));
elm_layout_text_set(obj, "elm.text.right", left);
free(left);
edje_object_part_drag_value_get
(ELM_WIDGET_DATA(sd)->resize_obj, "elm.drag_button_base", &pos, NULL);
edje_object_part_drag_value_set
(ELM_WIDGET_DATA(sd)->resize_obj, "elm.drag_button_base", 1.0 - pos, 0.5);
}
static Eina_Bool
_elm_actionslider_smart_theme(Evas_Object *obj)
{
Eina_Bool mirrored;
ELM_ACTIONSLIDER_DATA_GET(obj, sd);
mirrored = elm_object_mirrored_get(obj);
if (!ELM_WIDGET_CLASS(_elm_actionslider_parent_sc)->theme(obj))
return EINA_FALSE;
if (elm_object_mirrored_get(obj) != mirrored)
_mirroredness_change_eval(obj);
edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
return EINA_TRUE;
_mirrored_set(obj, elm_widget_mirrored_get(obj));
edje_object_part_text_escaped_set(wd->as, "elm.text.center", wd->text_center);
edje_object_part_text_escaped_set(wd->as, "elm.text.indicator", wd->indicator_label);
edje_object_message_signal_process(wd->as);
_sizing_eval(obj);
}
static void
_drag_button_down_cb(void *data,
Evas_Object *o __UNUSED__,
const char *emission __UNUSED__,
const char *source __UNUSED__)
_drag_button_down_cb(void *data, Evas_Object *o __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
Elm_Actionslider_Smart_Data *sd = data;
sd->mouse_down = EINA_TRUE;
Widget_Data *wd = elm_widget_data_get((Evas_Object *) data);
if (!wd) return;
wd->mouse_down = EINA_TRUE;
}
static void
_drag_button_move_cb(void *data,
Evas_Object *o __UNUSED__,
const char *emission __UNUSED__,
const char *source __UNUSED__)
_drag_button_move_cb(void *data, Evas_Object *o __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
Evas_Object *obj = data;
Evas_Object *obj = (Evas_Object *) data;
Widget_Data *wd = elm_widget_data_get(obj);
double pos = 0.0;
if (!wd) return;
ELM_ACTIONSLIDER_DATA_GET(obj, sd);
if (!sd->mouse_down) return;
edje_object_part_drag_value_get
(ELM_WIDGET_DATA(sd)->resize_obj, "elm.drag_button_base", &pos, NULL);
if (!wd->mouse_down) return;
edje_object_part_drag_value_get(wd->as, "elm.drag_button_base", &pos, NULL);
if (pos == 0.0)
evas_object_smart_callback_call
(obj, SIG_CHANGED, !elm_widget_mirrored_get(obj) ? "left" : "right");
evas_object_smart_callback_call(obj, SIG_CHANGED,
(void *) ((!elm_widget_mirrored_get(obj)) ?
"left" : "right"));
else if (pos == 1.0)
evas_object_smart_callback_call
(obj, SIG_CHANGED, !elm_widget_mirrored_get(obj) ? "right" : "left");
evas_object_smart_callback_call(obj, SIG_CHANGED,
(void *) ((!elm_widget_mirrored_get(obj)) ?
"right" : "left"));
else if (pos >= 0.45 && pos <= 0.55)
evas_object_smart_callback_call(obj, SIG_CHANGED, "center");
}
static void
_text_get(const Evas_Object *obj,
const char **left,
const char **right,
const char **center)
{
/* mirroredness already evaluated by the two calls below */
*left = elm_layout_text_get(obj, "left");
*right = elm_layout_text_get(obj, "right");
*center = elm_layout_text_get(obj, "center");
evas_object_smart_callback_call(obj, SIG_CHANGED, (void *)"center");
}
static Eina_Bool
_button_animator(void *data)
_button_animation(void *data)
{
Evas_Object *obj = data;
Widget_Data *wd = elm_widget_data_get(obj);
double cur_position = 0.0, new_position = 0.0;
double move_amount = 0.05;
Eina_Bool flag_finish_animation = EINA_FALSE;
double cur_position = 0.0, new_position = 0.0;
if (!wd) return ECORE_CALLBACK_CANCEL;
ELM_ACTIONSLIDER_DATA_GET(obj, sd);
edje_object_part_drag_value_get
(ELM_WIDGET_DATA(sd)->resize_obj, "elm.drag_button_base",
&cur_position, NULL);
{
double adjusted_final;
adjusted_final = (!elm_widget_mirrored_get(obj)) ?
sd->final_position : 1.0 - sd->final_position;
if ((adjusted_final == 0.0) ||
(adjusted_final == 0.5 && cur_position >= adjusted_final))
{
new_position = cur_position - move_amount;
if (new_position <= adjusted_final)
{
new_position = adjusted_final;
flag_finish_animation = EINA_TRUE;
}
}
else if ((adjusted_final == 1.0) ||
(adjusted_final == 0.5 && cur_position < adjusted_final))
{
new_position = cur_position + move_amount;
if (new_position >= adjusted_final)
{
new_position = adjusted_final;
flag_finish_animation = EINA_TRUE;
}
}
edje_object_part_drag_value_set
(ELM_WIDGET_DATA(sd)->resize_obj, "elm.drag_button_base",
new_position, 0.5);
}
edje_object_part_drag_value_get(wd->as,
"elm.drag_button_base", &cur_position, NULL);
{
double adjusted_final;
adjusted_final = (!elm_widget_mirrored_get(obj)) ?
wd->final_position : 1.0 - wd->final_position;
if ((adjusted_final == 0.0) ||
(adjusted_final == 0.5 && cur_position >= adjusted_final))
{
new_position = cur_position - move_amount;
if (new_position <= adjusted_final)
{
new_position = adjusted_final;
flag_finish_animation = EINA_TRUE;
}
}
else if ((adjusted_final == 1.0) ||
(adjusted_final == 0.5 && cur_position < adjusted_final))
{
new_position = cur_position + move_amount;
if (new_position >= adjusted_final)
{
new_position = adjusted_final;
flag_finish_animation = EINA_TRUE;
}
}
edje_object_part_drag_value_set(wd->as,
"elm.drag_button_base", new_position, 0.5);
}
if (flag_finish_animation)
{
const char *left, *right, *center;
_text_get(obj, &left, &right, &center);
if ((!sd->final_position) &&
(sd->enabled_position & ELM_ACTIONSLIDER_LEFT))
evas_object_smart_callback_call(obj, SIG_SELECTED, (char *)left);
else if ((sd->final_position == 0.5) &&
(sd->enabled_position & ELM_ACTIONSLIDER_CENTER))
evas_object_smart_callback_call(obj, SIG_SELECTED, (char *)center);
else if ((sd->final_position == 1) &&
(sd->enabled_position & ELM_ACTIONSLIDER_RIGHT))
evas_object_smart_callback_call(obj, SIG_SELECTED, (char *)right);
sd->button_animator = NULL;
if ((!wd->final_position) &&
(wd->enabled_position & ELM_ACTIONSLIDER_LEFT))
evas_object_smart_callback_call(data, SIG_SELECTED,
(void *)wd->text_left);
else if ((wd->final_position == 0.5) &&
(wd->enabled_position & ELM_ACTIONSLIDER_CENTER))
evas_object_smart_callback_call(data, SIG_SELECTED,
(void *)wd->text_center);
else if ((wd->final_position == 1) &&
(wd->enabled_position & ELM_ACTIONSLIDER_RIGHT))
evas_object_smart_callback_call(data, SIG_SELECTED,
(void *)wd->text_right);
wd->button_animator = NULL;
return ECORE_CALLBACK_CANCEL;
}
return ECORE_CALLBACK_RENEW;
}
static void
_drag_button_up_cb(void *data,
Evas_Object *o __UNUSED__,
const char *emission __UNUSED__,
const char *source __UNUSED__)
_drag_button_up_cb(void *data, Evas_Object *o __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
Evas_Object *obj = data;
Evas_Object *obj = (Evas_Object *) data;
Widget_Data *wd = elm_widget_data_get(obj);
double position = 0.0;
if (!wd) return;
ELM_ACTIONSLIDER_DATA_GET(obj, sd);
wd->mouse_down = EINA_FALSE;
sd->mouse_down = EINA_FALSE;
edje_object_part_drag_value_get(wd->as, "elm.drag_button_base",
&position, NULL);
edje_object_part_drag_value_get
(ELM_WIDGET_DATA(sd)->resize_obj, "elm.drag_button_base", &position,
NULL);
const char *left, *right, *center;
_text_get(obj, &left, &right, &center);
if ((sd->enabled_position & ELM_ACTIONSLIDER_LEFT) &&
if ((wd->enabled_position & ELM_ACTIONSLIDER_LEFT) &&
((!elm_widget_mirrored_get(obj) && position == 0.0) ||
(elm_widget_mirrored_get(obj) && position == 1.0)))
{
sd->final_position = 0;
evas_object_smart_callback_call(obj, SIG_SELECTED, (char *)left);
wd->final_position = 0;
evas_object_smart_callback_call(data, SIG_SELECTED,
(void *) wd->text_left);
return;
}
if (position >= 0.45 && position <= 0.55 &&
(sd->enabled_position & ELM_ACTIONSLIDER_CENTER))
(wd->enabled_position & ELM_ACTIONSLIDER_CENTER))
{
sd->final_position = 0.5;
evas_object_smart_callback_call(obj, SIG_SELECTED, (char *)center);
if (sd->button_animator) ecore_animator_del(sd->button_animator);
sd->button_animator = ecore_animator_add(_button_animator, obj);
wd->final_position = 0.5;
evas_object_smart_callback_call(data, SIG_SELECTED,
(void *)wd->text_center);
if (wd->button_animator) ecore_animator_del(wd->button_animator);
wd->button_animator = ecore_animator_add(_button_animation, data);
return;
}
if ((sd->enabled_position & ELM_ACTIONSLIDER_RIGHT) &&
if ((wd->enabled_position & ELM_ACTIONSLIDER_RIGHT) &&
((!elm_widget_mirrored_get(obj) && position == 1.0) ||
(elm_widget_mirrored_get(obj) && position == 0.0)))
{
sd->final_position = 1;
evas_object_smart_callback_call(obj, SIG_SELECTED, (char *)right);
wd->final_position = 1;
evas_object_smart_callback_call(data, SIG_SELECTED,
(void *) wd->text_right);
return;
}
if (sd->magnet_position == ELM_ACTIONSLIDER_NONE) return;
if (wd->magnet_position == ELM_ACTIONSLIDER_NONE) return;
#define _FIX_POS_ON_MIRROREDNESS(x) \
((!elm_widget_mirrored_get(obj)) ? x : 1.0 - x)
#define _FINAL_POS_BY_ORIENTATION(x) (x)
#define _POS_BY_ORIENTATION(x) \
((!elm_widget_mirrored_get(obj)) ? \
x : 1.0 - x)
position = _FIX_POS_ON_MIRROREDNESS(position);
position = _POS_BY_ORIENTATION(position);
if (position < 0.3)
{
if (sd->magnet_position & ELM_ACTIONSLIDER_LEFT)
sd->final_position = 0;
else if (sd->magnet_position & ELM_ACTIONSLIDER_CENTER)
sd->final_position = 0.5;
else if (sd->magnet_position & ELM_ACTIONSLIDER_RIGHT)
sd->final_position = 1;
if (wd->magnet_position & ELM_ACTIONSLIDER_LEFT)
wd->final_position = _FINAL_POS_BY_ORIENTATION(0);
else if (wd->magnet_position & ELM_ACTIONSLIDER_CENTER)
wd->final_position = 0.5;
else if (wd->magnet_position & ELM_ACTIONSLIDER_RIGHT)
wd->final_position = _FINAL_POS_BY_ORIENTATION(1);
}
else if ((position >= 0.3) && (position <= 0.7))
{
if (sd->magnet_position & ELM_ACTIONSLIDER_CENTER)
sd->final_position = 0.5;
if (wd->magnet_position & ELM_ACTIONSLIDER_CENTER)
wd->final_position = 0.5;
else if (position < 0.5)
{
if (sd->magnet_position & ELM_ACTIONSLIDER_LEFT)
sd->final_position = 0;
if (wd->magnet_position & ELM_ACTIONSLIDER_LEFT)
wd->final_position = _FINAL_POS_BY_ORIENTATION(0);
else
sd->final_position = 1;
wd->final_position = _FINAL_POS_BY_ORIENTATION(1);
}
else
{
if (sd->magnet_position & ELM_ACTIONSLIDER_RIGHT)
sd->final_position = 1;
if (wd->magnet_position & ELM_ACTIONSLIDER_RIGHT)
wd->final_position = _FINAL_POS_BY_ORIENTATION(1);
else
sd->final_position = 0;
wd->final_position = _FINAL_POS_BY_ORIENTATION(0);
}
}
else
{
if (sd->magnet_position & ELM_ACTIONSLIDER_RIGHT)
sd->final_position = 1;
else if (sd->magnet_position & ELM_ACTIONSLIDER_CENTER)
sd->final_position = 0.5;
if (wd->magnet_position & ELM_ACTIONSLIDER_RIGHT)
wd->final_position = _FINAL_POS_BY_ORIENTATION(1);
else if (wd->magnet_position & ELM_ACTIONSLIDER_CENTER)
wd->final_position = 0.5;
else
sd->final_position = 0;
wd->final_position = _FINAL_POS_BY_ORIENTATION(0);
}
if (sd->button_animator) ecore_animator_del(sd->button_animator);
sd->button_animator = ecore_animator_add(_button_animator, obj);
if (wd->button_animator) ecore_animator_del(wd->button_animator);
wd->button_animator = ecore_animator_add(_button_animation, data);
#undef _FINAL_FIX_POS_ON_MIRROREDNESS
#undef _FINAL_POS_BY_ORIENTATION
}
static void
_mirrored_part_fix(const Evas_Object *obj,
const char **part)
_elm_actionslider_label_set(Evas_Object *obj, const char *item, const char *label)
{
if (elm_widget_mirrored_get(obj))
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (!item || !strcmp(item, "indicator"))
{
/* exchange left and right */
if (!strcmp(*part, "left")) *part = "right";
else if (!strcmp(*part, "right"))
*part = "left";
else if (!strcmp(*part, "elm.text.right"))
*part = "elm.text.left";
else if (!strcmp(*part, "elm.text.left"))
*part = "elm.text.right";
eina_stringshare_replace(&wd->indicator_label, label);
edje_object_part_text_escaped_set(wd->as, "elm.text.indicator",
wd->indicator_label);
}
else if (!strcmp(item, "left"))
{
eina_stringshare_replace(&wd->text_left, label);
if (!elm_widget_mirrored_get(obj))
edje_object_part_text_escaped_set(wd->as, "elm.text.left", wd->text_left);
else
edje_object_part_text_escaped_set(wd->as, "elm.text.right", wd->text_left);
}
else if (!strcmp(item, "center"))
{
eina_stringshare_replace(&wd->text_center, label);
edje_object_part_text_escaped_set(wd->as, "elm.text.center", wd->text_center);
}
else if (!strcmp(item, "right"))
{
eina_stringshare_replace(&wd->text_right, label);
if (!elm_widget_mirrored_get(obj))
edje_object_part_text_escaped_set(wd->as, "elm.text.right", wd->text_right);
else
edje_object_part_text_escaped_set(wd->as, "elm.text.left", wd->text_right);
}
}
static Eina_Bool
_elm_actionslider_smart_text_set(Evas_Object *obj,
const char *item,
const char *label)
{
_mirrored_part_fix(obj, &item);
return _elm_actionslider_parent_sc->text_set(obj, item, label);
}
static const char *
_elm_actionslider_smart_text_get(const Evas_Object *obj,
const char *item)
_elm_actionslider_label_get(const Evas_Object *obj, const char *item)
{
_mirrored_part_fix(obj, &item);
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
return _elm_actionslider_parent_sc->text_get(obj, item);
}
if (!item || !strcmp(item, "indicator"))
return wd->indicator_label;
else if (!strcmp(item, "left"))
return wd->text_left;
else if (!strcmp(item, "center"))
return wd->text_center;
else if (!strcmp(item, "right"))
return wd->text_right;
static void
_elm_actionslider_smart_add(Evas_Object *obj)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Actionslider_Smart_Data);
ELM_WIDGET_CLASS(_elm_actionslider_parent_sc)->base.add(obj);
priv->mouse_down = EINA_FALSE;
priv->enabled_position = ELM_ACTIONSLIDER_ALL;
priv->drag_button_base =
evas_object_rectangle_add(evas_object_evas_get(obj));
evas_object_color_set(priv->drag_button_base, 0, 0, 0, 0);
edje_object_signal_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, "elm.drag_button,mouse,up", "",
_drag_button_up_cb, obj);
edje_object_signal_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, "elm.drag_button,mouse,down", "",
_drag_button_down_cb, priv);
edje_object_signal_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, "elm.drag_button,mouse,move", "",
_drag_button_move_cb, obj);
elm_layout_theme_set
(obj, "actionslider", "base", elm_widget_style_get(obj));
elm_layout_content_set(obj, "elm.drag_button_base", priv->drag_button_base);
}
static void
_elm_actionslider_smart_set_user(Elm_Layout_Smart_Class *sc)
{
ELM_WIDGET_CLASS(sc)->base.add = _elm_actionslider_smart_add;
ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */
ELM_WIDGET_CLASS(sc)->theme = _elm_actionslider_smart_theme;
sc->sizing_eval = _elm_actionslider_smart_sizing_eval;
sc->text_set = _elm_actionslider_smart_text_set;
sc->text_get = _elm_actionslider_smart_text_get;
sc->text_aliases = _text_aliases;
return NULL;
}
EAPI Evas_Object *
elm_actionslider_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Widget_Data *wd;
Evas *e;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
ELM_SET_WIDTYPE(widtype, "actionslider");
elm_widget_type_set(obj, "actionslider");
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_text_set_hook_set(obj, _elm_actionslider_label_set);
elm_widget_text_get_hook_set(obj, _elm_actionslider_label_get);
obj = evas_object_smart_add(e, _elm_actionslider_smart_class_new());
wd->mouse_down = EINA_FALSE;
wd->enabled_position = ELM_ACTIONSLIDER_ALL;
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
wd->as = edje_object_add(e);
_elm_theme_object_set(obj, wd->as, "actionslider", "base", "default");
elm_widget_resize_object_set(obj, wd->as);
elm_layout_sizing_eval(obj);
wd->drag_button_base = evas_object_rectangle_add(e);
evas_object_color_set(wd->drag_button_base, 0, 0, 0, 0);
edje_object_part_swallow(wd->as, "elm.drag_button_base", wd->drag_button_base);
edje_object_signal_callback_add(wd->as,
"elm.drag_button,mouse,up", "",
_drag_button_up_cb, obj);
edje_object_signal_callback_add(wd->as,
"elm.drag_button,mouse,down", "",
_drag_button_down_cb, obj);
edje_object_signal_callback_add(wd->as,
"elm.drag_button,mouse,move", "",
_drag_button_move_cb, obj);
evas_object_smart_callbacks_descriptions_set(obj, _signals);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_sizing_eval(obj);
return obj;
}
EAPI void
elm_actionslider_indicator_pos_set(Evas_Object *obj,
Elm_Actionslider_Pos pos)
elm_actionslider_indicator_pos_set(Evas_Object *obj, Elm_Actionslider_Pos pos)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
double position = 0.0;
ELM_ACTIONSLIDER_CHECK(obj);
ELM_ACTIONSLIDER_DATA_GET(obj, sd);
if (!wd) return;
pos = _get_pos_by_orientation(obj, pos);
if (pos == ELM_ACTIONSLIDER_CENTER) position = 0.5;
else if (pos == ELM_ACTIONSLIDER_RIGHT)
position = 1.0;
edje_object_part_drag_value_set
(ELM_WIDGET_DATA(sd)->resize_obj, "elm.drag_button_base", position, 0.5);
else if (pos == ELM_ACTIONSLIDER_RIGHT) position = 1.0;
edje_object_part_drag_value_set(wd->as, "elm.drag_button_base", position, 0.5);
}
EAPI Elm_Actionslider_Pos
elm_actionslider_indicator_pos_get(const Evas_Object *obj)
{
ELM_CHECK_WIDTYPE(obj, widtype) ELM_ACTIONSLIDER_NONE;
Widget_Data *wd = elm_widget_data_get(obj);
double position;
if (!wd) return ELM_ACTIONSLIDER_NONE;
ELM_ACTIONSLIDER_CHECK(obj) ELM_ACTIONSLIDER_NONE;
ELM_ACTIONSLIDER_DATA_GET(obj, sd);
edje_object_part_drag_value_get
(ELM_WIDGET_DATA(sd)->resize_obj, "elm.drag_button_base", &position,
NULL);
edje_object_part_drag_value_get(wd->as, "elm.drag_button_base", &position, NULL);
if (position < 0.3)
return _get_pos_by_orientation(obj, ELM_ACTIONSLIDER_LEFT);
else if (position < 0.7)
@ -516,64 +447,59 @@ elm_actionslider_indicator_pos_get(const Evas_Object *obj)
}
EAPI void
elm_actionslider_magnet_pos_set(Evas_Object *obj,
Elm_Actionslider_Pos pos)
elm_actionslider_magnet_pos_set(Evas_Object *obj, Elm_Actionslider_Pos pos)
{
ELM_ACTIONSLIDER_CHECK(obj);
ELM_ACTIONSLIDER_DATA_GET(obj, sd);
sd->magnet_position = pos;
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
wd->magnet_position = pos;
}
EAPI Elm_Actionslider_Pos
elm_actionslider_magnet_pos_get(const Evas_Object *obj)
{
ELM_ACTIONSLIDER_CHECK(obj) ELM_ACTIONSLIDER_NONE;
ELM_ACTIONSLIDER_DATA_GET(obj, sd);
return sd->magnet_position;
ELM_CHECK_WIDTYPE(obj, widtype) ELM_ACTIONSLIDER_NONE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return ELM_ACTIONSLIDER_NONE;
return wd->magnet_position;
}
EAPI void
elm_actionslider_enabled_pos_set(Evas_Object *obj,
Elm_Actionslider_Pos pos)
elm_actionslider_enabled_pos_set(Evas_Object *obj, Elm_Actionslider_Pos pos)
{
ELM_ACTIONSLIDER_CHECK(obj);
ELM_ACTIONSLIDER_DATA_GET(obj, sd);
sd->enabled_position = pos;
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
wd->enabled_position = pos;
}
EAPI Elm_Actionslider_Pos
elm_actionslider_enabled_pos_get(const Evas_Object *obj)
{
ELM_ACTIONSLIDER_CHECK(obj) ELM_ACTIONSLIDER_NONE;
ELM_ACTIONSLIDER_DATA_GET(obj, sd);
return sd->enabled_position;
ELM_CHECK_WIDTYPE(obj, widtype) ELM_ACTIONSLIDER_NONE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return ELM_ACTIONSLIDER_NONE;
return wd->enabled_position;
}
EAPI const char *
elm_actionslider_selected_label_get(const Evas_Object *obj)
{
const char *left, *right, *center;
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
ELM_ACTIONSLIDER_CHECK(obj) NULL;
ELM_ACTIONSLIDER_DATA_GET(obj, sd);
if ((wd->final_position == 0.0) &&
(wd->enabled_position & ELM_ACTIONSLIDER_LEFT))
return wd->text_left;
_text_get(obj, &left, &right, &center);
if ((wd->final_position == 0.5) &&
(wd->enabled_position & ELM_ACTIONSLIDER_CENTER))
return wd->text_center;
if ((sd->final_position == 0.0) &&
(sd->enabled_position & ELM_ACTIONSLIDER_LEFT))
return left;
if ((sd->final_position == 0.5) &&
(sd->enabled_position & ELM_ACTIONSLIDER_CENTER))
return center;
if ((sd->final_position == 1.0) &&
(sd->enabled_position & ELM_ACTIONSLIDER_RIGHT))
return right;
if ((wd->final_position == 1.0) &&
(wd->enabled_position & ELM_ACTIONSLIDER_RIGHT))
return wd->text_right;
return NULL;
}

View File

@ -21,15 +21,12 @@
*
* @note By default all positions are set as enabled.
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for actionslider objects.
* Signals that you can add callbacks for are:
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* @li @c "selected" - when user selects an enabled position (the
* label is passed as event info)".
* @li @c "pos_changed" - when the indicator reaches any of the
* positions("left", "right" or "center").
* "selected" - when user selects an enabled position (the label is passed as
* event info)".
* "pos_changed" - when the indicator reaches any of the positions("left",
* "right" or "center").
*
* Default text parts of the actionslider widget that you can use for are:
* @li "indicator" - An indicator label of the actionslider

View File

@ -1,90 +1,75 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_layout.h"
static const char BG_SMART_NAME[] = "elm_bg";
typedef struct _Widget_Data Widget_Data;
typedef struct _Elm_Bg_Smart_Data Elm_Bg_Smart_Data;
struct _Elm_Bg_Smart_Data
struct _Widget_Data
{
Elm_Layout_Smart_Data base;
/* the basic background's edje object has three swallow spots, namely:
* - "elm.swallow.rectangle" (elm_bg_color_set),
* - "elm.swallow.background" (elm_bg_file_set) and
* - "elm.swallow.content" (elm_bg_overlay_set).
* the following three variables hold possible content to fit in each
* of them, respectively. */
Evas_Object *rect, *img;
const char *file, *group; /* path to file and group name
* to give life to "img" */
Elm_Bg_Option option;
Evas_Object *base, *rect, *img, *overlay;
const char *file, *group;
Elm_Bg_Option option;
struct
{
Evas_Coord w, h;
} load_opts;
{
Evas_Coord w, h;
} load_opts;
};
#define ELM_BG_DATA_GET(o, sd) \
Elm_Bg_Smart_Data * sd = evas_object_smart_data_get(o)
static const char *widtype = NULL;
#define ELM_BG_DATA_GET_OR_RETURN(o, ptr) \
ELM_BG_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define ELM_BG_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_BG_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_BG_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), BG_SMART_NAME, __func__)) \
return
static const Elm_Layout_Part_Alias_Description _content_aliases[] =
{
{"overlay", "elm.swallow.content"},
{NULL, NULL}
};
/* Inheriting from elm_layout. Besides, we need no more than what is
* there */
EVAS_SMART_SUBCLASS_NEW
(BG_SMART_NAME, _elm_bg, Elm_Layout_Smart_Class, Elm_Layout_Smart_Class,
elm_layout_smart_class_get, 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 _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content);
static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *part);
static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part);
static void
_elm_bg_smart_sizing_eval(Evas_Object *obj)
_del_hook(Evas_Object *obj)
{
Evas_Coord iw = 0, ih = 0, mw = -1, mh = -1;
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);
Evas_Coord w, h;
_elm_theme_object_set(obj, wd->base, "bg", "base",
elm_widget_style_get(obj));
if (wd->rect)
edje_object_part_swallow(wd->base, "elm.swallow.rectangle", wd->rect);
if (wd->img)
edje_object_part_swallow(wd->base, "elm.swallow.background", wd->img);
if (wd->overlay)
edje_object_part_swallow(wd->base, "elm.swallow.content", wd->overlay);
// FIXME: if i don't do this, bg doesnt calc correctly. why?
evas_object_geometry_get(wd->base, NULL, NULL, &w, &h);
evas_object_resize(wd->base, w, h);
}
static void
_custom_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
Widget_Data *wd = data;
Evas_Coord bx = 0, by = 0, bw = 0, bh = 0;
Evas_Coord iw = 0, ih = 0, mw = -1, mh = -1;
Evas_Coord fx = 0, fy = 0, fw = 0, fh = 0;
Evas_Coord nx = 0, ny = 0, nw = 0, nh = 0;
const char *p;
ELM_BG_DATA_GET(obj, sd);
if ((!sd->img) || (!sd->file)) return;
if (((p = strrchr(sd->file, '.'))) && (!strcasecmp(p, ".edj"))) return;
if ((!wd->img) || (!wd->file)) return;
if (((p = strrchr(wd->file, '.'))) && (!strcasecmp(p, ".edj"))) return;
/* grab image size */
evas_object_image_size_get(sd->img, &iw, &ih);
evas_object_image_size_get(wd->img, &iw, &ih);
if ((iw < 1) || (ih < 1)) return;
/* grab base object dimensions */
evas_object_geometry_get
(ELM_WIDGET_DATA(sd)->resize_obj, &bx, &by, &bw, &bh);
evas_object_geometry_get(wd->base, &bx, &by, &bw, &bh);
/* set some defaults */
nx = bx;
@ -92,246 +77,248 @@ _elm_bg_smart_sizing_eval(Evas_Object *obj)
nw = bw;
nh = bh;
switch (sd->option)
switch (wd->option)
{
case ELM_BG_OPTION_CENTER:
fw = nw = iw;
fh = nh = ih;
nx = ((bw - fw) / 2);
ny = ((bh - fh) / 2);
mw = iw;
mh = ih;
break;
fw = nw = iw;
fh = nh = ih;
nx = ((bw - fw) / 2);
ny = ((bh - fh) / 2);
mw = iw;
mh = ih;
break;
case ELM_BG_OPTION_SCALE:
fw = bw;
fh = ((ih * fw) / iw);
if (fh < bh)
{
fh = bh;
fw = ((iw * fh) / ih);
}
fx = ((bw - fw) / 2);
fy = ((bh - fh) / 2);
break;
fw = bw;
fh = ((ih * fw) / iw);
if (fh < bh)
{
fh = bh;
fw = ((iw * fh) / ih);
}
fx = ((bw - fw) / 2);
fy = ((bh - fh) / 2);
break;
case ELM_BG_OPTION_TILE:
fw = iw;
fh = ih;
break;
fw = iw;
fh = ih;
break;
case ELM_BG_OPTION_STRETCH:
default:
fw = bw;
fh = bh;
break;
fw = bw;
fh = bh;
break;
}
evas_object_move(sd->img, nx, ny);
evas_object_resize(sd->img, nw, nh);
evas_object_image_fill_set(sd->img, fx, fy, fw, fh);
evas_object_move(wd->img, nx, ny);
evas_object_resize(wd->img, nw, nh);
evas_object_image_fill_set(wd->img, fx, fy, fw, fh);
evas_object_size_hint_min_set(sd->img, mw, mh);
evas_object_size_hint_max_set(sd->img, mw, mh);
evas_object_size_hint_min_set(wd->img, mw, mh);
evas_object_size_hint_max_set(wd->img, mw, mh);
}
static void
_on_resize(void *data,
Evas *e __UNUSED__,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
{
elm_layout_sizing_eval(data);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd;
if (part && strcmp(part, "overlay")) return;
wd = elm_widget_data_get(obj);
if (!wd) return;
if (content == wd->overlay) return;
if (wd->overlay) evas_object_del(wd->overlay);
wd->overlay = content;
if (content)
{
edje_object_part_swallow(wd->base, "elm.swallow.content", content);
elm_widget_sub_object_add(obj, content);
}
_custom_resize(wd, NULL, NULL, NULL);
}
static void
_elm_bg_smart_add(Evas_Object *obj)
static Evas_Object *
_content_get_hook(const Evas_Object *obj, const char *part)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Bg_Smart_Data);
ELM_WIDGET_CLASS(_elm_bg_parent_sc)->base.add(obj);
elm_widget_can_focus_set(obj, EINA_FALSE);
priv->option = ELM_BG_OPTION_SCALE;
evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _on_resize, obj);
elm_layout_theme_set(obj, "bg", "base", elm_widget_style_get(obj));
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd;
if (part && strcmp(part, "overlay")) return NULL;
wd = elm_widget_data_get(obj);
if (!wd) return NULL;
return wd->overlay;
}
static void
_elm_bg_smart_set_user(Elm_Layout_Smart_Class *sc)
static Evas_Object *
_content_unset_hook(Evas_Object *obj, const char *part)
{
ELM_WIDGET_CLASS(sc)->base.add = _elm_bg_smart_add;
sc->sizing_eval = _elm_bg_smart_sizing_eval;
sc->content_aliases = _content_aliases;
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd;
Evas_Object *overlay;
if (part && strcmp(part, "overlay")) return NULL;
wd = elm_widget_data_get(obj);
if (!wd || !wd->overlay) return NULL;
overlay = wd->overlay;
elm_widget_sub_object_del(obj, wd->overlay);
edje_object_part_unswallow(wd->base, wd->overlay);
wd->overlay = NULL;
_custom_resize(wd, NULL, NULL, NULL);
return overlay;
}
EAPI Evas_Object *
elm_bg_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
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_content_set_hook_set(obj, _content_set_hook);
elm_widget_content_get_hook_set(obj, _content_get_hook);
elm_widget_content_unset_hook_set(obj, _content_unset_hook);
obj = evas_object_smart_add(e, _elm_bg_smart_class_new());
elm_widget_can_focus_set(obj, EINA_FALSE);
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
wd->base = edje_object_add(e);
_elm_theme_object_set(obj, wd->base, "bg", "base", "default");
elm_widget_resize_object_set(obj, wd->base);
evas_object_event_callback_add(wd->base, EVAS_CALLBACK_RESIZE,
_custom_resize, wd);
wd->option = ELM_BG_OPTION_SCALE;
return obj;
}
EAPI Eina_Bool
elm_bg_file_set(Evas_Object *obj,
const char *file,
const char *group)
elm_bg_file_set(Evas_Object *obj, const char *file, const char *group)
{
ELM_BG_CHECK(obj) EINA_FALSE;
ELM_BG_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE);
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
const char *p;
Eina_Bool ret;
if (sd->img)
if (wd->img)
{
evas_object_del(sd->img);
sd->img = NULL;
evas_object_del(wd->img);
wd->img = NULL;
}
if (!file)
{
eina_stringshare_del(sd->file);
sd->file = NULL;
eina_stringshare_del(sd->group);
sd->group = NULL;
eina_stringshare_del(wd->file);
wd->file = NULL;
eina_stringshare_del(wd->group);
wd->group = NULL;
return EINA_TRUE;
}
eina_stringshare_replace(&sd->file, file);
eina_stringshare_replace(&sd->group, group);
eina_stringshare_replace(&wd->file, file);
eina_stringshare_replace(&wd->group, group);
if (((p = strrchr(file, '.'))) && (!strcasecmp(p, ".edj")))
{
sd->img = edje_object_add
(evas_object_evas_get(ELM_WIDGET_DATA(sd)->resize_obj));
ret = edje_object_file_set(sd->img, file, group);
wd->img = edje_object_add(evas_object_evas_get(wd->base));
edje_object_file_set(wd->img, file, group);
}
else
{
int err;
sd->img = evas_object_image_add
(evas_object_evas_get(ELM_WIDGET_DATA(sd)->resize_obj));
if ((sd->load_opts.w > 0) && (sd->load_opts.h > 0))
evas_object_image_load_size_set
(sd->img, sd->load_opts.w, sd->load_opts.h);
evas_object_image_file_set(sd->img, file, group);
err = evas_object_image_load_error_get(sd->img);
if (err != EVAS_LOAD_ERROR_NONE)
{
ERR("Could not load image '%s': %s\n",
file, evas_load_error_str(err));
ret = EINA_FALSE;
}
else
ret = EINA_TRUE;
wd->img = evas_object_image_add(evas_object_evas_get(wd->base));
if ((wd->load_opts.w > 0) && (wd->load_opts.h > 0))
evas_object_image_load_size_set(wd->img, wd->load_opts.w, wd->load_opts.h);
evas_object_image_file_set(wd->img, file, group);
}
evas_object_repeat_events_set(wd->img, EINA_TRUE);
edje_object_part_swallow(wd->base, "elm.swallow.background", wd->img);
elm_widget_sub_object_add(obj, wd->img);
_custom_resize(wd, NULL, NULL, NULL);
evas_object_repeat_events_set(sd->img, EINA_TRUE);
ret &= elm_layout_content_set(obj, "elm.swallow.background", sd->img);
elm_layout_sizing_eval(obj);
return ret;
return EINA_TRUE;
}
EAPI void
elm_bg_file_get(const Evas_Object *obj,
const char **file,
const char **group)
elm_bg_file_get(const Evas_Object *obj, const char **file, const char **group)
{
ELM_BG_CHECK(obj);
ELM_BG_DATA_GET_OR_RETURN(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (file) *file = wd->file;
if (group) *group = wd->group;
if (file) *file = sd->file;
if (group) *group = sd->group;
return;
}
EAPI void
elm_bg_option_set(Evas_Object *obj,
Elm_Bg_Option option)
elm_bg_option_set(Evas_Object *obj, Elm_Bg_Option option)
{
ELM_BG_CHECK(obj);
ELM_BG_DATA_GET_OR_RETURN(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd;
sd->option = option;
wd = elm_widget_data_get(obj);
wd->option = option;
_custom_resize(wd, NULL, NULL, NULL);
elm_layout_sizing_eval(obj);
return;
}
EAPI Elm_Bg_Option
elm_bg_option_get(const Evas_Object *obj)
{
ELM_BG_CHECK(obj) EINA_FALSE;
ELM_BG_DATA_GET_OR_RETURN_VAL(obj, sd, ELM_BG_OPTION_LAST);
ELM_CHECK_WIDTYPE(obj, widtype) ELM_BG_OPTION_LAST;
Widget_Data *wd;
return sd->option;
wd = elm_widget_data_get(obj);
return wd->option;
}
EAPI void
elm_bg_color_set(Evas_Object *obj,
int r,
int g,
int b)
elm_bg_color_set(Evas_Object *obj, int r, int g, int b)
{
ELM_BG_CHECK(obj);
ELM_BG_DATA_GET_OR_RETURN(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd;
if (!sd->rect)
wd = elm_widget_data_get(obj);
if (!wd->rect)
{
sd->rect = evas_object_rectangle_add
(evas_object_evas_get(ELM_WIDGET_DATA(sd)->resize_obj));
elm_layout_content_set(obj, "elm.swallow.rectangle", sd->rect);
elm_layout_sizing_eval(obj);
wd->rect = evas_object_rectangle_add(evas_object_evas_get(wd->base));
edje_object_part_swallow(wd->base, "elm.swallow.rectangle", wd->rect);
elm_widget_sub_object_add(obj, wd->rect);
_custom_resize(wd, NULL, NULL, NULL);
}
evas_object_color_set(wd->rect, r, g, b, 255);
evas_object_color_set(sd->rect, r, g, b, 255);
return;
}
EAPI void
elm_bg_color_get(const Evas_Object *obj,
int *r,
int *g,
int *b)
elm_bg_color_get(const Evas_Object *obj, int *r, int *g, int *b)
{
ELM_BG_CHECK(obj);
ELM_BG_DATA_GET_OR_RETURN(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd;
evas_object_color_get(sd->rect, r, g, b, NULL);
wd = elm_widget_data_get(obj);
evas_object_color_get(wd->rect, r, g, b, NULL);
return;
}
EAPI void
elm_bg_load_size_set(Evas_Object *obj,
Evas_Coord w,
Evas_Coord h)
elm_bg_load_size_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
{
ELM_BG_CHECK(obj);
ELM_BG_DATA_GET_OR_RETURN(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
const char *p;
if (!wd) return;
wd->load_opts.w = w;
wd->load_opts.h = h;
if (!wd->img) return;
if (!(((p = strrchr(wd->file, '.'))) && (!strcasecmp(p, ".edj"))))
evas_object_image_load_size_set(wd->img, w, h);
sd->load_opts.w = w;
sd->load_opts.h = h;
if (!sd->img) return;
if (!(((p = strrchr(sd->file, '.'))) && (!strcasecmp(p, ".edj"))))
evas_object_image_load_size_set(sd->img, w, h);
return;
}

View File

@ -1,5 +1,5 @@
/**
* @defgroup Bg Background
* @defgroup Bg Bg
* @ingroup Elementary
*
* @image html img/widget/bg/preview-00.png
@ -14,11 +14,8 @@
* properties useful to a background, like setting it to tiled,
* centered, scaled or stretched.
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for background objects.
*
* Default content parts of the bg widget that you can use for are:
* @li @c "overlay" - overlay of the bg
* @li "overlay" - overlay of the bg
*
* Supported elm_object common APIs.
* @li @ref elm_object_part_content_set

View File

@ -2,90 +2,81 @@
#include "elm_priv.h"
#include "els_box.h"
static const char BOX_SMART_NAME[] = "elm_box";
static const char SIG_CHILD_ADDED[] = "child,added";
static const char SIG_CHILD_REMOVED[] = "child,removed";
typedef struct _Elm_Box_Smart_Data Elm_Box_Smart_Data;
static const Evas_Smart_Cb_Description _signals[] = {
{SIG_CHILD_ADDED, ""},
{SIG_CHILD_REMOVED, ""},
{NULL, NULL}
};
typedef struct _Widget_Data Widget_Data;
typedef struct _Transition_Animation_Data Transition_Animation_Data;
struct _Elm_Box_Smart_Data
struct _Widget_Data
{
Elm_Widget_Smart_Data base; /* base widget smart data as
* first member obligatory, as
* we're inheriting from it */
Eina_Bool horizontal : 1;
Eina_Bool homogeneous : 1;
Eina_Bool recalc : 1;
Evas_Object *box;
Eina_Bool horizontal:1;
Eina_Bool homogeneous:1;
Eina_Bool recalc:1;
};
struct _Elm_Box_Transition
{
double initial_time;
double duration;
double initial_time;
double duration;
Eina_Bool animation_ended:1;
Eina_Bool recalculate:1;
Ecore_Animator *animator;
struct
{
Evas_Object_Box_Layout layout;
void *data;
void (*free_data)(void *data);
} start, end;
{
Evas_Object_Box_Layout layout;
void *data;
void(*free_data)(void *data);
} start, end;
void (*transition_end_cb)(void *data);
void *transition_end_data;
void (*transition_end_free_data)(void *data);
Eina_List *objs;
Evas_Object *box;
Eina_Bool animation_ended : 1;
Eina_Bool recalculate : 1;
void(*transition_end_cb)(void *data);
void *transition_end_data;
void (*transition_end_free_data)(void *data);
Eina_List *objs;
Evas_Object *box;
};
struct _Transition_Animation_Data
{
Evas_Object *obj;
struct
{
Evas_Coord x, y, w, h;
} start, end;
{
Evas_Coord x, y, w, h;
} start, end;
};
#define ELM_BOX_DATA_GET(o, sd) \
Elm_Box_Smart_Data * sd = evas_object_smart_data_get(o)
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);
#define ELM_BOX_DATA_GET_OR_RETURN(o, ptr) \
ELM_BOX_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
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, EINA_FALSE);
}
#define ELM_BOX_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_BOX_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_BOX_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), BOX_SMART_NAME, __func__)) \
return
EVAS_SMART_SUBCLASS_NEW
(BOX_SMART_NAME, _elm_box, Elm_Widget_Smart_Class,
Elm_Widget_Smart_Class, elm_widget_smart_class_get, NULL);
static const char SIG_CHILD_ADDED[] = "child,added";
static const char SIG_CHILD_REMOVED[] = "child,removed";
static const Evas_Smart_Cb_Description _smart_callbacks[] = {
{SIG_CHILD_ADDED, ""},
{SIG_CHILD_REMOVED, ""},
{NULL, NULL}
};
static void
_del_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
free(wd);
}
static void *
_elm_box_list_data_get(const Eina_List *list)
@ -95,9 +86,7 @@ _elm_box_list_data_get(const Eina_List *list)
}
static void
_child_added_cb_proxy(void *data,
Evas_Object *o __UNUSED__,
void *event_info)
_cb_proxy_child_added(void *data, Evas_Object *o __UNUSED__, void *event_info)
{
Evas_Object *box = data;
Evas_Object_Box_Option *opt = event_info;
@ -105,9 +94,7 @@ _child_added_cb_proxy(void *data,
}
static void
_child_removed_cb_proxy(void *data,
Evas_Object *o __UNUSED__,
void *event_info)
_cb_proxy_child_removed(void *data, Evas_Object *o __UNUSED__, void *event_info)
{
Evas_Object *box = data;
Evas_Object *child = event_info;
@ -115,14 +102,14 @@ _child_removed_cb_proxy(void *data,
}
static Eina_Bool
_elm_box_smart_focus_next(const Evas_Object *obj,
Elm_Focus_Direction dir,
Evas_Object **next)
_elm_box_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
{
Widget_Data *wd = elm_widget_data_get(obj);
const Eina_List *items;
void *(*list_data_get)(const Eina_List *list);
void *(*list_data_get) (const Eina_List *list);
ELM_BOX_DATA_GET(obj, sd);
if ((!wd) || (!wd->box))
return EINA_FALSE;
/* Focus chain */
/* TODO: Change this to use other chain */
@ -130,8 +117,7 @@ _elm_box_smart_focus_next(const Evas_Object *obj,
list_data_get = eina_list_data_get;
else
{
Evas_Object_Box_Data *bd =
evas_object_smart_data_get(ELM_WIDGET_DATA(sd)->resize_obj);
Evas_Object_Box_Data *bd = evas_object_smart_data_get(wd->box);
items = bd->children;
list_data_get = _elm_box_list_data_get;
@ -141,76 +127,65 @@ _elm_box_smart_focus_next(const Evas_Object *obj,
return elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next);
}
static Eina_Bool
_elm_box_smart_theme(Evas_Object *obj)
static void
_theme_hook(Evas_Object *obj)
{
ELM_BOX_DATA_GET(obj, sd);
if (!_elm_box_parent_sc->theme(obj)) return EINA_FALSE;
evas_object_smart_calculate(ELM_WIDGET_DATA(sd)->resize_obj);
return EINA_TRUE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
_elm_widget_mirrored_reload(obj);
evas_object_smart_calculate(wd->box);
}
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;
ELM_BOX_DATA_GET(obj, sd);
evas_object_size_hint_min_get
(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh);
evas_object_size_hint_max_get
(ELM_WIDGET_DATA(sd)->resize_obj, &maxw, &maxh);
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
_on_size_hints_changed(void *data,
Evas *e __UNUSED__,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
_sizing_eval(data);
}
static Eina_Bool
_elm_box_smart_sub_object_del(Evas_Object *obj,
Evas_Object *child)
static void
_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
if (!_elm_box_parent_sc->sub_object_del(obj, child)) return EINA_FALSE;
_sizing_eval(obj);
return EINA_TRUE;
}
static void
_elm_box_custom_layout(Evas_Object *o,
Evas_Object_Box_Data *priv,
void *data)
_layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data)
{
ELM_BOX_DATA_GET(data, sd);
_els_box_layout(o, priv, sd->horizontal, sd->homogeneous,
elm_widget_mirrored_get(data));
Evas_Object *obj = (Evas_Object *) data;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
_els_box_layout(o, priv, wd->horizontal, wd->homogeneous,
elm_widget_mirrored_get(obj));
}
static Eina_Bool
_transition_animation(void *data)
{
evas_object_smart_changed(data);
return ECORE_CALLBACK_RENEW;
}
static void
_transition_layout_child_added(void *data,
Evas_Object *obj __UNUSED__,
void *event_info)
_transition_layout_child_added(void *data, Evas_Object *obj __UNUSED__, void *event_info)
{
Transition_Animation_Data *tad;
Evas_Object_Box_Option *opt = event_info;
@ -218,22 +193,19 @@ _transition_layout_child_added(void *data,
tad = calloc(1, sizeof(Transition_Animation_Data));
if (!tad) return;
tad->obj = opt->obj;
layout_data->objs = eina_list_append(layout_data->objs, tad);
layout_data->recalculate = EINA_TRUE;
}
static void
_transition_layout_child_removed(void *data,
Evas_Object *obj __UNUSED__,
void *event_info)
_transition_layout_child_removed(void *data, Evas_Object *obj __UNUSED__, void *event_info)
{
Eina_List *l;
Transition_Animation_Data *tad;
Elm_Box_Transition *layout_data = data;
EINA_LIST_FOREACH (layout_data->objs, l, tad)
EINA_LIST_FOREACH(layout_data->objs, l, tad)
{
if (tad->obj == event_info)
{
@ -246,32 +218,27 @@ _transition_layout_child_removed(void *data,
}
static void
_transition_layout_obj_resize_cb(void *data,
Evas *e __UNUSED__,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_transition_layout_obj_resize_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
Elm_Box_Transition *layout_data = data;
layout_data->recalculate = EINA_TRUE;
}
static void
_transition_layout_calculate_coords(Evas_Object *obj,
Evas_Object_Box_Data *priv,
_transition_layout_calculate_coords(Evas_Object *obj, Evas_Object_Box_Data *priv,
Elm_Box_Transition *layout_data)
{
Eina_List *l;
Evas_Coord x, y, w, h;
Transition_Animation_Data *tad;
Evas_Coord x, y, w, h;
const double curtime = ecore_loop_time_get();
layout_data->duration =
layout_data->duration - (curtime - layout_data->initial_time);
layout_data->duration - (curtime - layout_data->initial_time);
layout_data->initial_time = curtime;
evas_object_geometry_get(obj, &x, &y, &w, &h);
EINA_LIST_FOREACH (layout_data->objs, l, tad)
EINA_LIST_FOREACH(layout_data->objs, l, tad)
{
evas_object_geometry_get(tad->obj, &tad->start.x, &tad->start.y,
&tad->start.w, &tad->start.h);
@ -279,7 +246,7 @@ _transition_layout_calculate_coords(Evas_Object *obj,
tad->start.y = tad->start.y - y;
}
layout_data->end.layout(obj, priv, layout_data->end.data);
EINA_LIST_FOREACH (layout_data->objs, l, tad)
EINA_LIST_FOREACH(layout_data->objs, l, tad)
{
evas_object_geometry_get(tad->obj, &tad->end.x, &tad->end.y,
&tad->end.w, &tad->end.h);
@ -296,16 +263,16 @@ _transition_layout_load_children_list(Evas_Object_Box_Data *priv,
Evas_Object_Box_Option *opt;
Transition_Animation_Data *tad;
EINA_LIST_FREE (layout_data->objs, tad)
free(tad);
EINA_LIST_FREE(layout_data->objs, tad)
free(tad);
EINA_LIST_FOREACH (priv->children, l, opt)
EINA_LIST_FOREACH(priv->children, l, opt)
{
tad = calloc(1, sizeof(Transition_Animation_Data));
if (!tad)
{
EINA_LIST_FREE (layout_data->objs, tad)
free(tad);
EINA_LIST_FREE(layout_data->objs, tad)
free(tad);
layout_data->objs = NULL;
return EINA_FALSE;
}
@ -316,11 +283,8 @@ _transition_layout_load_children_list(Evas_Object_Box_Data *priv,
}
static Eina_Bool
_transition_layout_animation_start(Evas_Object *obj,
Evas_Object_Box_Data *priv,
Elm_Box_Transition *layout_data,
Eina_Bool (*transition_animation_cb)
(void *data))
_transition_layout_animation_start(Evas_Object *obj, Evas_Object_Box_Data *priv,
Elm_Box_Transition *layout_data, Eina_Bool(*transition_animation_cb)(void *data))
{
layout_data->start.layout(obj, priv, layout_data->start.data);
layout_data->box = obj;
@ -328,22 +292,17 @@ _transition_layout_animation_start(Evas_Object *obj,
if (!_transition_layout_load_children_list(priv, layout_data))
return EINA_FALSE;
_transition_layout_calculate_coords(obj, priv, layout_data);
evas_object_event_callback_add
(obj, EVAS_CALLBACK_RESIZE, _transition_layout_obj_resize_cb,
layout_data);
evas_object_smart_callback_add
(obj, SIG_CHILD_ADDED, _transition_layout_child_added, layout_data);
evas_object_smart_callback_add
(obj, SIG_CHILD_REMOVED, _transition_layout_child_removed, layout_data);
evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
_transition_layout_obj_resize_cb, layout_data);
evas_object_smart_callback_add(obj, SIG_CHILD_ADDED,
_transition_layout_child_added, layout_data);
evas_object_smart_callback_add(obj, SIG_CHILD_REMOVED,
_transition_layout_child_removed, layout_data);
if (!layout_data->animator)
layout_data->animator = ecore_animator_add(transition_animation_cb, obj);
layout_data->animation_ended = EINA_FALSE;
return EINA_TRUE;
}
@ -351,7 +310,6 @@ static void
_transition_layout_animation_stop(Elm_Box_Transition *layout_data)
{
layout_data->animation_ended = EINA_TRUE;
if (layout_data->animator)
{
ecore_animator_del(layout_data->animator);
@ -363,21 +321,19 @@ _transition_layout_animation_stop(Elm_Box_Transition *layout_data)
}
static void
_transition_layout_animation_exec(Evas_Object *obj,
Evas_Object_Box_Data *priv __UNUSED__,
Elm_Box_Transition *layout_data,
const double curtime)
_transition_layout_animation_exec(Evas_Object *obj, Evas_Object_Box_Data *priv __UNUSED__,
Elm_Box_Transition *layout_data, const double curtime)
{
Eina_List *l;
double progress = 0.0;
Evas_Coord x, y, w, h;
Transition_Animation_Data *tad;
Evas_Coord x, y, w, h;
Evas_Coord cur_x, cur_y, cur_w, cur_h;
double progress = 0.0;
progress = (curtime - layout_data->initial_time) / layout_data->duration;
evas_object_geometry_get(obj, &x, &y, &w, &h);
EINA_LIST_FOREACH (layout_data->objs, l, tad)
EINA_LIST_FOREACH(layout_data->objs, l, tad)
{
cur_x = x + tad->start.x + ((tad->end.x - tad->start.x) * progress);
cur_y = y + tad->start.y + ((tad->end.y - tad->start.y) * progress);
@ -388,236 +344,202 @@ _transition_layout_animation_exec(Evas_Object *obj,
}
}
static void
_elm_box_smart_add(Evas_Object *obj)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Box_Smart_Data);
ELM_WIDGET_DATA(priv)->resize_obj =
evas_object_box_add(evas_object_evas_get(obj));
evas_object_box_layout_set
(ELM_WIDGET_DATA(priv)->resize_obj, _elm_box_custom_layout, obj, NULL);
evas_object_event_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_on_size_hints_changed, obj);
_elm_box_parent_sc->base.add(obj);
evas_object_smart_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, SIG_CHILD_ADDED,
_child_added_cb_proxy, obj);
evas_object_smart_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, SIG_CHILD_REMOVED,
_child_removed_cb_proxy, obj);
elm_widget_can_focus_set(obj, EINA_FALSE);
elm_widget_highlight_ignore_set(obj, EINA_TRUE);
}
static void
_elm_box_smart_del(Evas_Object *obj)
{
Eina_List *l;
Evas_Object *child;
ELM_BOX_DATA_GET(obj, sd);
evas_object_event_callback_del_full
(ELM_WIDGET_DATA(sd)->resize_obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_on_size_hints_changed, obj);
/* let's make our box object the *last* to be processed, since it
* may (smart) parent other sub objects here */
EINA_LIST_FOREACH (ELM_WIDGET_DATA(sd)->subobjs, l, child)
{
if (child == ELM_WIDGET_DATA(sd)->resize_obj)
{
ELM_WIDGET_DATA(sd)->subobjs =
eina_list_demote_list(ELM_WIDGET_DATA(sd)->subobjs, l);
break;
}
}
_elm_box_parent_sc->base.del(obj);
}
static void
_elm_box_smart_set_user(Elm_Widget_Smart_Class *sc)
{
sc->base.add = _elm_box_smart_add;
sc->base.del = _elm_box_smart_del;
sc->sub_object_del = _elm_box_smart_sub_object_del;
sc->theme = _elm_box_smart_theme;
sc->focus_next = _elm_box_smart_focus_next;
}
EAPI Evas_Object *
elm_box_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
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);
elm_widget_focus_next_hook_set(obj, _elm_box_focus_next_hook);
elm_widget_can_focus_set(obj, EINA_FALSE);
elm_widget_highlight_ignore_set(obj, EINA_TRUE);
elm_widget_theme_hook_set(obj, _theme_hook);
obj = evas_object_smart_add(e, _elm_box_smart_class_new());
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, obj, NULL);
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
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);
evas_object_smart_callbacks_descriptions_set(obj, _signals);
evas_object_smart_callback_add
(wd->box, SIG_CHILD_ADDED, _cb_proxy_child_added, obj);
evas_object_smart_callback_add
(wd->box, SIG_CHILD_REMOVED, _cb_proxy_child_removed, obj);
return obj;
}
EAPI void
elm_box_horizontal_set(Evas_Object *obj,
Eina_Bool horizontal)
elm_box_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
{
ELM_BOX_CHECK(obj);
ELM_BOX_DATA_GET(obj, sd);
sd->horizontal = !!horizontal;
evas_object_smart_calculate(ELM_WIDGET_DATA(sd)->resize_obj);
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);
} */
}
EAPI Eina_Bool
elm_box_horizontal_get(const Evas_Object *obj)
{
ELM_BOX_CHECK(obj) EINA_FALSE;
ELM_BOX_DATA_GET(obj, sd);
return sd->horizontal;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->horizontal;
}
EAPI void
elm_box_homogeneous_set(Evas_Object *obj,
Eina_Bool homogeneous)
elm_box_homogeneous_set(Evas_Object *obj, Eina_Bool homogeneous)
{
ELM_BOX_CHECK(obj);
ELM_BOX_DATA_GET(obj, sd);
sd->homogeneous = !!homogeneous;
evas_object_smart_calculate(ELM_WIDGET_DATA(sd)->resize_obj);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
wd->homogeneous = !!homogeneous;
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);
} */
}
EAPI Eina_Bool
elm_box_homogeneous_get(const Evas_Object *obj)
{
ELM_BOX_CHECK(obj) EINA_FALSE;
ELM_BOX_DATA_GET(obj, sd);
return sd->homogeneous;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->homogeneous;
}
EAPI void
elm_box_pack_start(Evas_Object *obj,
Evas_Object *subobj)
elm_box_pack_start(Evas_Object *obj, Evas_Object *subobj)
{
ELM_BOX_CHECK(obj);
ELM_BOX_DATA_GET(obj, sd);
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(ELM_WIDGET_DATA(sd)->resize_obj, subobj);
evas_object_box_prepend(wd->box, subobj);
}
EAPI void
elm_box_pack_end(Evas_Object *obj,
Evas_Object *subobj)
elm_box_pack_end(Evas_Object *obj, Evas_Object *subobj)
{
ELM_BOX_CHECK(obj);
ELM_BOX_DATA_GET(obj, sd);
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(ELM_WIDGET_DATA(sd)->resize_obj, subobj);
evas_object_box_append(wd->box, subobj);
}
EAPI void
elm_box_pack_before(Evas_Object *obj,
Evas_Object *subobj,
Evas_Object *before)
elm_box_pack_before(Evas_Object *obj, Evas_Object *subobj, Evas_Object *before)
{
ELM_BOX_CHECK(obj);
ELM_BOX_DATA_GET(obj, sd);
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
(ELM_WIDGET_DATA(sd)->resize_obj, subobj, before);
evas_object_box_insert_before(wd->box, subobj, before);
}
EAPI void
elm_box_pack_after(Evas_Object *obj,
Evas_Object *subobj,
Evas_Object *after)
elm_box_pack_after(Evas_Object *obj, Evas_Object *subobj, Evas_Object *after)
{
ELM_BOX_CHECK(obj);
ELM_BOX_DATA_GET(obj, sd);
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(ELM_WIDGET_DATA(sd)->resize_obj, subobj, after);
evas_object_box_insert_after(wd->box, subobj, after);
}
EAPI void
elm_box_clear(Evas_Object *obj)
{
ELM_BOX_CHECK(obj);
ELM_BOX_DATA_GET(obj, sd);
/* EINA_TRUE means to delete objects as well */
evas_object_box_remove_all(ELM_WIDGET_DATA(sd)->resize_obj, EINA_TRUE);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_box_remove_all(wd->box, EINA_TRUE);
}
EAPI void
elm_box_unpack(Evas_Object *obj, Evas_Object *subobj)
{
ELM_BOX_CHECK(obj);
ELM_BOX_DATA_GET(obj, sd);
elm_widget_sub_object_del(obj, subobj);
evas_object_box_remove(ELM_WIDGET_DATA(sd)->resize_obj, subobj);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_box_remove(wd->box, subobj);
}
EAPI void
elm_box_unpack_all(Evas_Object *obj)
{
Evas_Object_Box_Data *bd;
Evas_Object_Box_Option *opt;
Eina_List *l;
ELM_BOX_CHECK(obj);
ELM_BOX_DATA_GET(obj, sd);
bd = evas_object_smart_data_get(ELM_WIDGET_DATA(sd)->resize_obj);
EINA_LIST_FOREACH (bd->children, l, opt)
elm_widget_sub_object_del(obj, opt->obj);
/* EINA_FALSE means to delete objects as well */
evas_object_box_remove_all(ELM_WIDGET_DATA(sd)->resize_obj, EINA_FALSE);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_box_remove_all(wd->box, EINA_FALSE);
}
EAPI void
elm_box_layout_set(Evas_Object *obj,
Evas_Object_Box_Layout cb,
const void *data,
Ecore_Cb free_data)
elm_box_layout_set(Evas_Object *obj, Evas_Object_Box_Layout cb, const void *data, Ecore_Cb free_data)
{
ELM_BOX_CHECK(obj);
ELM_BOX_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (cb)
evas_object_box_layout_set
(ELM_WIDGET_DATA(sd)->resize_obj, cb, data, free_data);
evas_object_box_layout_set(wd->box, cb, data, free_data);
else
evas_object_box_layout_set
(ELM_WIDGET_DATA(sd)->resize_obj, _elm_box_custom_layout, obj, NULL);
evas_object_box_layout_set(wd->box, _layout, obj, NULL);
}
EAPI void
elm_box_layout_transition(Evas_Object *obj,
Evas_Object_Box_Data *priv,
void *data)
elm_box_layout_transition(Evas_Object *obj, Evas_Object_Box_Data *priv, void *data)
{
Elm_Box_Transition *box_data = data;
const double curtime = ecore_loop_time_get();
@ -651,11 +573,9 @@ elm_box_layout_transition(Evas_Object *obj,
EAPI Elm_Box_Transition *
elm_box_transition_new(const double duration,
Evas_Object_Box_Layout start_layout,
void *start_layout_data,
Evas_Object_Box_Layout start_layout, void *start_layout_data,
Ecore_Cb start_layout_free_data,
Evas_Object_Box_Layout end_layout,
void *end_layout_data,
Evas_Object_Box_Layout end_layout, void *end_layout_data,
Ecore_Cb end_layout_free_data,
Ecore_Cb transition_end_cb,
void *transition_end_data)
@ -666,7 +586,8 @@ elm_box_transition_new(const double duration,
EINA_SAFETY_ON_NULL_RETURN_VAL(end_layout, NULL);
box_data = calloc(1, sizeof(Elm_Box_Transition));
if (!box_data) return NULL;
if (!box_data)
return NULL;
box_data->start.layout = start_layout;
box_data->start.data = start_layout_data;
@ -677,7 +598,6 @@ elm_box_transition_new(const double duration,
box_data->duration = duration;
box_data->transition_end_cb = transition_end_cb;
box_data->transition_end_data = transition_end_data;
return box_data;
}
@ -692,92 +612,72 @@ elm_box_transition_free(void *data)
box_data->start.free_data(box_data->start.data);
if ((box_data->end.free_data) && (box_data->end.data))
box_data->end.free_data(box_data->end.data);
EINA_LIST_FREE (box_data->objs, tad)
free(tad);
evas_object_event_callback_del
(box_data->box, EVAS_CALLBACK_RESIZE, _transition_layout_obj_resize_cb);
evas_object_smart_callback_del
(box_data->box, SIG_CHILD_ADDED, _transition_layout_child_added);
evas_object_smart_callback_del
(box_data->box, SIG_CHILD_REMOVED, _transition_layout_child_removed);
EINA_LIST_FREE(box_data->objs, tad)
free(tad);
evas_object_event_callback_del(box_data->box, EVAS_CALLBACK_RESIZE, _transition_layout_obj_resize_cb);
evas_object_smart_callback_del(box_data->box, SIG_CHILD_ADDED, _transition_layout_child_added);
evas_object_smart_callback_del(box_data->box, SIG_CHILD_REMOVED, _transition_layout_child_removed);
if (box_data->animator)
{
ecore_animator_del(box_data->animator);
box_data->animator = NULL;
}
free(data);
}
EAPI Eina_List *
elm_box_children_get(const Evas_Object *obj)
{
ELM_BOX_CHECK(obj) NULL;
ELM_BOX_DATA_GET(obj, sd);
return evas_object_box_children_get(ELM_WIDGET_DATA(sd)->resize_obj);
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
return evas_object_box_children_get(wd->box);
}
EAPI void
elm_box_padding_set(Evas_Object *obj,
Evas_Coord horizontal,
Evas_Coord vertical)
elm_box_padding_set(Evas_Object *obj, Evas_Coord horizontal, Evas_Coord vertical)
{
ELM_BOX_CHECK(obj);
ELM_BOX_DATA_GET(obj, sd);
evas_object_box_padding_set
(ELM_WIDGET_DATA(sd)->resize_obj, horizontal, vertical);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_box_padding_set(wd->box, horizontal, vertical);
}
EAPI void
elm_box_padding_get(const Evas_Object *obj,
Evas_Coord *horizontal,
Evas_Coord *vertical)
elm_box_padding_get(const Evas_Object *obj, Evas_Coord *horizontal, Evas_Coord *vertical)
{
ELM_BOX_CHECK(obj);
ELM_BOX_DATA_GET(obj, sd);
evas_object_box_padding_get
(ELM_WIDGET_DATA(sd)->resize_obj, horizontal, vertical);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_box_padding_get(wd->box, horizontal, vertical);
}
EAPI void
elm_box_align_set(Evas_Object *obj,
double horizontal,
double vertical)
elm_box_align_set(Evas_Object *obj, double horizontal, double vertical)
{
ELM_BOX_CHECK(obj);
ELM_BOX_DATA_GET(obj, sd);
evas_object_size_hint_align_set
(ELM_WIDGET_DATA(sd)->resize_obj, horizontal, vertical);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_size_hint_align_set(wd->box, horizontal, vertical);
}
EAPI void
elm_box_align_get(const Evas_Object *obj,
double *horizontal,
double *vertical)
elm_box_align_get(const Evas_Object *obj, double *horizontal, double *vertical)
{
ELM_BOX_CHECK(obj);
ELM_BOX_DATA_GET(obj, sd);
evas_object_size_hint_align_get
(ELM_WIDGET_DATA(sd)->resize_obj, horizontal, vertical);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_size_hint_align_get(wd->box, horizontal, vertical);
}
EAPI void
elm_box_recalculate(Evas_Object *obj)
{
ELM_BOX_CHECK(obj);
ELM_BOX_DATA_GET(obj, sd);
if (sd->recalc) return;
evas_object_smart_need_recalculate_set
(ELM_WIDGET_DATA(sd)->resize_obj, EINA_TRUE);
sd->recalc++;
evas_object_smart_calculate(ELM_WIDGET_DATA(sd)->resize_obj);
sd->recalc--;
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if ((!wd) || (wd->recalc)) return;
evas_object_smart_need_recalculate_set(wd->box, EINA_TRUE);
wd->recalc++;
evas_object_smart_calculate(wd->box);
wd->recalc--;
}

View File

@ -1,220 +1,368 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_layout.h"
static const char BUBBLE_SMART_NAME[] = "elm_bubble";
typedef struct _Widget_Data Widget_Data;
typedef struct _Elm_Bubble_Smart_Data Elm_Bubble_Smart_Data;
struct _Elm_Bubble_Smart_Data
struct _Widget_Data
{
Elm_Layout_Smart_Data base;
Elm_Bubble_Pos pos;
Evas_Object *bbl;
Evas_Object *content, *icon;
const char *label, *info, *corner;
Elm_Bubble_Pos pos;
};
static const char *widtype = NULL;
static void _del_hook(Evas_Object *obj);
static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
static void _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content);
static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *part);
static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part);
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 SIG_CLICKED[] = "clicked";
static const Elm_Layout_Part_Alias_Description _content_aliases[] =
static const Evas_Smart_Cb_Description _signals[] =
{
{"default", "elm.swallow.content"},
{"icon", "elm.swallow.icon"},
{NULL, NULL}
};
static const Elm_Layout_Part_Alias_Description _text_aliases[] =
{
{"default", "elm.text"},
{"info", "elm.info"},
{NULL, NULL}
};
static const Evas_Smart_Cb_Description _smart_callbacks[] =
{
{SIG_CLICKED, ""},
{NULL, NULL}
{SIG_CLICKED, ""},
{NULL, NULL}
};
static const char *corner_string[] =
{
"top_left",
"top_right",
"bottom_left",
"bottom_right"
"top_left",
"top_right",
"bottom_left",
"bottom_right"
};
#define ELM_BUBBLE_DATA_GET(o, sd) \
Elm_Bubble_Smart_Data * sd = evas_object_smart_data_get(o)
#define ELM_BUBBLE_DATA_GET_OR_RETURN(o, ptr) \
ELM_BUBBLE_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define ELM_BUBBLE_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_BUBBLE_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_BUBBLE_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), BUBBLE_SMART_NAME, __func__)) \
return
/* Inheriting from elm_layout. Besides, we need no more than what is
* there */
EVAS_SMART_SUBCLASS_NEW
(BUBBLE_SMART_NAME, _elm_bubble, Elm_Layout_Smart_Class,
Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks);
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);
if (wd->corner) eina_stringshare_del(wd->corner);
free(wd);
}
static void
_elm_bubble_smart_sizing_eval(Evas_Object *obj)
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
edje_object_mirrored_set(wd->bbl, rtl);
}
static void
_theme_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
_elm_widget_mirrored_reload(obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_elm_theme_object_set(obj, wd->bbl, "bubble", corner_string[wd->pos],
elm_widget_style_get(obj));
edje_object_part_text_escaped_set(wd->bbl, "elm.text", wd->label);
if (wd->label) edje_object_signal_emit(wd->bbl, "elm,state,text,visible", "elm");
else edje_object_signal_emit(wd->bbl, "elm,state,text,hidden", "elm");
edje_object_part_text_escaped_set(wd->bbl, "elm.info", wd->info);
if (wd->info) edje_object_signal_emit(wd->bbl, "elm,state,info,visible", "elm");
else edje_object_signal_emit(wd->bbl, "elm,state,info,hidden", "elm");
if (wd->content)
{
edje_object_part_swallow(wd->bbl, "elm.swallow.content", wd->content);
edje_object_message_signal_process(wd->bbl);
}
if (wd->icon)
edje_object_signal_emit(wd->bbl, "elm,state,icon,visible", "elm");
else
edje_object_signal_emit(wd->bbl, "elm,state,icon,hidden", "elm");
edje_object_scale_set(wd->bbl,
elm_widget_scale_get(obj) * _elm_config->scale);
_sizing_eval(obj);
}
static void
_content_set(Evas_Object *obj, Evas_Object *content)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->content == content) return;
if (wd->content) evas_object_del(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);
}
static Evas_Object *
_content_unset(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
Evas_Object *content;
if (!wd) return NULL;
if (!wd->content) return NULL;
content = wd->content;
elm_widget_sub_object_del(obj, content);
evas_object_event_callback_del_full(content,
EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_changed_size_hints, obj);
edje_object_part_unswallow(wd->bbl, content);
wd->content = NULL;
return content;
}
static void
_icon_set(Evas_Object *obj, Evas_Object* icon)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->icon == icon) return;
if (wd->icon) evas_object_del(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);
edje_object_signal_emit(wd->bbl, "elm,state,icon,visible", "elm");
edje_object_message_signal_process(wd->bbl);
}
_sizing_eval(obj);
}
static Evas_Object *
_icon_unset(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
Evas_Object *icon;
if (!wd) return NULL;
if (!wd->icon) return NULL;
icon = wd->icon;
elm_widget_sub_object_del(obj, icon);
evas_object_event_callback_del_full(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_changed_size_hints, obj);
edje_object_part_unswallow(wd->bbl, icon);
wd->icon = NULL;
return icon;
}
static void
_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (!part || !strcmp(part, "default"))
_content_set(obj, content);
else if (!strcmp(part, "icon"))
_icon_set(obj, content);
}
static Evas_Object *
_content_get_hook(const Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
if (!part || !strcmp(part, "default"))
return wd->content;
else if (!strcmp(part, "icon"))
return wd->icon;
return NULL;
}
static Evas_Object *
_content_unset_hook(Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
if (!part || !strcmp(part, "default"))
return _content_unset(obj);
else if (!strcmp(part, "icon"))
return _icon_unset(obj);
return NULL;
}
static Eina_Bool
_elm_bubble_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
{
Widget_Data *wd = elm_widget_data_get(obj);
Evas_Object *cur;
if ((!wd) || (!wd->content))
return EINA_FALSE;
cur = wd->content;
/* Try Focus cycle in subitem */
return elm_widget_focus_next_get(cur, dir, next);
}
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;
ELM_BUBBLE_DATA_GET(obj, sd);
if (!wd) return;
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
edje_object_size_min_restricted_calc
(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh);
edje_object_size_min_restricted_calc(wd->bbl, &minw, &minh, minw, minh);
evas_object_size_hint_min_set(obj, minw, minh);
evas_object_size_hint_max_set(obj, maxw, maxh);
}
/* overriding layout's focus_next() in order to just cycle through the
* content's tree */
static Eina_Bool
_elm_bubble_smart_focus_next(const Evas_Object *obj,
Elm_Focus_Direction dir,
Evas_Object **next)
static void
_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
Evas_Object *content;
content = elm_layout_content_get(obj, NULL);
if (!content) return EINA_FALSE;
/* attempt to follow focus cycle into sub-object */
return elm_widget_focus_next_get(content, dir, next);
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return;
_sizing_eval(data);
}
static void
_on_mouse_up(void *data,
Evas *e __UNUSED__,
Evas_Object *obj __UNUSED__,
void *event_info)
_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)
{
edje_object_signal_emit(wd->bbl, "elm,state,icon,hidden", "elm");
wd->icon = NULL;
edje_object_message_signal_process(wd->bbl);
}
_sizing_eval(obj);
}
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, SIG_CLICKED, NULL);
}
static Eina_Bool
_elm_bubble_smart_text_set(Evas_Object *obj,
const char *item,
const char *label)
static void
_elm_bubble_label_set(Evas_Object *obj, const char *item, const char *label)
{
if (!_elm_bubble_parent_sc->text_set(obj, item, label)) return EINA_FALSE;
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (item && (!strcmp(item, "info") || !strcmp(item, "elm.info")))
if (!item || !strcmp(item, "default"))
{
if (label)
elm_layout_signal_emit(obj, "elm,state,info,visible", "elm");
else
elm_layout_signal_emit(obj, "elm,state,info,hidden", "elm");
eina_stringshare_replace(&wd->label, label);
edje_object_part_text_escaped_set(wd->bbl, "elm.text", label);
if (label) edje_object_signal_emit(wd->bbl, "elm,state,text,visible",
"elm");
else edje_object_signal_emit(wd->bbl, "elm,state,text,hidden", "elm");
_sizing_eval(obj);
}
else if (!strcmp(item, "info"))
{
eina_stringshare_replace(&wd->info, label);
edje_object_part_text_escaped_set(wd->bbl, "elm.info", label);
if (label) edje_object_signal_emit(wd->bbl, "elm,state,info,visible",
"elm");
else edje_object_signal_emit(wd->bbl, "elm,state,info,hidden", "elm");
_sizing_eval(obj);
}
}
static const char*
_elm_bubble_label_get(const Evas_Object *obj, const char *item)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
if (!item || !strcmp(item, "default"))
{
return wd->label;
}
else if (!strcmp(item, "info"))
{
return wd->info;
}
elm_layout_sizing_eval(obj);
return EINA_TRUE;
}
static void
_elm_bubble_smart_add(Evas_Object *obj)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Bubble_Smart_Data);
ELM_WIDGET_CLASS(_elm_bubble_parent_sc)->base.add(obj);
priv->pos = ELM_BUBBLE_POS_TOP_LEFT; //default
elm_widget_can_focus_set(obj, EINA_FALSE);
evas_object_event_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, EVAS_CALLBACK_MOUSE_UP,
_on_mouse_up, obj);
elm_layout_theme_set(obj, "bubble", "base", elm_widget_style_get(obj));
}
static void
_elm_bubble_smart_set_user(Elm_Layout_Smart_Class *sc)
{
ELM_WIDGET_CLASS(sc)->base.add = _elm_bubble_smart_add;
ELM_WIDGET_CLASS(sc)->focus_next = _elm_bubble_smart_focus_next;
sc->text_set = _elm_bubble_smart_text_set;
sc->sizing_eval = _elm_bubble_smart_sizing_eval;
sc->content_aliases = _content_aliases;
sc->text_aliases = _text_aliases;
return NULL;
}
EAPI Evas_Object *
elm_bubble_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
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);
elm_widget_focus_next_hook_set(obj, _elm_bubble_focus_next_hook);
elm_widget_can_focus_set(obj, EINA_FALSE);
elm_widget_text_set_hook_set(obj, _elm_bubble_label_set);
elm_widget_text_get_hook_set(obj, _elm_bubble_label_get);
elm_widget_content_set_hook_set(obj, _content_set_hook);
elm_widget_content_get_hook_set(obj, _content_get_hook);
elm_widget_content_unset_hook_set(obj, _content_unset_hook);
obj = evas_object_smart_add(e, _elm_bubble_smart_class_new());
wd->corner = eina_stringshare_add("base");
wd->pos = ELM_BUBBLE_POS_TOP_LEFT; //default
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
wd->bbl = edje_object_add(e);
elm_widget_resize_object_set(obj, wd->bbl);
elm_layout_sizing_eval(obj);
evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
evas_object_event_callback_add(wd->bbl, EVAS_CALLBACK_MOUSE_UP,
_mouse_up, obj);
evas_object_smart_callbacks_descriptions_set(obj, _signals);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_elm_theme_object_set(obj, wd->bbl, "bubble", wd->corner,
elm_widget_style_get(obj));
_sizing_eval(obj);
return obj;
}
EAPI void
elm_bubble_pos_set(Evas_Object *obj,
Elm_Bubble_Pos pos)
elm_bubble_pos_set(Evas_Object *obj, Elm_Bubble_Pos pos)
{
ELM_BUBBLE_CHECK(obj);
ELM_BUBBLE_DATA_GET_OR_RETURN(obj, sd);
if (pos < ELM_BUBBLE_POS_TOP_LEFT || pos > ELM_BUBBLE_POS_BOTTOM_RIGHT)
return;
sd->pos = pos;
eina_stringshare_replace
(&(ELM_LAYOUT_DATA(sd)->group), corner_string[sd->pos]);
ELM_WIDGET_DATA(sd)->api->theme(obj);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (pos<ELM_BUBBLE_POS_TOP_LEFT || pos>ELM_BUBBLE_POS_BOTTOM_RIGHT) return;
wd->pos = pos;
_theme_hook(obj);
}
EAPI Elm_Bubble_Pos
elm_bubble_pos_get(const Evas_Object *obj)
{
ELM_BUBBLE_CHECK(obj) ELM_BUBBLE_POS_INVALID;
ELM_BUBBLE_DATA_GET_OR_RETURN_VAL(obj, sd, ELM_BUBBLE_POS_INVALID);
return sd->pos;
ELM_CHECK_WIDTYPE(obj, widtype) ELM_BUBBLE_POS_INVALID;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return ELM_BUBBLE_POS_INVALID;
return wd->pos;
}

View File

@ -29,12 +29,8 @@
* @li "bottom_left"
* @li "bottom_right"
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for bubble objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* @li @c "clicked" - This is called when a user has clicked the bubble.
* Signals that you can add callbacks for are:
* @li "clicked" - This is called when a user has clicked the bubble.
*
* Default content parts of the bubble that you can use for are:
* @li "default" - A content of the bubble

View File

@ -1,88 +1,287 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_button.h"
static const char BUTTON_SMART_NAME[] = "elm_button";
typedef struct _Widget_Data Widget_Data;
struct _Widget_Data
{
Evas_Object *btn, *icon;
const char *label;
double ar_threshold;
double ar_interval;
Ecore_Timer *timer;
Eina_Bool autorepeat : 1;
Eina_Bool repeating : 1;
Eina_Bool delete_me : 1;
};
static const char *widtype = NULL;
static void _del_hook(Evas_Object *obj);
static void _del_pre_hook(Evas_Object *obj);
static void _theme_hook(Evas_Object *obj);
static void _disable_hook(Evas_Object *obj);
static void _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content);
static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *part);
static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part);
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 _activate(Evas_Object *obj);
static void _activate_hook(Evas_Object *obj);
static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src,
Evas_Callback_Type type, void *event_info);
static const char SIG_CLICKED[] = "clicked";
static const char SIG_REPEATED[] = "repeated";
static const char SIG_PRESSED[] = "pressed";
static const char SIG_UNPRESSED[] = "unpressed";
static const Evas_Smart_Cb_Description _signals[] = {
{SIG_CLICKED, ""},
{SIG_REPEATED, ""},
{SIG_PRESSED, ""},
{SIG_UNPRESSED, ""},
{NULL, NULL}
};
#define ELM_BUTTON_DATA_GET(o, sd) \
Elm_Button_Smart_Data * sd = evas_object_smart_data_get(o)
#define ELM_BUTTON_DATA_GET_OR_RETURN(o, ptr) \
ELM_BUTTON_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define ELM_BUTTON_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_BUTTON_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_BUTTON_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), BUTTON_SMART_NAME, __func__)) \
return
static const Elm_Layout_Part_Alias_Description _content_aliases[] =
static Eina_Bool
_event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info)
{
{"icon", "elm.swallow.icon"},
{NULL, NULL}
};
if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
Evas_Event_Key_Down *ev = event_info;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
if (elm_widget_disabled_get(obj)) return EINA_FALSE;
if ((strcmp(ev->keyname, "Return")) &&
(strcmp(ev->keyname, "KP_Enter")) &&
(strcmp(ev->keyname, "space")))
return EINA_FALSE;
_activate(obj);
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
edje_object_signal_emit(wd->btn, "elm,anim,activate", "elm");
return EINA_TRUE;
}
static const Elm_Layout_Part_Alias_Description _text_aliases[] =
static void
_del_pre_hook(Evas_Object *obj)
{
{"default", "elm.text"},
{NULL, NULL}
};
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
wd->delete_me = EINA_TRUE;
}
/* no *direct* instantiation of this class, so far */
__UNUSED__ static Evas_Smart *_elm_button_smart_class_new(void);
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);
}
/* smart callbacks coming from elm button objects (besides the ones
* coming from elm layout): */
static const Evas_Smart_Cb_Description _smart_callbacks[] = {
{SIG_CLICKED, ""},
{SIG_REPEATED, ""},
{SIG_PRESSED, ""},
{SIG_UNPRESSED, ""},
{NULL, NULL}
};
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, EINA_TRUE);
}
else
{
edje_object_signal_emit(wd->btn, "elm,action,unfocus", "elm");
evas_object_focus_set(wd->btn, EINA_FALSE);
}
}
/* Inheriting from elm_layout. Besides, we need no more than what is
* there */
EVAS_SMART_SUBCLASS_NEW
(BUTTON_SMART_NAME, _elm_button, Elm_Button_Smart_Class,
Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks);
static void
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
edje_object_mirrored_set(wd->btn, rtl);
}
static void
_theme_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
const char *str;
if (!wd) return;
_elm_widget_mirrored_reload(obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_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_escaped_set(wd->btn, "elm.text", wd->label);
if (elm_object_disabled_get(obj))
edje_object_signal_emit(wd->btn, "elm,state,disabled", "elm");
edje_object_message_signal_process(wd->btn);
edje_object_scale_set(wd->btn, elm_widget_scale_get(obj) * _elm_config->scale);
str = edje_object_data_get(wd->btn, "focus_highlight");
if ((str) && (!strcmp(str, "on")))
elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
else
elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
_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
_signal_emit_hook(Evas_Object *obj, const char *emission, const char *source)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
edje_object_signal_emit(wd->btn, emission, source);
}
static void
_signal_callback_add_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
edje_object_signal_callback_add(wd->btn, emission, source, func_cb, data);
}
static void
_signal_callback_del_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data)
{
Widget_Data *wd = elm_widget_data_get(obj);
edje_object_signal_callback_del_full(wd->btn, emission, source, func_cb,
data);
}
static void
_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (part && strcmp(part, "icon")) return;
if (wd->icon == content) return;
if (wd->icon) evas_object_del(wd->icon);
wd->icon = 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->btn, "elm.swallow.content", content);
edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm");
edje_object_message_signal_process(wd->btn);
}
_sizing_eval(obj);
}
static Evas_Object *
_content_get_hook(const Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd;
if (part && strcmp(part, "icon")) return NULL;
wd = elm_widget_data_get(obj);
if (!wd) return NULL;
return wd->icon;
}
static Evas_Object *
_content_unset_hook(Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd;
if (part && strcmp(part, "icon")) return NULL;
wd = elm_widget_data_get(obj);
if (!wd) return NULL;
if (!wd->icon) return NULL;
Evas_Object *icon = wd->icon;
elm_widget_sub_object_del(obj, wd->icon);
edje_object_part_unswallow(wd->btn, icon);
return icon;
}
static void
_sizing_eval(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
Evas_Coord minw = -1, minh = -1;
if (!wd) return;
if (wd->delete_me) 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);
}
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
_activate(Evas_Object *obj)
{
ELM_BUTTON_DATA_GET_OR_RETURN(obj, sd);
if (sd->timer)
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->timer)
{
ecore_timer_del(sd->timer);
sd->timer = NULL;
ecore_timer_del(wd->timer);
wd->timer = NULL;
}
sd->repeating = EINA_FALSE;
wd->repeating = EINA_FALSE;
if ((_elm_config->access_mode == ELM_ACCESS_MODE_OFF) ||
(_elm_access_2nd_click_timeout(obj)))
{
if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
_elm_access_say(E_("Clicked"));
_elm_access_say(E_("Clicked"));
if (!elm_widget_disabled_get(obj) &&
!evas_object_freeze_events_get(obj))
evas_object_smart_callback_call(obj, SIG_CLICKED, NULL);
@ -90,49 +289,13 @@ _activate(Evas_Object *obj)
}
static void
_elm_button_smart_sizing_eval(Evas_Object *obj)
_activate_hook(Evas_Object *obj)
{
Evas_Coord minw = -1, minh = -1;
ELM_BUTTON_DATA_GET(obj, sd);
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
edje_object_size_min_restricted_calc
(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh);
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
evas_object_size_hint_min_set(obj, minw, minh);
}
static Eina_Bool
_elm_button_smart_event(Evas_Object *obj,
Evas_Object *src __UNUSED__,
Evas_Callback_Type type,
void *event_info)
{
Evas_Event_Key_Down *ev = event_info;
if (elm_widget_disabled_get(obj)) return EINA_FALSE;
if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
if ((strcmp(ev->keyname, "Return")) &&
(strcmp(ev->keyname, "KP_Enter")) &&
(strcmp(ev->keyname, "space")))
return EINA_FALSE;
_activate(obj);
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
elm_layout_signal_emit(obj, "elm,anim,activate", "elm");
return EINA_TRUE;
}
static void
_on_clicked_signal(void *data,
Evas_Object *obj __UNUSED__,
const char *emission __UNUSED__,
const char *source __UNUSED__)
_signal_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
_activate(data);
}
@ -140,12 +303,13 @@ _on_clicked_signal(void *data,
static Eina_Bool
_autorepeat_send(void *data)
{
ELM_BUTTON_DATA_GET_OR_RETURN_VAL(data, sd, ECORE_CALLBACK_CANCEL);
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return ECORE_CALLBACK_CANCEL;
evas_object_smart_callback_call(data, SIG_REPEATED, NULL);
if (!sd->repeating)
if (!wd->repeating)
{
sd->timer = NULL;
wd->timer = NULL;
return ECORE_CALLBACK_CANCEL;
}
@ -155,252 +319,216 @@ _autorepeat_send(void *data)
static Eina_Bool
_autorepeat_initial_send(void *data)
{
ELM_BUTTON_DATA_GET_OR_RETURN_VAL(data, sd, ECORE_CALLBACK_CANCEL);
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return ECORE_CALLBACK_CANCEL;
if (sd->timer) ecore_timer_del(sd->timer);
sd->repeating = EINA_TRUE;
if (wd->timer) ecore_timer_del(wd->timer);
wd->repeating = EINA_TRUE;
_autorepeat_send(data);
sd->timer = ecore_timer_add(sd->ar_interval, _autorepeat_send, data);
wd->timer = ecore_timer_add(wd->ar_interval, _autorepeat_send, data);
return ECORE_CALLBACK_CANCEL;
}
static void
_on_pressed_signal(void *data,
Evas_Object *obj __UNUSED__,
const char *emission __UNUSED__,
const char *source __UNUSED__)
_signal_pressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
ELM_BUTTON_DATA_GET_OR_RETURN(data, sd);
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return;
if ((sd->autorepeat) && (!sd->repeating))
if ((wd->autorepeat) && (!wd->repeating))
{
if (sd->ar_threshold <= 0.0)
_autorepeat_initial_send(data); /* call immediately */
if (wd->ar_threshold <= 0.0)
_autorepeat_initial_send(data); /* call immediately */
else
sd->timer = ecore_timer_add
(sd->ar_threshold, _autorepeat_initial_send, data);
wd->timer = ecore_timer_add(wd->ar_threshold, _autorepeat_initial_send, data);
}
evas_object_smart_callback_call(data, SIG_PRESSED, NULL);
}
static void
_on_unpressed_signal(void *data,
Evas_Object *obj __UNUSED__,
const char *emission __UNUSED__,
const char *source __UNUSED__)
_signal_unpressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
ELM_BUTTON_DATA_GET_OR_RETURN(data, sd);
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return;
if (sd->timer)
if (wd->timer)
{
ecore_timer_del(sd->timer);
sd->timer = NULL;
ecore_timer_del(wd->timer);
wd->timer = NULL;
}
sd->repeating = EINA_FALSE;
wd->repeating = EINA_FALSE;
evas_object_smart_callback_call(data, SIG_UNPRESSED, NULL);
}
static void
_elm_button_label_set(Evas_Object *obj, const char *item, const char *label)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (item && strcmp(item, "default")) return;
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_escaped_set(wd->btn, "elm.text", label);
_sizing_eval(obj);
}
static const char *
_elm_button_label_get(const Evas_Object *obj, const char *item)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (item && strcmp(item, "default")) return NULL;
if (!wd) return NULL;
return wd->label;
}
static char *
_access_info_cb(void *data __UNUSED__,
Evas_Object *obj,
Elm_Widget_Item *item __UNUSED__)
_access_info_cb(void *data __UNUSED__, Evas_Object *obj, Elm_Widget_Item *item __UNUSED__)
{
const char *txt = elm_widget_access_info_get(obj);
if (!txt) txt = elm_layout_text_get(obj, NULL);
if (!txt) txt = _elm_button_label_get(obj, NULL);
if (txt) return strdup(txt);
return NULL;
}
static char *
_access_state_cb(void *data __UNUSED__,
Evas_Object *obj,
Elm_Widget_Item *item __UNUSED__)
_access_state_cb(void *data __UNUSED__, Evas_Object *obj, Elm_Widget_Item *item __UNUSED__)
{
if (elm_widget_disabled_get(obj))
return strdup(E_("State: Disabled"));
return NULL;
}
static void
_elm_button_smart_add(Evas_Object *obj)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Button_Smart_Data);
ELM_WIDGET_CLASS(_elm_button_parent_sc)->base.add(obj);
edje_object_signal_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,click", "",
_on_clicked_signal, obj);
edje_object_signal_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,press", "",
_on_pressed_signal, obj);
edje_object_signal_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,unpress", "",
_on_unpressed_signal, obj);
_elm_access_object_register(obj, ELM_WIDGET_DATA(priv)->resize_obj);
_elm_access_text_set
(_elm_access_object_get(obj), ELM_ACCESS_TYPE, E_("Button"));
_elm_access_callback_set
(_elm_access_object_get(obj), ELM_ACCESS_INFO, _access_info_cb, NULL);
_elm_access_callback_set
(_elm_access_object_get(obj), ELM_ACCESS_STATE, _access_state_cb, priv);
elm_widget_can_focus_set(obj, EINA_TRUE);
elm_layout_theme_set(obj, "button", "base", elm_widget_style_get(obj));
}
static void
_elm_button_smart_set_user(Elm_Button_Smart_Class *sc)
{
ELM_WIDGET_CLASS(sc)->base.add = _elm_button_smart_add;
ELM_WIDGET_CLASS(sc)->event = _elm_button_smart_event;
ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */
ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_button_smart_sizing_eval;
ELM_LAYOUT_CLASS(sc)->content_aliases = _content_aliases;
ELM_LAYOUT_CLASS(sc)->text_aliases = _text_aliases;
}
EAPI const Elm_Button_Smart_Class *
elm_button_smart_class_get(void)
{
static Elm_Button_Smart_Class _sc =
ELM_BUTTON_SMART_CLASS_INIT_NAME_VERSION(BUTTON_SMART_NAME);
static const Elm_Button_Smart_Class *class = NULL;
if (class) return class;
_elm_button_smart_set(&_sc);
class = &_sc;
return class;
}
/* new class here just to take advantage of
* ELM_BUTTON_SMART_CLASS_INIT() macro, which sets auto-repeat capability */
EVAS_SMART_SUBCLASS_NEW
(BUTTON_SMART_NAME, _elm_button_widget, Elm_Button_Smart_Class,
Elm_Button_Smart_Class, elm_button_smart_class_get, NULL);
static void
_elm_button_widget_smart_set_user(Elm_Button_Smart_Class *sc __UNUSED__)
{
/* NOP: declared because it's obligatory for Evas macro */
}
EAPI Evas_Object *
elm_button_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
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_del_pre_hook_set(obj, _del_pre_hook);
elm_widget_theme_hook_set(obj, _theme_hook);
elm_widget_disable_hook_set(obj, _disable_hook);
elm_widget_can_focus_set(obj, EINA_TRUE);
elm_widget_activate_hook_set(obj, _activate_hook);
elm_widget_event_hook_set(obj, _event_hook);
elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook);
elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook);
elm_widget_text_set_hook_set(obj, _elm_button_label_set);
elm_widget_text_get_hook_set(obj, _elm_button_label_get);
elm_widget_content_set_hook_set(obj, _content_set_hook);
elm_widget_content_get_hook_set(obj, _content_get_hook);
elm_widget_content_unset_hook_set(obj, _content_unset_hook);
obj = evas_object_smart_add(e, _elm_button_widget_smart_class_new());
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);
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
_theme_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);
_elm_access_object_register(obj, wd->btn);
_elm_access_text_set(_elm_access_object_get(obj),
ELM_ACCESS_TYPE, E_("Button"));
_elm_access_callback_set(_elm_access_object_get(obj),
ELM_ACCESS_INFO, _access_info_cb, obj);
_elm_access_callback_set(_elm_access_object_get(obj),
ELM_ACCESS_STATE, _access_state_cb, obj);
return obj;
}
EAPI void
elm_button_autorepeat_set(Evas_Object *obj,
Eina_Bool on)
elm_button_autorepeat_set(Evas_Object *obj, Eina_Bool on)
{
ELM_BUTTON_CHECK(obj);
ELM_BUTTON_DATA_GET_OR_RETURN(obj, sd);
if (sd->timer)
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->timer)
{
ecore_timer_del(sd->timer);
sd->timer = NULL;
ecore_timer_del(wd->timer);
wd->timer = NULL;
}
sd->autorepeat = on;
sd->repeating = EINA_FALSE;
wd->autorepeat = on;
wd->repeating = EINA_FALSE;
}
#define _AR_CAPABLE(_sd) \
(ELM_BUTTON_CLASS(ELM_WIDGET_DATA(_sd)->api)->admits_autorepeat)
EAPI Eina_Bool
elm_button_autorepeat_get(const Evas_Object *obj)
{
ELM_BUTTON_CHECK(obj) EINA_FALSE;
ELM_BUTTON_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE);
return _AR_CAPABLE(sd) & sd->autorepeat;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->autorepeat;
}
EAPI void
elm_button_autorepeat_initial_timeout_set(Evas_Object *obj,
double t)
elm_button_autorepeat_initial_timeout_set(Evas_Object *obj, double t)
{
ELM_BUTTON_CHECK(obj);
ELM_BUTTON_DATA_GET_OR_RETURN(obj, sd);
if (!_AR_CAPABLE(sd))
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)
{
ERR("this widget does not support auto repetition of clicks.");
return;
ecore_timer_del(wd->timer);
wd->timer = NULL;
}
if (sd->ar_threshold == t) return;
if (sd->timer)
{
ecore_timer_del(sd->timer);
sd->timer = NULL;
}
sd->ar_threshold = t;
wd->ar_threshold = t;
}
EAPI double
elm_button_autorepeat_initial_timeout_get(const Evas_Object *obj)
{
ELM_BUTTON_CHECK(obj) 0.0;
ELM_BUTTON_DATA_GET_OR_RETURN_VAL(obj, sd, 0.0);
if (!_AR_CAPABLE(sd)) return 0.0;
return sd->ar_threshold;
ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return 0.0;
return wd->ar_threshold;
}
EAPI void
elm_button_autorepeat_gap_timeout_set(Evas_Object *obj,
double t)
elm_button_autorepeat_gap_timeout_set(Evas_Object *obj, double t)
{
ELM_BUTTON_CHECK(obj);
ELM_BUTTON_DATA_GET_OR_RETURN(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->ar_interval == t) return;
if (!_AR_CAPABLE(sd))
{
ERR("this widget does not support auto repetition of clicks.");
return;
}
if (sd->ar_interval == t) return;
sd->ar_interval = t;
if ((sd->repeating) && (sd->timer)) ecore_timer_interval_set(sd->timer, t);
wd->ar_interval = t;
if ((wd->repeating) && (wd->timer)) ecore_timer_interval_set(wd->timer, t);
}
EAPI double
elm_button_autorepeat_gap_timeout_get(const Evas_Object *obj)
{
ELM_BUTTON_CHECK(obj) 0.0;
ELM_BUTTON_DATA_GET_OR_RETURN_VAL(obj, sd, 0.0);
return sd->ar_interval;
ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return 0.0;
return wd->ar_interval;
}

View File

@ -12,11 +12,7 @@
* This is a push-button. Press it and run some function. It can contain
* a simple label and icon object and it also has an autorepeat feature.
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for button objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* This widget emits the following signals:
* @li "clicked": the user clicked the button (press/release).
* @li "repeated": the user pressed the button without releasing it.
* @li "pressed": button was pressed.

File diff suppressed because it is too large Load Diff

View File

@ -2,23 +2,17 @@
* @defgroup Calendar Calendar
* @ingroup Elementary
*
* This is a calendar widget. It helps applications to flexibly
* display a calender with day of the week, date, year and
* month. Applications are able to set specific dates to be reported
* back, when selected, in the smart callbacks of the calendar
* widget. The API of this widget lets the applications perform other
* functions, like:
* This is a Calendar widget. Calender widget helps applications to flexibly
* display a calender with day of the week, day, year and month. Applications will be
* able to choose a specific date that will be reported in the smart_callbacks for
* the calendar widget. The APIs of calendar widget let the applications perform
* other functions like,
* placing marks on specific dates
* Setting the bounds for the calendar (minimum and maximum years)
* Setting the day names of the week. ( for ex. Thu. or Thursday)
* Setting the year and month format.
*
* - placing marks on specific dates
* - setting the bounds for the calendar (minimum and maximum years)
* - setting the day names of the week (e.g. "Thu" or "Thursday")
* - setting the year and month format.
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for calendar objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* Signals that you can add callbacks for are:
* - @c "changed" - emitted when the date in the calendar is changed.
*
* Supported elm_object common APIs.

View File

@ -1,375 +1,518 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_layout.h"
static const char CHECK_SMART_NAME[] = "elm_check";
typedef struct _Widget_Data Widget_Data;
typedef struct _Elm_Check_Smart_Data Elm_Check_Smart_Data;
struct _Elm_Check_Smart_Data
struct _Widget_Data
{
Elm_Layout_Smart_Data base;
Eina_Bool state;
Eina_Bool *statep;
};
#define ELM_CHECK_DATA_GET(o, sd) \
Elm_Check_Smart_Data * sd = evas_object_smart_data_get(o)
#define ELM_CHECK_DATA_GET_OR_RETURN(o, ptr) \
ELM_CHECK_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define ELM_CHECK_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_CHECK_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_CHECK_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), CHECK_SMART_NAME, __func__)) \
return
static const Elm_Layout_Part_Alias_Description _content_aliases[] =
{
{"icon", "elm.swallow.icon"},
{NULL, NULL}
};
static const Elm_Layout_Part_Alias_Description _text_aliases[] =
{
{"default", "elm.text"},
{"on", "elm.ontext"},
{"off", "elm.offtext"},
{NULL, NULL}
Evas_Object *chk, *icon;
Eina_Bool state;
Eina_Bool *statep;
const char *label;
const char *ontext, *offtext;
};
static const char *widtype = NULL;
static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src,
Evas_Callback_Type type, void *event_info);
static void _del_hook(Evas_Object *obj);
static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
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 void _on_focus_hook(void *data, Evas_Object *obj);
static void _activate_hook(Evas_Object *obj);
static void _content_set_hook(Evas_Object *obj, const char *part,
Evas_Object *content);
static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *part);
static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part);
static void _activate(Evas_Object *obj);
static const char SIG_CHANGED[] = "changed";
/* smart callbacks coming from elm check objects: */
static const Evas_Smart_Cb_Description _smart_callbacks[] = {
{SIG_CHANGED, ""},
{NULL, NULL}
static const Evas_Smart_Cb_Description _signals[] = {
{SIG_CHANGED, ""},
{NULL, NULL}
};
/* Inheriting from elm_layout. Besides, we need no more than what is
* there */
EVAS_SMART_SUBCLASS_NEW
(CHECK_SMART_NAME, _elm_check, Elm_Layout_Smart_Class,
Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks);
static void
_activate(Evas_Object *obj)
{
ELM_CHECK_DATA_GET(obj, sd);
if ((_elm_config->access_mode != ELM_ACCESS_MODE_OFF) &&
(!_elm_access_2nd_click_timeout(obj)))
return;
sd->state = !sd->state;
if (sd->statep) *sd->statep = sd->state;
if (sd->state)
{
elm_layout_signal_emit(obj, "elm,state,check,on", "elm");
if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
{
if (!elm_layout_text_get(obj, "on"))
{
_elm_access_say(E_("State: On"));
}
else
_elm_access_say(E_("State: On"));
}
}
else
{
elm_layout_signal_emit(obj, "elm,state,check,off", "elm");
if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
{
if (!elm_layout_text_get(obj, "off"))
{
_elm_access_say(E_("State: Off"));
}
else
_elm_access_say(E_("State: Off"));
}
}
evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);
}
static Eina_Bool
_elm_check_smart_event(Evas_Object *obj,
Evas_Object *src __UNUSED__,
Evas_Callback_Type type,
void *event_info)
_event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__,
Evas_Callback_Type type, void *event_info)
{
Evas_Event_Key_Down *ev = event_info;
if (elm_widget_disabled_get(obj)) return EINA_FALSE;
if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
Evas_Event_Key_Down *ev = event_info;
if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
if (elm_widget_disabled_get(obj)) return EINA_FALSE;
if ((strcmp(ev->keyname, "Return")) &&
(strcmp(ev->keyname, "KP_Enter")) &&
(strcmp(ev->keyname, "space")))
return EINA_FALSE;
_activate(obj);
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
return EINA_TRUE;
}
static void
_elm_check_smart_sizing_eval(Evas_Object *obj)
_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
_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->chk, "elm,action,focus", "elm");
evas_object_focus_set(wd->chk, EINA_TRUE);
}
else
{
edje_object_signal_emit(wd->chk, "elm,action,unfocus", "elm");
evas_object_focus_set(wd->chk, EINA_FALSE);
}
}
static void
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
edje_object_mirrored_set(wd->chk, rtl);
}
static void
_theme_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
_elm_widget_mirrored_reload(obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_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_escaped_set(wd->chk, "elm.text", wd->label);
edje_object_part_text_escaped_set(wd->chk, "elm.ontext", wd->ontext);
edje_object_part_text_escaped_set(wd->chk, "elm.offtext", wd->offtext);
if (elm_widget_disabled_get(obj))
edje_object_signal_emit(wd->chk, "elm,state,disabled", "elm");
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;
ELM_CHECK_DATA_GET(obj, sd);
if (!wd) return;
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
edje_object_size_min_restricted_calc
(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, 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 Eina_Bool
_elm_check_smart_theme(Evas_Object *obj)
static void
_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
ELM_CHECK_DATA_GET(obj, sd);
if (!ELM_WIDGET_CLASS(_elm_check_parent_sc)->theme(obj)) return EINA_FALSE;
if (!sd->state) elm_layout_signal_emit(obj, "elm,state,check,off", "elm");
else elm_layout_signal_emit(obj, "elm,state,check,on", "elm");
edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
elm_layout_sizing_eval(obj);
return EINA_TRUE;
}
static char *
_access_info_cb(void *data __UNUSED__,
Evas_Object *obj,
Elm_Widget_Item *item __UNUSED__)
{
const char *txt = elm_widget_access_info_get(obj);
if (!txt) txt = elm_layout_text_get(obj, NULL);
if (txt) return strdup(txt);
return NULL;
}
static char *
_access_state_cb(void *data,
Evas_Object *obj,
Elm_Widget_Item *item __UNUSED__)
{
Elm_Check_Smart_Data *sd = data;
const char *on_text, *off_text;
if (elm_widget_disabled_get(obj))
return strdup(E_("State: Disabled"));
if (sd->state)
{
on_text = elm_layout_text_get(ELM_WIDGET_DATA(sd)->obj, "on");
if (on_text)
{
char buf[1024];
snprintf(buf, sizeof(buf), "%s: %s", E_("State"), on_text);
return strdup(buf);
}
else
return strdup(E_("State: On"));
}
off_text = elm_layout_text_get(ELM_WIDGET_DATA(sd)->obj, "off");
if (off_text)
{
char buf[1024];
snprintf(buf, sizeof(buf), "%s: %s", E_("State"), off_text);
return strdup(buf);
}
return strdup(E_("State: Off"));
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return;
if (obj != wd->icon) return;
_sizing_eval(data);
}
static void
_on_check_off(void *data,
Evas_Object *o __UNUSED__,
const char *emission __UNUSED__,
const char *source __UNUSED__)
_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
{
Evas_Object *obj = data;
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);
edje_object_message_signal_process(wd->chk);
}
}
ELM_CHECK_DATA_GET(obj, sd);
sd->state = EINA_FALSE;
if (sd->statep) *sd->statep = sd->state;
elm_layout_signal_emit(obj, "elm,state,check,off", "elm");
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
_on_check_on(void *data,
Evas_Object *o __UNUSED__,
const char *emission __UNUSED__,
const char *source __UNUSED__)
_signal_check_on(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
Evas_Object *obj = data;
ELM_CHECK_DATA_GET(obj, sd);
sd->state = EINA_TRUE;
if (sd->statep) *sd->statep = sd->state;
elm_layout_signal_emit(obj, "elm,state,check,on", "elm");
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
_on_check_toggle(void *data,
Evas_Object *o __UNUSED__,
const char *emission __UNUSED__,
const char *source __UNUSED__)
_signal_check_toggle(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
_activate(data);
}
static void
_elm_check_smart_add(Evas_Object *obj)
_activate_hook(Evas_Object *obj)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Check_Smart_Data);
ELM_WIDGET_CLASS(_elm_check_parent_sc)->base.add(obj);
edje_object_signal_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,check,on", "",
_on_check_on, obj);
edje_object_signal_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,check,off", "",
_on_check_off, obj);
edje_object_signal_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,check,toggle", "",
_on_check_toggle, obj);
_elm_access_object_register(obj, ELM_WIDGET_DATA(priv)->resize_obj);
_elm_access_text_set
(_elm_access_object_get(obj), ELM_ACCESS_TYPE, E_("Check"));
_elm_access_callback_set
(_elm_access_object_get(obj), ELM_ACCESS_INFO, _access_info_cb, priv);
_elm_access_callback_set
(_elm_access_object_get(obj), ELM_ACCESS_STATE, _access_state_cb, priv);
elm_widget_can_focus_set(obj, EINA_TRUE);
_activate(obj);
}
static void
_elm_check_smart_set_user(Elm_Layout_Smart_Class *sc)
_signal_emit_hook(Evas_Object *obj, const char *emission, const char *source)
{
ELM_WIDGET_CLASS(sc)->base.add = _elm_check_smart_add;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
ELM_WIDGET_CLASS(sc)->theme = _elm_check_smart_theme;
ELM_WIDGET_CLASS(sc)->event = _elm_check_smart_event;
ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */
edje_object_signal_emit(wd->chk, emission, source);
}
sc->sizing_eval = _elm_check_smart_sizing_eval;
static void
_signal_callback_add_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
edje_object_signal_callback_add(wd->chk, emission, source, func_cb, data);
}
sc->content_aliases = _content_aliases;
sc->text_aliases = _text_aliases;
static void
_signal_callback_del_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data)
{
Widget_Data *wd = elm_widget_data_get(obj);
edje_object_signal_callback_del_full(wd->chk, emission, source, func_cb,
data);
}
static void
_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd;
if (part && strcmp(part, "icon")) return;
wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->icon == content) return;
if (wd->icon) evas_object_del(wd->icon);
wd->icon = 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->chk, "elm.swallow.content", content);
edje_object_signal_emit(wd->chk, "elm,state,icon,visible", "elm");
edje_object_message_signal_process(wd->chk);
}
_sizing_eval(obj);
}
static Evas_Object *
_content_get_hook(const Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd;
if (part && strcmp(part, "icon")) return NULL;
wd = elm_widget_data_get(obj);
if (!wd) return NULL;
return wd->icon;
}
static Evas_Object *
_content_unset_hook(Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd;
if (part && strcmp(part, "icon")) return NULL;
wd = elm_widget_data_get(obj);
if (!wd) return NULL;
if (!wd->icon) return NULL;
Evas_Object *icon = wd->icon;
elm_widget_sub_object_del(obj, wd->icon);
edje_object_part_unswallow(wd->chk, icon);
return icon;
}
static void
_activate(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if ((_elm_config->access_mode == ELM_ACCESS_MODE_OFF) ||
(_elm_access_2nd_click_timeout(obj)))
{
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");
if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
{
if (!wd->ontext)
{
_elm_access_say(E_("State: On"));
}
else
_elm_access_say(E_("State: On"));
}
}
else
{
edje_object_signal_emit(wd->chk, "elm,state,check,off", "elm");
if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
{
if (!wd->offtext)
{
_elm_access_say(E_("State: Off"));
}
else
_elm_access_say(E_("State: Off"));
}
}
evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);
}
}
static void
_elm_check_label_set(Evas_Object *obj, const char *item, const char *label)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if ((!item) || (!strcmp(item, "default")))
{
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_escaped_set(wd->chk, "elm.text", label);
}
else if ((item) && (!strcmp(item, "on")))
{
eina_stringshare_replace(&wd->ontext, label);
edje_object_part_text_escaped_set(wd->chk, "elm.ontext", wd->ontext);
}
else if ((item) && (!strcmp(item, "off")))
{
eina_stringshare_replace(&wd->offtext, label);
edje_object_part_text_escaped_set(wd->chk, "elm.offtext", wd->offtext);
}
_sizing_eval(obj);
}
static const char *
_elm_check_label_get(const Evas_Object *obj, const char *item)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
if ((!item) || (!strcmp(item, "default")))
return wd->label;
else if ((item) && (!strcmp(item, "on")))
return wd->ontext;
else if ((item) && (!strcmp(item, "off")))
return wd->offtext;
return NULL;
}
static char *
_access_info_cb(void *data __UNUSED__, Evas_Object *obj, Elm_Widget_Item *item __UNUSED__)
{
const char *txt = elm_widget_access_info_get(obj);
if (!txt) txt = _elm_check_label_get(obj, NULL);
if (txt) return strdup(txt);
return NULL;
}
static char *
_access_state_cb(void *data, Evas_Object *obj, Elm_Widget_Item *item __UNUSED__)
{
Evas_Object *o = data;
Widget_Data *wd = elm_widget_data_get(o);
if (!wd) return NULL;
if (elm_widget_disabled_get(obj))
return strdup(E_("State: Disabled"));
if (wd->state)
{
if (wd->ontext)
{
char buf[1024];
snprintf(buf, sizeof(buf), "%s: %s", E_("State"), wd->ontext);
return strdup(buf);
}
else
return strdup(E_("State: On"));
}
if (wd->offtext)
{
char buf[1024];
snprintf(buf, sizeof(buf), "%s: %s", E_("State"), wd->offtext);
return strdup(buf);
}
return strdup(E_("State: Off"));
}
EAPI Evas_Object *
elm_check_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
ELM_SET_WIDTYPE(widtype, "check");
elm_widget_type_set(obj, "check");
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, EINA_TRUE);
elm_widget_activate_hook_set(obj, _activate_hook);
elm_widget_event_hook_set(obj, _event_hook);
elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook);
elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook);
elm_widget_text_set_hook_set(obj, _elm_check_label_set);
elm_widget_text_get_hook_set(obj, _elm_check_label_get);
elm_widget_content_set_hook_set(obj, _content_set_hook);
elm_widget_content_get_hook_set(obj, _content_get_hook);
elm_widget_content_unset_hook_set(obj, _content_unset_hook);
obj = evas_object_smart_add(e, _elm_check_smart_class_new());
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);
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
elm_layout_theme_set(obj, "check", "base", elm_widget_style_get(obj));
elm_layout_sizing_eval(obj);
_mirrored_set(obj, elm_widget_mirrored_get(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);
_elm_access_object_register(obj, wd->chk);
_elm_access_text_set(_elm_access_object_get(obj),
ELM_ACCESS_TYPE, E_("Check"));
_elm_access_callback_set(_elm_access_object_get(obj),
ELM_ACCESS_INFO, _access_info_cb, obj);
_elm_access_callback_set(_elm_access_object_get(obj),
ELM_ACCESS_STATE, _access_state_cb, obj);
return obj;
}
EAPI void
elm_check_state_set(Evas_Object *obj,
Eina_Bool state)
elm_check_state_set(Evas_Object *obj, Eina_Bool state)
{
ELM_CHECK_CHECK(obj);
ELM_CHECK_DATA_GET(obj, sd);
if (state != sd->state)
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (state != wd->state)
{
sd->state = state;
if (sd->statep) *sd->statep = sd->state;
if (sd->state)
elm_layout_signal_emit(obj, "elm,state,check,on", "elm");
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
elm_layout_signal_emit(obj, "elm,state,check,off", "elm");
edje_object_signal_emit(wd->chk, "elm,state,check,off", "elm");
}
edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
edje_object_message_signal_process(wd->chk);
}
EAPI Eina_Bool
elm_check_state_get(const Evas_Object *obj)
{
ELM_CHECK_CHECK(obj) EINA_FALSE;
ELM_CHECK_DATA_GET(obj, sd);
return sd->state;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->state;
}
EAPI void
elm_check_state_pointer_set(Evas_Object *obj,
Eina_Bool *statep)
elm_check_state_pointer_set(Evas_Object *obj, Eina_Bool *statep)
{
ELM_CHECK_CHECK(obj);
ELM_CHECK_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (statep)
{
sd->statep = statep;
if (*sd->statep != sd->state)
wd->statep = statep;
if (*wd->statep != wd->state)
{
sd->state = *sd->statep;
if (sd->state)
elm_layout_signal_emit(obj, "elm,state,check,on", "elm");
wd->state = *wd->statep;
if (wd->state)
edje_object_signal_emit(wd->chk, "elm,state,check,on", "elm");
else
elm_layout_signal_emit(obj, "elm,state,check,off", "elm");
edje_object_signal_emit(wd->chk, "elm,state,check,off", "elm");
}
}
else
sd->statep = NULL;
wd->statep = NULL;
}

View File

@ -9,24 +9,20 @@
* @image html img/widget/check/preview-02.png
* @image latex img/widget/check/preview-02.eps
*
* @brief The check widget allows for toggling a value between true
* and false.
* @brief The check widget allows for toggling a value between true and
* false.
*
* 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 between false
* and true. elm_check_state_set() sets the boolean state 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.
* 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.
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for check objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* - @c "changed" - This is called whenever the user changes the state of
* the check objects (@c event_info is always @c NULL).
* Signals that you can add callbacks for are:
* "changed" - This is called whenever the user changes the state of the check
* objects(event_info is NULL).
*
* Default content parts of the check widget that you can use for are:
* @li "icon" - An icon of the check

File diff suppressed because it is too large Load Diff

View File

@ -30,12 +30,8 @@
* am/pm indicator may be optionally shown, too, when it will
* switch to 12h.
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for clock objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* - @c "changed" - the clock's user changed the time
* Smart callbacks one can register to:
* - "changed" - the clock's user changed the time
*
* Supported elm_object common APIs.
* @li @ref elm_object_signal_emit

File diff suppressed because it is too large Load Diff

View File

@ -5,26 +5,19 @@
* @image html img/widget/colorselector/preview-00.png
* @image latex img/widget/colorselector/preview-00.eps
*
* A ColorSelector is a color selection widget. It allows application
* to set a series of colors.It also allows to load/save colors
* from/to config with a unique identifier, by default, the colors are
* loaded/saved from/to config using "default" identifier. The colors
* can be picked by user from the color set by clicking on individual
* color item on the palette or by selecting it from selector.
* A ColorSelector is a color selection widget. It allows application to set a
* series of colors.It also allows to load/save colors from/to config with a
* unique identifier, by default, the colors are loaded/saved from/to config
* using "default" identifier.
* The colors can be picked by user from the color set by clicking on individual color
* item on the palette or by selecting it from selector.
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for check objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* - @c "changed" - When the color value changes on selector
* event_info is NULL.
* - @c "color,item,selected" - When user clicks on color item. The
* event_info parameter of the callback will be the selected color
* item.
* - @c "color,item,longpressed" - When user long presses on color
* item. The event info parameter of the callback contains selected
* color item.
* Signals that you can add callbacks for are:
* - "changed" - When the color value changes on selector(event_info is NULL).
* - "color,item,selected" - When user clicks on color item. The event_info parameter
* of the callback will be the selected color item.
* - "color,item,longpressed" - When user long presses on color item. The event info
* parameter of the callback contains selected color item.
*
* See @ref tutorial_colorselector.
* @{

View File

@ -1,39 +1,36 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_layout.h"
#ifndef MIN
# define MIN(a, b) ((a) < (b)) ? (a) : (b)
# define MIN(a,b) ((a) < (b)) ? (a) : (b)
#endif
#ifndef MAX
# define MAX(a, b) ((a) < (b)) ? (b) : (a)
# define MAX(a,b) ((a) < (b)) ? (b) : (a)
#endif
static const char CONFORM_SMART_NAME[] = "elm_conform";
typedef struct _Elm_Conform_Smart_Data Elm_Conform_Smart_Data;
struct _Elm_Conform_Smart_Data
typedef struct _Widget_Data Widget_Data;
struct _Widget_Data
{
Elm_Layout_Smart_Data base;
Evas_Object *indicator;
Evas_Object *softkey;
Evas_Object *virtualkeypad;
Evas_Object *clipboard;
Evas_Object *scroller;
Evas_Object *base;
Evas_Object *indicator;
Evas_Object *softkey;
Evas_Object *virtualkeypad;
Evas_Object *clipboard;
Evas_Object *content;
Evas_Object *scroller;
#ifdef HAVE_ELEMENTARY_X
Ecore_Event_Handler *prop_hdl;
Ecore_Event_Handler *prop_hdl;
Ecore_X_Virtual_Keyboard_State vkb_state;
#endif
struct
{
Ecore_Animator *animator; // animaton timer
double start; // time started
Evas_Coord auto_x, auto_y; // desired delta
Evas_Coord x, y; // current delta
double start; // time started
Evas_Coord auto_x, auto_y; // desired delta
Evas_Coord x, y; // current delta
} delta;
Ecore_Job *show_region_job;
Ecore_Job *show_region_job;
};
/* Enum to identify conformant swallow parts */
@ -48,58 +45,162 @@ enum _Conformant_Part_Type
#ifdef HAVE_ELEMENTARY_X
#define SUB_TYPE_COUNT 2
/* FIXME: change the smart names once those two are ported to new classes */
static char *sub_type[SUB_TYPE_COUNT] = { "scroller", "genlist" };
#endif
static const Elm_Layout_Part_Alias_Description _content_aliases[] =
/* local function prototypes */
static const char *widtype = NULL;
static void _del_pre_hook(Evas_Object *obj);
static void _del_hook(Evas_Object *obj);
static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
static void _theme_hook(Evas_Object *obj);
static void _content_set_hook(Evas_Object *obj,
const char *part,
Evas_Object *content);
static Evas_Object *_content_get_hook(const Evas_Object *obj,
const char *part);
static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part);
static void _swallow_conformant_parts(Evas_Object *obj);
static void _conformant_part_size_set(Evas_Object *obj,
Evas_Object *sobj,
Evas_Coord sx,
Evas_Coord sy,
Evas_Coord sw,
Evas_Coord sh);
static void _conformant_part_sizing_eval(Evas_Object *obj,
Conformant_Part_Type part_type);
static void _conformant_move_resize_event_cb(void *data,
Evas *e,
Evas_Object *obj,
void *event_info);
static void _sizing_eval(Evas_Object *obj);
static void _show_region_job(void *data);
static void _changed_size_hints(void *data, Evas *e,
Evas_Object *obj,
void *event_info);
/* local functions */
static void
_del_pre_hook(Evas_Object *obj)
{
{"icon", "elm.swallow.content"},
{NULL, NULL}
};
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
/* Inheriting from elm_layout. Besides, we need no more than what is
* there */
EVAS_SMART_SUBCLASS_NEW
(CONFORM_SMART_NAME, _elm_conform, Elm_Layout_Smart_Class,
Elm_Layout_Smart_Class, elm_layout_smart_class_get, NULL);
#ifdef HAVE_ELEMENTARY_X
if (wd->prop_hdl) ecore_event_handler_del(wd->prop_hdl);
#endif
}
#define ELM_CONFORM_DATA_GET(o, sd) \
Elm_Conform_Smart_Data * sd = evas_object_smart_data_get(o)
static void
_del_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
#define ELM_CONFORM_DATA_GET_OR_RETURN(o, ptr) \
ELM_CONFORM_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
if (wd->show_region_job) ecore_job_del(wd->show_region_job);
free(wd);
}
#define ELM_CONFORM_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_CONFORM_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
static void
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
#define ELM_CONFORM_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), CONFORM_SMART_NAME, __func__)) \
return
edje_object_mirrored_set(wd->base, rtl);
}
static void
_theme_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
_elm_widget_mirrored_reload(obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_elm_theme_object_set(obj, wd->base, "conformant", "base",
elm_widget_style_get(obj));
_swallow_conformant_parts(obj);
if (wd->content)
edje_object_part_swallow(wd->base, "elm.swallow.content", wd->content);
_sizing_eval(obj);
}
static void
_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd;
if (part && strcmp(part, "default")) return;
wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->content == content) return;
if (wd->content) evas_object_del(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);
}
static Evas_Object *
_content_get_hook(const Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd;
if (part && strcmp(part, "default")) return NULL;
wd = elm_widget_data_get(obj);
if (!wd) return NULL;
return wd->content;
}
static Evas_Object *
_content_unset_hook(Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd;
Evas_Object *content;
if (part && strcmp(part, "default")) return NULL;
wd = elm_widget_data_get(obj);
if ((!wd) || (!wd->content)) return NULL;
content = wd->content;
elm_widget_sub_object_del(obj, wd->content);
evas_object_event_callback_del_full(content,
EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_changed_size_hints, obj);
edje_object_part_unswallow(wd->base, content);
wd->content = NULL;
return content;
}
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);
}
/* Example of env vars:
* ILLUME_KBD="0, 0, 800, 301"
* ILLUME_IND="0, 0, 800, 32"
* ILLUME_STK="0, 568, 800, 32"
* ILLUME_IND=0,0,800,32
* ILLUME_STK="0,568,800,32
*/
static Eina_Bool
_conformant_part_geometry_get_from_env(const char *part,
int *sx,
int *sy,
int *sw,
int *sh)
_conformant_part_geometry_env_get(const char *part, int *sx, int *sy, int *sw, int *sh)
{
const char delimiters[] = " ,;";
char *env_val, *token;
@ -135,12 +236,8 @@ _conformant_part_geometry_get_from_env(const char *part,
}
static void
_conformant_part_size_hints_set(Evas_Object *obj,
Evas_Object *sobj,
Evas_Coord sx,
Evas_Coord sy,
Evas_Coord sw,
Evas_Coord sh)
_conformant_part_size_set(Evas_Object *obj, Evas_Object *sobj, Evas_Coord sx,
Evas_Coord sy, Evas_Coord sw, Evas_Coord sh)
{
Evas_Coord cx, cy, cw, ch;
Evas_Coord part_height = 0, part_width = 0;
@ -149,7 +246,7 @@ _conformant_part_size_hints_set(Evas_Object *obj,
/* Part overlapping with conformant */
if ((cx < (sx + sw)) && ((cx + cw) > sx)
&& (cy < (sy + sh)) && ((cy + ch) > sy))
&& (cy < (sy + sh)) && ((cy + ch) > sy))
{
part_height = MIN((cy + ch), (sy + sh)) - MAX(cy, sy);
part_width = MIN((cx + cw), (sx + sw)) - MAX(cx, sx);
@ -160,248 +257,270 @@ _conformant_part_size_hints_set(Evas_Object *obj,
}
static void
_conformant_part_sizing_eval(Evas_Object *obj,
Conformant_Part_Type part_type)
_conformant_part_sizing_eval(Evas_Object *obj, Conformant_Part_Type part_type)
{
#ifdef HAVE_ELEMENTARY_X
Ecore_X_Window zone = 0;
Evas_Object *top;
#endif
int sx = -1, sy = -1, sw = -1, sh = -1;
Ecore_X_Window xwin;
ELM_CONFORM_DATA_GET(obj, sd);
int sx = -1, sy = -1, sw = -1, sh = -1;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
#ifdef HAVE_ELEMENTARY_X
top = elm_widget_top_get(obj);
xwin = elm_win_xwindow_get(top);
if (xwin)
zone = ecore_x_e_illume_zone_get(xwin);
#endif
if (part_type & ELM_CONFORM_INDICATOR_PART)
{
if ((!_conformant_part_geometry_get_from_env
("ILLUME_IND", &sx, &sy, &sw, &sh)) && (xwin))
if ((!_conformant_part_geometry_env_get("ILLUME_IND",
&sx, &sy, &sw, &sh)) && (xwin))
{
#ifdef HAVE_ELEMENTARY_X
//No information of the indicator geometry, reset the geometry.
if (!ecore_x_e_illume_indicator_geometry_get
(zone, &sx, &sy, &sw, &sh))
//No information of the indicator geometry, reset the geometry.
if (!ecore_x_e_illume_indicator_geometry_get(zone, &sx, &sy, &sw, &sh))
sx = sy = sw = sh = 0;
#else
;
#endif
}
_conformant_part_size_hints_set(obj, sd->indicator, sx, sy, sw, sh);
_conformant_part_size_set(obj, wd->indicator, sx, sy, sw, sh);
}
if (part_type & ELM_CONFORM_VIRTUAL_KEYPAD_PART)
{
if ((!_conformant_part_geometry_get_from_env
("ILLUME_KBD", &sx, &sy, &sw, &sh)) && (xwin))
if ((!_conformant_part_geometry_env_get("ILLUME_KBD",
&sx, &sy, &sw, &sh)) && (xwin))
{
#ifdef HAVE_ELEMENTARY_X
//No information of the keyboard geometry, reset the geometry.
if (!ecore_x_e_illume_keyboard_geometry_get
(zone, &sx, &sy, &sw, &sh))
sx = sy = sw = sh = 0;
//No information of the keyboard geometry, reset the geometry.
if (!ecore_x_e_illume_keyboard_geometry_get(zone, &sx, &sy, &sw, &sh))
sx = sy = sw = sh = 0;
#else
;
#endif
}
_conformant_part_size_hints_set
(obj, sd->virtualkeypad, sx, sy, sw, sh);
_conformant_part_size_set(obj, wd->virtualkeypad, sx, sy, sw, sh);
}
if (part_type & ELM_CONFORM_SOFTKEY_PART)
{
if ((!_conformant_part_geometry_get_from_env
("ILLUME_STK", &sx, &sy, &sw, &sh)) && (xwin))
if ((!_conformant_part_geometry_env_get("ILLUME_STK",
&sx, &sy, &sw, &sh)) && (xwin))
{
#ifdef HAVE_ELEMENTARY_X
//No information of the softkey geometry, reset the geometry.
if (!ecore_x_e_illume_softkey_geometry_get
(zone, &sx, &sy, &sw, &sh))
sx = sy = sw = sh = 0;
//No information of the softkey geometry, reset the geometry.
if (!ecore_x_e_illume_softkey_geometry_get(zone, &sx, &sy, &sw, &sh))
sx = sy = sw = sh = 0;
#else
;
#endif
}
_conformant_part_size_hints_set(obj, sd->softkey, sx, sy, sw, sh);
_conformant_part_size_set(obj, wd->softkey, sx, sy, sw, sh);
}
if (part_type & ELM_CONFORM_CLIPBOARD_PART)
{
if ((!_conformant_part_geometry_get_from_env
("ILLUME_CB", &sx, &sy, &sw, &sh)) && (xwin))
if ((!_conformant_part_geometry_env_get("ILLUME_CB",
&sx, &sy, &sw, &sh)) && (xwin))
{
#ifdef HAVE_ELEMENTARY_X
//No information of the clipboard geometry, reset the geometry.
if (!ecore_x_e_illume_clipboard_geometry_get
(zone, &sx, &sy, &sw, &sh))
sx = sy = sw = sh = 0;
//No information of the clipboard geometry, reset the geometry.
if (!ecore_x_e_illume_clipboard_geometry_get(zone, &sx, &sy, &sw, &sh))
sx = sy = sw = sh = 0;
#else
;
#endif
}
_conformant_part_size_hints_set(obj, sd->clipboard, sx, sy, sw, sh);
_conformant_part_size_set(obj, wd->clipboard, sx, sy, sw, sh);
}
}
static void
_conformant_parts_swallow(Evas_Object *obj)
_swallow_conformant_parts(Evas_Object *obj)
{
Evas *e;
Widget_Data *wd = elm_widget_data_get(obj);
Evas *e = evas_object_evas_get(obj);
if (!wd || !e) return;
ELM_CONFORM_DATA_GET(obj, sd);
e = evas_object_evas_get(obj);
sd->scroller = NULL;
wd->scroller = NULL;
//Indicator
if (!sd->indicator)
if (!wd->indicator)
{
sd->indicator = evas_object_rectangle_add(e);
evas_object_size_hint_min_set(sd->indicator, -1, 0);
evas_object_size_hint_max_set(sd->indicator, -1, 0);
wd->indicator = evas_object_rectangle_add(e);
elm_widget_sub_object_add(obj, wd->indicator);
evas_object_size_hint_min_set(wd->indicator, -1, 0);
evas_object_size_hint_max_set(wd->indicator, -1, 0);
}
else
_conformant_part_sizing_eval(obj, ELM_CONFORM_INDICATOR_PART);
evas_object_color_set(sd->indicator, 0, 0, 0, 0);
elm_layout_content_set(obj, "elm.swallow.indicator", sd->indicator);
evas_object_color_set(wd->indicator, 0, 0, 0, 0);
edje_object_part_swallow(wd->base, "elm.swallow.indicator", wd->indicator);
//Virtual Keyboard
if (!sd->virtualkeypad)
if (!wd->virtualkeypad)
{
sd->virtualkeypad = evas_object_rectangle_add(e);
elm_widget_sub_object_add(obj, sd->virtualkeypad);
evas_object_size_hint_max_set(sd->virtualkeypad, -1, 0);
wd->virtualkeypad = evas_object_rectangle_add(e);
elm_widget_sub_object_add(obj, wd->virtualkeypad);
evas_object_size_hint_min_set(wd->virtualkeypad, -1, 0);
evas_object_size_hint_max_set(wd->virtualkeypad, -1, 0);
}
else
_conformant_part_sizing_eval(obj, ELM_CONFORM_VIRTUAL_KEYPAD_PART);
evas_object_color_set(sd->virtualkeypad, 0, 0, 0, 0);
elm_layout_content_set(obj, "elm.swallow.virtualkeypad", sd->virtualkeypad);
evas_object_color_set(wd->virtualkeypad, 0, 0, 0, 0);
edje_object_part_swallow(wd->base, "elm.swallow.virtualkeypad",
wd->virtualkeypad);
//Clipboard
if (!sd->clipboard)
if (!wd->clipboard)
{
sd->clipboard = evas_object_rectangle_add(e);
evas_object_size_hint_min_set(sd->clipboard, -1, 0);
evas_object_size_hint_max_set(sd->clipboard, -1, 0);
wd->clipboard = evas_object_rectangle_add(e);
elm_widget_sub_object_add(obj, wd->clipboard);
evas_object_size_hint_min_set(wd->clipboard, -1, 0);
evas_object_size_hint_max_set(wd->clipboard, -1, 0);
}
else
_conformant_part_sizing_eval(obj, ELM_CONFORM_CLIPBOARD_PART);
evas_object_color_set(sd->clipboard, 0, 0, 0, 0);
elm_layout_content_set(obj, "elm.swallow.clipboard", sd->clipboard);
evas_object_color_set(wd->clipboard, 0, 0, 0, 0);
edje_object_part_swallow(wd->base, "elm.swallow.clipboard",
wd->clipboard);
//Softkey
if (!sd->softkey)
if (!wd->softkey)
{
sd->softkey = evas_object_rectangle_add(e);
evas_object_size_hint_min_set(sd->softkey, -1, 0);
evas_object_size_hint_max_set(sd->softkey, -1, 0);
wd->softkey = evas_object_rectangle_add(e);
elm_widget_sub_object_add(obj, wd->softkey);
evas_object_size_hint_min_set(wd->softkey, -1, 0);
evas_object_size_hint_max_set(wd->softkey, -1, 0);
}
else
_conformant_part_sizing_eval(obj, ELM_CONFORM_SOFTKEY_PART);
evas_object_color_set(sd->softkey, 0, 0, 0, 0);
elm_layout_content_set(obj, "elm.swallow.softkey", sd->softkey);
evas_object_color_set(wd->softkey, 0, 0, 0, 0);
edje_object_part_swallow(wd->base, "elm.swallow.softkey", wd->softkey);
}
static Eina_Bool
_elm_conform_smart_theme(Evas_Object *obj)
static void
_changed_size_hints(void *data, Evas *e __UNUSED__,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
{
if (!ELM_WIDGET_CLASS(_elm_conform_parent_sc)->theme(obj))
return EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return;
_conformant_parts_swallow(obj);
elm_layout_sizing_eval(obj);
return EINA_TRUE;
_sizing_eval(data);
}
// 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)
{
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)
{
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)
{
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)
{
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_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 void
_autoscroll_mode_disable(Evas_Object *obj)
{
// called when autoscroll mode should be off - set delta to 0 and
// call _autoscroll_move()
}
*/
static void
_move_resize_cb(void *data __UNUSED__,
Evas *e __UNUSED__,
Evas_Object *obj,
void *event_info __UNUSED__)
_conformant_move_resize_event_cb(void *data __UNUSED__, Evas *e __UNUSED__,
Evas_Object *obj, void *event_info __UNUSED__)
{
Conformant_Part_Type part_type;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
part_type = (ELM_CONFORM_INDICATOR_PART |
ELM_CONFORM_SOFTKEY_PART |
ELM_CONFORM_VIRTUAL_KEYPAD_PART |
ELM_CONFORM_CLIPBOARD_PART);
part_type = (ELM_CONFORM_INDICATOR_PART |
ELM_CONFORM_SOFTKEY_PART |
ELM_CONFORM_VIRTUAL_KEYPAD_PART |
ELM_CONFORM_CLIPBOARD_PART);
_conformant_part_sizing_eval(obj, part_type);
}
// showing the focused/important region.
#ifdef HAVE_ELEMENTARY_X
static void
_content_resize_event_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj
__UNUSED__, void *event_info __UNUSED__)
{
Evas_Object *conformant = (Evas_Object *)data;
Widget_Data *wd = elm_widget_data_get(conformant);
if (!wd) return;
if (wd->vkb_state == ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF) return;
if (wd->show_region_job) ecore_job_del(wd->show_region_job);
wd->show_region_job = ecore_job_add(_show_region_job, conformant);
}
#endif
static void
_show_region_job(void *data)
{
Evas_Object *focus_obj;
Evas_Object *conformant = (Evas_Object *)data;
Widget_Data *wd = elm_widget_data_get(conformant);
if (!wd) return;
ELM_CONFORM_DATA_GET(data, sd);
focus_obj = elm_widget_focused_object_get(data);
focus_obj = elm_widget_focused_object_get(conformant);
if (focus_obj)
{
Evas_Coord x, y, w, h;
@ -414,46 +533,27 @@ _show_region_job(void *data)
elm_widget_show_region_set(focus_obj, x, y, w, h, EINA_TRUE);
}
sd->show_region_job = NULL;
wd->show_region_job = NULL;
}
// showing the focused/important region.
#ifdef HAVE_ELEMENTARY_X
static void
_on_content_resize(void *data,
Evas *e __UNUSED__,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
{
ELM_CONFORM_DATA_GET(data, sd);
if (sd->vkb_state == ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF) return;
if (sd->show_region_job) ecore_job_del(sd->show_region_job);
sd->show_region_job = ecore_job_add(_show_region_job, data);
}
#endif
#ifdef HAVE_ELEMENTARY_X
static void
_autoscroll_objects_update(void *data)
_update_autoscroll_objs(void *data)
{
int i;
const char *type;
int i;
Evas_Object *sub, *top_scroller = NULL;
Evas_Object *conformant = (Evas_Object *)data;
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return;
ELM_CONFORM_DATA_GET(data, sd);
sub = elm_widget_focused_object_get(data);
//Look up for top most scroller in the focus object hierarchy
//inside Conformant.
sub = elm_widget_focused_object_get(conformant);
//Look up for Top most scroller in the Focus Object hierarchy inside Conformant.
while (sub)
{
type = elm_widget_type_get(sub);
if (!strcmp(type, CONFORM_SMART_NAME)) break;
if (!strcmp(type, "conformant")) break;
for (i = 0; i < SUB_TYPE_COUNT; i++)
if (!strcmp(type, sub_type[i]))
{
@ -464,37 +564,35 @@ _autoscroll_objects_update(void *data)
}
//If the scroller got changed by app, replace it.
if (top_scroller != sd->scroller)
if (top_scroller != wd->scroller)
{
if (sd->scroller)
evas_object_event_callback_del
(sd->scroller, EVAS_CALLBACK_RESIZE, _on_content_resize);
sd->scroller = top_scroller;
if (sd->scroller)
evas_object_event_callback_add
(sd->scroller, EVAS_CALLBACK_RESIZE, _on_content_resize, data);
if (wd->scroller) evas_object_event_callback_del(wd->scroller,
EVAS_CALLBACK_RESIZE,
_content_resize_event_cb);
wd->scroller = top_scroller;
if (wd->scroller) evas_object_event_callback_add(wd->scroller,
EVAS_CALLBACK_RESIZE,
_content_resize_event_cb,
data);
}
}
static Eina_Bool
_on_prop_change(void *data,
int type __UNUSED__,
void *event)
_prop_change(void *data, int type __UNUSED__, void *event)
{
Ecore_X_Event_Window_Property *ev = event;
ELM_CONFORM_DATA_GET(data, sd);
Ecore_X_Event_Window_Property *ev;
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return ECORE_CALLBACK_PASS_ON;
ev = event;
if (ev->atom == ECORE_X_ATOM_E_ILLUME_ZONE)
{
Conformant_Part_Type part_type;
part_type = (ELM_CONFORM_INDICATOR_PART |
ELM_CONFORM_SOFTKEY_PART |
ELM_CONFORM_VIRTUAL_KEYPAD_PART |
ELM_CONFORM_CLIPBOARD_PART);
part_type = (ELM_CONFORM_INDICATOR_PART |
ELM_CONFORM_SOFTKEY_PART |
ELM_CONFORM_VIRTUAL_KEYPAD_PART |
ELM_CONFORM_CLIPBOARD_PART);
_conformant_part_sizing_eval(data, part_type);
}
else if (ev->atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY)
@ -509,15 +607,16 @@ _on_prop_change(void *data,
{
Ecore_X_Window zone;
DBG("Keyboard Geometry Changed\n");
printf("Keyboard Geometry Changed\n");
zone = ecore_x_e_illume_zone_get(ev->win);
sd->vkb_state = ecore_x_e_virtual_keyboard_state_get(zone);
if (sd->vkb_state == ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF)
wd->vkb_state = ecore_x_e_virtual_keyboard_state_get(zone);
if (wd->vkb_state == ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF)
{
evas_object_size_hint_min_set(sd->virtualkeypad, -1, 0);
evas_object_size_hint_max_set(sd->virtualkeypad, -1, 0);
evas_object_size_hint_min_set(wd->virtualkeypad, -1, 0);
evas_object_size_hint_max_set(wd->virtualkeypad, -1, 0);
}
else _autoscroll_objects_update(data);
else
_update_autoscroll_objs(data);
}
else if (ev->atom == ECORE_X_ATOM_E_ILLUME_CLIPBOARD_STATE)
{
@ -529,73 +628,43 @@ _on_prop_change(void *data,
if (state != ECORE_X_ILLUME_CLIPBOARD_STATE_ON)
{
evas_object_size_hint_min_set(sd->clipboard, -1, 0);
evas_object_size_hint_max_set(sd->clipboard, -1, 0);
evas_object_size_hint_min_set(wd->clipboard, -1, 0);
evas_object_size_hint_max_set(wd->clipboard, -1, 0);
}
else _autoscroll_objects_update(data);
else
_update_autoscroll_objs(data);
}
return ECORE_CALLBACK_PASS_ON;
}
#endif
static void
_elm_conform_smart_add(Evas_Object *obj)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Conform_Smart_Data);
ELM_WIDGET_CLASS(_elm_conform_parent_sc)->base.add(obj);
elm_widget_can_focus_set(obj, EINA_FALSE);
elm_layout_theme_set(obj, "conformant", "base", elm_widget_style_get(obj));
_conformant_parts_swallow(obj);
}
static void
_elm_conform_smart_del(Evas_Object *obj)
{
ELM_CONFORM_DATA_GET(obj, sd);
#ifdef HAVE_ELEMENTARY_X
if (sd->prop_hdl) ecore_event_handler_del(sd->prop_hdl);
#endif
if (sd->show_region_job) ecore_job_del(sd->show_region_job);
ELM_WIDGET_CLASS(_elm_conform_parent_sc)->base.del(obj);
}
static void
_elm_conform_smart_set_user(Elm_Layout_Smart_Class *sc)
{
ELM_WIDGET_CLASS(sc)->base.add = _elm_conform_smart_add;
ELM_WIDGET_CLASS(sc)->base.del = _elm_conform_smart_del;
ELM_WIDGET_CLASS(sc)->theme = _elm_conform_smart_theme;
ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */
sc->content_aliases = _content_aliases;
}
EAPI Evas_Object *
elm_conformant_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
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_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, EINA_FALSE);
elm_widget_content_set_hook_set(obj, _content_set_hook);
elm_widget_content_get_hook_set(obj, _content_get_hook);
elm_widget_content_unset_hook_set(obj, _content_unset_hook);
obj = evas_object_smart_add(e, _elm_conform_smart_class_new());
wd->base = edje_object_add(e);
_elm_theme_object_set(obj, wd->base, "conformant", "base", "default");
elm_widget_resize_object_set(obj, wd->base);
/* NB: we got to sub-object-add before we probe for the top widget */
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
_swallow_conformant_parts(obj);
#ifdef HAVE_ELEMENTARY_X
Evas_Object *top = elm_widget_top_get(obj);
@ -603,21 +672,21 @@ elm_conformant_add(Evas_Object *parent)
if ((xwin) && (!elm_win_inlined_image_object_get(top)))
{
ELM_CONFORM_DATA_GET(obj, sd);
sd->prop_hdl = ecore_event_handler_add
(ECORE_X_EVENT_WINDOW_PROPERTY, _on_prop_change, obj);
sd->vkb_state = ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF;
wd->prop_hdl = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY,
_prop_change, obj);
wd->vkb_state = ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF;
}
// FIXME: get kbd region prop
#endif
evas_object_event_callback_add
(obj, EVAS_CALLBACK_RESIZE, _move_resize_cb, obj);
evas_object_event_callback_add
(obj, EVAS_CALLBACK_MOVE, _move_resize_cb, obj);
evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
_conformant_move_resize_event_cb, obj);
evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
_conformant_move_resize_event_cb, obj);
elm_layout_sizing_eval(obj);
evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_sizing_eval(obj);
return obj;
}

View File

@ -16,11 +16,6 @@
* space required for such stuff, and when they popup, as a keyboard
* shows when an entry is selected, conformant content won't change.
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for conformant objects.
*
* This widget emits the same signals sent from @ref Layout:
*
* Available styles for it:
* - @c "default"
*

View File

@ -1,68 +0,0 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_container.h"
static const char CONTAINER_SMART_NAME[] = "elm_container";
/* Elementary smart class for all widgets containing others */
EVAS_SMART_SUBCLASS_NEW
(CONTAINER_SMART_NAME, _elm_container, Elm_Container_Smart_Class,
Elm_Widget_Smart_Class, elm_widget_smart_class_get, NULL);
/* no *direct* instantiation of this class, so far */
__UNUSED__ static Evas_Smart *_elm_container_smart_class_new(void);
static Eina_Bool
_unimplemented_smart_content_set(Evas_Object *obj,
const char *name __UNUSED__,
Evas_Object *content __UNUSED__)
{
WRN("The %s widget does not implement the \"content_set()\" function.",
elm_widget_type_get(obj));
return EINA_FALSE;
}
static Evas_Object *
_unimplemented_smart_content_get(const Evas_Object *obj,
const char *name __UNUSED__)
{
WRN("The %s widget does not implement the \"content_get()\" function.",
elm_widget_type_get(obj));
return NULL;
}
static Evas_Object *
_unimplemented_smart_content_unset(Evas_Object *obj,
const char *name __UNUSED__)
{
WRN("The %s widunset does not implement the \"content_unset()\" function.",
elm_widget_type_get(obj));
return NULL;
}
EAPI const Elm_Container_Smart_Class *
elm_container_smart_class_get(void)
{
static Elm_Container_Smart_Class _sc =
ELM_CONTAINER_SMART_CLASS_INIT_NAME_VERSION(CONTAINER_SMART_NAME);
static const Elm_Container_Smart_Class *class = NULL;
if (class)
return class;
_elm_container_smart_set(&_sc);
class = &_sc;
return class;
}
static void
_elm_container_smart_set_user(Elm_Container_Smart_Class *sc)
{
sc->content_set = _unimplemented_smart_content_set;
sc->content_get = _unimplemented_smart_content_get;
sc->content_unset = _unimplemented_smart_content_unset;
}

File diff suppressed because it is too large Load Diff

View File

@ -172,16 +172,12 @@
*
* <b>export ELM_MODULES="datetime_input_ctxpopup>datetime/api"</b>
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for datetime objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* @li @b "changed" - whenever Datetime field value is changed, this
* signal is sent.
* Datetime widgets emits the following signals:
*
* @li @b "language,changed" - whenever system locale changes, this
* signal is sent.
* @li @b "changed" - whenever Datetime field value is changed, this signal is sent.
*
* @li @b "language,changed" - whenever system locale changes, this signal is sent.
*
* Here is an example on its usage:
* @li @ref datetime_example

View File

@ -1,633 +0,0 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_layout.h"
static const char DAYSELECTOR_SMART_NAME[] = "elm_dayselector";
typedef struct _Elm_Dayselector_Smart_Data Elm_Dayselector_Smart_Data;
typedef struct _Elm_Dayselector_Item Elm_Dayselector_Item;
/* signals to edc */
#define ITEM_TYPE_WEEKDAY_DEFAULT "elm,type,weekday,default"
#define ITEM_TYPE_WEEKDAY_STYLE1 "elm,type,weekday,style1"
#define ITEM_TYPE_WEEKEND_DEFAULT "elm,type,weekend,default"
#define ITEM_TYPE_WEEKEND_STYLE1 "elm,type,weekend,style1"
#define ITEM_POS_LEFT "elm,pos,check,left"
#define ITEM_POS_RIGHT "elm,pos,check,right"
#define ITEM_POS_MIDDLE "elm,pos,check,middle"
struct _Elm_Dayselector_Smart_Data
{
Elm_Layout_Smart_Data base;
Eina_List *items;
Elm_Dayselector_Day week_start;
Elm_Dayselector_Day weekend_start;
unsigned int weekend_len;
};
struct _Elm_Dayselector_Item
{
ELM_WIDGET_ITEM;
Elm_Dayselector_Day day;
const char *day_style;
};
static const char SIG_CHANGED[] = "dayselector,changed";
static const char SIG_LANG_CHANGED[] = "language,changed";
static const Evas_Smart_Cb_Description _smart_callbacks[] = {
{SIG_CHANGED, ""},
{SIG_LANG_CHANGED, ""},
{NULL, NULL}
};
#define ELM_DAYSELECTOR_DATA_GET(o, sd) \
Elm_Dayselector_Smart_Data * sd = evas_object_smart_data_get(o)
#define ELM_DAYSELECTOR_DATA_GET_OR_RETURN(o, ptr) \
ELM_DAYSELECTOR_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define ELM_DAYSELECTOR_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_DAYSELECTOR_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_DAYSELECTOR_CHECK(obj) \
if (!obj || !elm_widget_type_check( \
(obj), DAYSELECTOR_SMART_NAME, __func__)) \
return
/* Inheriting from elm_layout. Besides, we need no more than what is
* there */
EVAS_SMART_SUBCLASS_NEW
(DAYSELECTOR_SMART_NAME, _elm_dayselector, Elm_Layout_Smart_Class,
Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks);
static void
_elm_dayselector_smart_sizing_eval(Evas_Object *obj)
{
Evas_Coord min_w = -1, min_h = -1;
ELM_DAYSELECTOR_DATA_GET(obj, sd);
elm_coords_finger_size_adjust(ELM_DAYSELECTOR_MAX, &min_w, 1, &min_h);
edje_object_size_min_restricted_calc
(ELM_WIDGET_DATA(sd)->resize_obj, &min_w, &min_h, min_w, min_h);
elm_coords_finger_size_adjust(ELM_DAYSELECTOR_MAX, &min_w, 1, &min_h);
evas_object_size_hint_min_set(obj, min_w, min_h);
}
static void
_dayselector_resize(void *data,
Evas *e __UNUSED__,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
{
elm_layout_sizing_eval(data);
}
#if 0
static Eina_Bool
_elm_dayselector_smart_focus_next(const Evas_Object *obj,
Elm_Focus_Direction dir __UNUSED__,
Evas_Object **next __UNUSED__)
{
ELM_DAYSELECTOR_DATA_GET(obj, sd);
/* TODO: Focus switch support to Elm_widget_Item is not supported yet.*/
return EINA_FALSE;
}
#endif
static Eina_Bool
_elm_dayselector_smart_translate(Evas_Object *obj)
{
time_t t;
Eina_List *l;
char buf[1024];
struct tm time_daysel;
Elm_Dayselector_Item *it;
ELM_DAYSELECTOR_DATA_GET(obj, sd);
t = time(NULL);
localtime_r(&t, &time_daysel);
EINA_LIST_FOREACH (sd->items, l, it)
{
time_daysel.tm_wday = it->day;
strftime(buf, sizeof(buf), "%a", &time_daysel);
elm_object_text_set(VIEW(it), buf);
}
evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL);
return EINA_TRUE;
}
static void
_update_items(Evas_Object *obj)
{
Eina_List *l;
Eina_Bool rtl;
unsigned int last_day;
Elm_Dayselector_Item *it;
ELM_DAYSELECTOR_DATA_GET(obj, sd);
last_day = sd->week_start + ELM_DAYSELECTOR_MAX - 1;
if (last_day >= ELM_DAYSELECTOR_MAX)
last_day = last_day % ELM_DAYSELECTOR_MAX;
rtl = elm_widget_mirrored_get(obj);
EINA_LIST_FOREACH (sd->items, l, it)
{
elm_object_signal_emit(VIEW(it), it->day_style, "");
if (it->day == sd->week_start)
{
if (rtl) elm_object_signal_emit(VIEW(it), ITEM_POS_RIGHT, "elm");
else elm_object_signal_emit(VIEW(it), ITEM_POS_LEFT, "elm");
}
else if (it->day == last_day)
{
if (rtl) elm_object_signal_emit(VIEW(it), ITEM_POS_LEFT, "elm");
else elm_object_signal_emit(VIEW(it), ITEM_POS_RIGHT, "elm");
}
else
elm_object_signal_emit(VIEW(it), ITEM_POS_MIDDLE, "elm");
}
}
static inline unsigned int
_item_location_get(Elm_Dayselector_Smart_Data *sd,
Elm_Dayselector_Item *it)
{
return (ELM_DAYSELECTOR_MAX - sd->week_start + it->day) %
ELM_DAYSELECTOR_MAX;
}
static Eina_Bool
_elm_dayselector_smart_theme(Evas_Object *obj)
{
Eina_List *l;
char buf[1024];
Elm_Dayselector_Item *it;
ELM_DAYSELECTOR_DATA_GET(obj, sd);
if (!ELM_WIDGET_CLASS(_elm_dayselector_parent_sc)->theme(obj))
return EINA_FALSE;
EINA_LIST_FOREACH (sd->items, l, it)
{
snprintf
(buf, sizeof(buf), "dayselector/%s", elm_object_style_get(obj));
elm_object_style_set(VIEW(it), buf);
snprintf
(buf, sizeof(buf), "day%d,visible", _item_location_get(sd, it));
elm_layout_signal_emit(obj, buf, "elm");
}
_update_items(obj);
elm_layout_sizing_eval(obj);
return EINA_TRUE;
}
static void
_item_del_cb(void *data,
Evas *e __UNUSED__,
Evas_Object *obj,
void *event_info __UNUSED__)
{
Eina_List *l;
char buf[1024];
Elm_Dayselector_Item *it;
ELM_DAYSELECTOR_DATA_GET(data, sd);
EINA_LIST_FOREACH (sd->items, l, it)
{
if (obj == VIEW(it))
{
sd->items = eina_list_remove(sd->items, it);
eina_stringshare_del(it->day_style);
snprintf(buf, sizeof(buf), "day%d,default",
_item_location_get(sd, it));
elm_layout_signal_emit(obj, buf, "elm");
VIEW(it) = NULL;
elm_widget_item_free(it);
elm_layout_sizing_eval(obj);
break;
}
}
}
static void
_item_signal_emit_cb(void *data,
Evas_Object *obj __UNUSED__,
const char *emission,
const char *source __UNUSED__)
{
Elm_Dayselector_Item *it = data;
eina_stringshare_replace(&it->day_style, emission);
}
static void
_item_clicked_cb(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
{
Elm_Dayselector_Item *it = data;
evas_object_smart_callback_call(WIDGET(it), SIG_CHANGED, (void *)it->day);
}
static Elm_Dayselector_Item *
_item_find(const Evas_Object *obj,
Elm_Dayselector_Day day)
{
Eina_List *l;
Elm_Dayselector_Item *it;
ELM_DAYSELECTOR_DATA_GET(obj, sd);
EINA_LIST_FOREACH (sd->items, l, it)
if (day == it->day) return it;
return NULL;
}
static Eina_Bool
_elm_dayselector_smart_content_set(Evas_Object *obj,
const char *item,
Evas_Object *content)
{
int day;
char buf[1024];
Elm_Dayselector_Item *it = NULL;
ELM_DAYSELECTOR_DATA_GET(obj, sd);
if (strcmp(elm_object_widget_type_get(content), "elm_check"))
return EINA_FALSE;
if (!item) return EINA_FALSE;
day = atoi(item + (strlen(item) - 1));
if (day < 0 || day > ELM_DAYSELECTOR_MAX) return EINA_FALSE;
it = _item_find(obj, day);
if (it)
{
snprintf(buf, sizeof(buf), "day%d", _item_location_get(sd, it));
if (!ELM_CONTAINER_CLASS(_elm_dayselector_parent_sc)->content_set
(obj, buf, content))
return EINA_FALSE;
if (!content) return EINA_TRUE; /* item deletion already
* handled */
evas_object_del(VIEW(it));
VIEW(it) = content;
}
else
{
it = elm_widget_item_new(obj, Elm_Dayselector_Item);
it->day = day;
snprintf(buf, sizeof(buf), "day%d", _item_location_get(sd, it));
if (!ELM_CONTAINER_CLASS(_elm_dayselector_parent_sc)->content_set
(obj, buf, content))
{
elm_widget_item_free(it);
return EINA_FALSE;
}
sd->items = eina_list_append(sd->items, it);
VIEW(it) = content;
}
snprintf(buf, sizeof(buf), "day%d,visible", _item_location_get(sd, it));
elm_layout_signal_emit(obj, buf, "elm");
evas_object_smart_callback_add(VIEW(it), "changed", _item_clicked_cb, it);
evas_object_event_callback_add
(VIEW(it), EVAS_CALLBACK_DEL, _item_del_cb, obj);
elm_object_signal_callback_add
(VIEW(it), ITEM_TYPE_WEEKDAY_DEFAULT, "", _item_signal_emit_cb, it);
elm_object_signal_callback_add
(VIEW(it), ITEM_TYPE_WEEKDAY_STYLE1, "", _item_signal_emit_cb, it);
elm_object_signal_callback_add
(VIEW(it), ITEM_TYPE_WEEKEND_DEFAULT, "", _item_signal_emit_cb, it);
elm_object_signal_callback_add
(VIEW(it), ITEM_TYPE_WEEKEND_STYLE1, "", _item_signal_emit_cb, it);
elm_layout_sizing_eval(obj);
_update_items(obj);
return EINA_TRUE;
}
static Evas_Object *
_elm_dayselector_smart_content_unset(Evas_Object *obj,
const char *item)
{
int day;
char buf[1024];
Evas_Object *content;
Elm_Dayselector_Item *it = NULL;
ELM_DAYSELECTOR_DATA_GET(obj, sd);
day = atoi(item + (strlen(item) - 1));
if (day < 0 || day > ELM_DAYSELECTOR_MAX) return EINA_FALSE;
it = _item_find(obj, day);
if (!it) return NULL;
content = VIEW(it);
if (!ELM_CONTAINER_CLASS(_elm_dayselector_parent_sc)->content_unset
(obj, buf))
return EINA_FALSE;
sd->items = eina_list_remove(sd->items, it);
evas_object_smart_callback_del(content, "changed", _item_clicked_cb);
evas_object_event_callback_del(content, EVAS_CALLBACK_DEL, _item_del_cb);
elm_object_signal_callback_del
(content, ITEM_TYPE_WEEKDAY_DEFAULT, "", _item_signal_emit_cb);
elm_object_signal_callback_del
(content, ITEM_TYPE_WEEKDAY_STYLE1, "", _item_signal_emit_cb);
elm_object_signal_callback_del
(content, ITEM_TYPE_WEEKEND_DEFAULT, "", _item_signal_emit_cb);
elm_object_signal_callback_del
(content, ITEM_TYPE_WEEKEND_STYLE1, "", _item_signal_emit_cb);
snprintf(buf, sizeof(buf), "day%d,default", _item_location_get(sd, it));
elm_layout_signal_emit(obj, buf, "elm");
VIEW(it) = NULL;
elm_widget_item_free(it);
elm_layout_sizing_eval(obj);
return content;
}
static void
_items_style_set(Evas_Object *obj)
{
Eina_List *l;
Elm_Dayselector_Item *it;
unsigned int weekend_last;
ELM_DAYSELECTOR_DATA_GET(obj, sd);
weekend_last = sd->weekend_start + sd->weekend_len - 1;
if (weekend_last >= ELM_DAYSELECTOR_MAX)
weekend_last = weekend_last % ELM_DAYSELECTOR_MAX;
EINA_LIST_FOREACH (sd->items, l, it)
{
if (weekend_last >= sd->weekend_start)
{
if ((it->day >= sd->weekend_start) && (it->day <= weekend_last))
eina_stringshare_replace(&it->day_style,
ITEM_TYPE_WEEKEND_DEFAULT);
else
eina_stringshare_replace(&it->day_style,
ITEM_TYPE_WEEKDAY_DEFAULT);
}
else
{
if ((it->day >= sd->weekend_start) || (it->day <= weekend_last))
eina_stringshare_replace(&it->day_style,
ITEM_TYPE_WEEKEND_DEFAULT);
else
eina_stringshare_replace(&it->day_style,
ITEM_TYPE_WEEKDAY_DEFAULT);
}
}
}
static void
_items_create(Evas_Object *obj)
{
time_t t;
char buf[1024];
unsigned int idx;
struct tm time_daysel;
t = time(NULL);
localtime_r(&t, &time_daysel);
for (idx = 0; idx < ELM_DAYSELECTOR_MAX; idx++)
{
Evas_Object *chk;
chk = elm_check_add(obj);
elm_object_style_set(chk, "dayselector/default");
time_daysel.tm_wday = idx;
strftime(buf, sizeof(buf), "%a", &time_daysel);
elm_object_text_set(chk, buf);
snprintf(buf, sizeof(buf), "day%d", idx);
elm_layout_content_set(obj, buf, chk);
}
_items_style_set(obj);
_update_items(obj);
}
static void
_elm_dayselector_smart_add(Evas_Object *obj)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Dayselector_Smart_Data);
ELM_WIDGET_CLASS(_elm_dayselector_parent_sc)->base.add(obj);
elm_layout_theme_set(obj, "dayselector", "base", "dayselector");
priv->week_start = _elm_config->week_start;
priv->weekend_start = _elm_config->weekend_start;
priv->weekend_len = _elm_config->weekend_len;
_items_create(obj);
evas_object_event_callback_add
(obj, EVAS_CALLBACK_RESIZE, _dayselector_resize, obj);
elm_layout_sizing_eval(obj);
}
static void
_elm_dayselector_smart_del(Evas_Object *obj)
{
ELM_DAYSELECTOR_DATA_GET(obj, sd);
Elm_Dayselector_Item *it;
EINA_LIST_FREE (sd->items, it)
{
sd->items = eina_list_remove(sd->items, it);
eina_stringshare_del(it->day_style);
elm_widget_item_free(it);
}
/* handles freeing sd */
ELM_WIDGET_CLASS(_elm_dayselector_parent_sc)->base.del(obj);
}
static void
_elm_dayselector_smart_set_user(Elm_Layout_Smart_Class *sc)
{
ELM_WIDGET_CLASS(sc)->base.add = _elm_dayselector_smart_add;
ELM_WIDGET_CLASS(sc)->base.del = _elm_dayselector_smart_del;
ELM_WIDGET_CLASS(sc)->theme = _elm_dayselector_smart_theme;
ELM_WIDGET_CLASS(sc)->translate = _elm_dayselector_smart_translate;
#if 0
ELM_WIDGET_CLASS(sc)->focus_next = _elm_dayselector_smart_focus_next;
#else
ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */
#endif
ELM_CONTAINER_CLASS(sc)->content_set = _elm_dayselector_smart_content_set;
ELM_CONTAINER_CLASS(sc)->content_unset =
_elm_dayselector_smart_content_unset;
sc->sizing_eval = _elm_dayselector_smart_sizing_eval;
}
EAPI Evas_Object *
elm_dayselector_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
obj = evas_object_smart_add(e, _elm_dayselector_smart_class_new());
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
return obj;
}
EAPI void
elm_dayselector_day_selected_set(Evas_Object *obj,
Elm_Dayselector_Day day,
Eina_Bool selected)
{
ELM_DAYSELECTOR_CHECK(obj);
elm_check_state_set(VIEW(_item_find(obj, day)), selected);
}
EAPI Eina_Bool
elm_dayselector_day_selected_get(const Evas_Object *obj,
Elm_Dayselector_Day day)
{
ELM_DAYSELECTOR_CHECK(obj) EINA_FALSE;
return elm_check_state_get(VIEW(_item_find(obj, day)));
}
EAPI void
elm_dayselector_week_start_set(Evas_Object *obj,
Elm_Dayselector_Day day)
{
Eina_List *l;
char buf[1024];
Elm_Dayselector_Item *it;
ELM_DAYSELECTOR_CHECK(obj);
ELM_DAYSELECTOR_DATA_GET(obj, sd);
/* just shuffling items, so swalling them directly */
sd->week_start = day;
EINA_LIST_FOREACH (sd->items, l, it)
{
snprintf(buf, sizeof(buf), "day%d", _item_location_get(sd, it));
edje_object_part_swallow
(ELM_WIDGET_DATA(sd)->resize_obj, buf, VIEW(it));
}
_update_items(obj);
}
EAPI Elm_Dayselector_Day
elm_dayselector_week_start_get(const Evas_Object *obj)
{
ELM_DAYSELECTOR_CHECK(obj) ELM_DAYSELECTOR_MAX;
ELM_DAYSELECTOR_DATA_GET(obj, sd);
return sd->week_start;
}
EAPI void
elm_dayselector_weekend_start_set(Evas_Object *obj,
Elm_Dayselector_Day day)
{
ELM_DAYSELECTOR_CHECK(obj);
ELM_DAYSELECTOR_DATA_GET(obj, sd);
sd->weekend_start = day;
_items_style_set(obj);
_update_items(obj);
}
EAPI Elm_Dayselector_Day
elm_dayselector_weekend_start_get(const Evas_Object *obj)
{
ELM_DAYSELECTOR_CHECK(obj) ELM_DAYSELECTOR_MAX;
ELM_DAYSELECTOR_DATA_GET(obj, sd);
return sd->weekend_start;
}
EAPI void
elm_dayselector_weekend_length_set(Evas_Object *obj,
unsigned int length)
{
ELM_DAYSELECTOR_CHECK(obj);
ELM_DAYSELECTOR_DATA_GET(obj, sd);
sd->weekend_len = length;
_items_style_set(obj);
_update_items(obj);
}
EAPI unsigned int
elm_dayselector_weekend_length_get(const Evas_Object *obj)
{
ELM_DAYSELECTOR_CHECK(obj) 0;
ELM_DAYSELECTOR_DATA_GET(obj, sd);
return sd->weekend_len;
}

File diff suppressed because it is too large Load Diff

View File

@ -16,11 +16,7 @@
* so that it helps the user to reach an item which is distant from
* the current selection.
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for flip selector objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* Smart callbacks one can register to:
* - @c "selected" - when the widget's selected text item is changed
* - @c "overflowed" - when the widget's current selection is changed
* from the first item in its list to the last

View File

@ -1,269 +1,325 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_layout.h"
static const char FRAME_SMART_NAME[] = "elm_frame";
typedef struct _Widget_Data Widget_Data;
typedef struct _Elm_Frame_Smart_Data Elm_Frame_Smart_Data;
struct _Elm_Frame_Smart_Data
struct _Widget_Data
{
Elm_Layout_Smart_Data base;
Eina_Bool collapsed : 1;
Eina_Bool collapsible : 1;
Eina_Bool anim : 1;
Evas_Object *frm;
Evas_Object *content;
const char *label;
unsigned int recalc_count;
Eina_Bool collapsed : 1;
Eina_Bool collapsible : 1;
Eina_Bool anim : 1;
};
static const char SIG_CLICKED[] = "clicked";
static const Evas_Smart_Cb_Description _smart_callbacks[] = {
static const Evas_Smart_Cb_Description _signals[] = {
{SIG_CLICKED, ""},
{NULL, NULL}
};
#define ELM_FRAME_DATA_GET(o, sd) \
Elm_Frame_Smart_Data * sd = evas_object_smart_data_get(o)
#define ELM_FRAME_DATA_GET_OR_RETURN(o, ptr) \
ELM_FRAME_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define ELM_FRAME_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_FRAME_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_FRAME_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), FRAME_SMART_NAME, __func__)) \
return
static const Elm_Layout_Part_Alias_Description _content_aliases[] =
{
{"default", "elm.swallow.content"},
{NULL, NULL}
};
static const Elm_Layout_Part_Alias_Description _text_aliases[] =
{
{"default", "elm.text"},
{NULL, NULL}
};
/* Inheriting from elm_layout. Besides, we need no more than what is
* there */
EVAS_SMART_SUBCLASS_NEW
(FRAME_SMART_NAME, _elm_frame, Elm_Layout_Smart_Class,
Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks);
static const char *widtype = NULL;
static void _del_hook(Evas_Object *obj);
static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
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
_sizing_eval(Evas_Object *obj,
Elm_Frame_Smart_Data *sd)
_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
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
edje_object_mirrored_set(wd->frm, rtl);
}
static void
_theme_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
_elm_widget_mirrored_reload(obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_elm_theme_object_set(obj, wd->frm, "frame", "base",
elm_widget_style_get(obj));
edje_object_part_text_escaped_set(wd->frm, "elm.text", wd->label);
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 Eina_Bool
_elm_frame_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
{
Widget_Data *wd = elm_widget_data_get(obj);
if ((!wd) || (!wd->content))
return EINA_FALSE;
/* Try Focus cycle in subitem */
return elm_widget_focus_next_get(wd->content, dir, next);
}
static void
_sizing_eval(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
Evas_Coord minw = -1, minh = -1;
Evas_Coord cminw = -1, cminh = -1;
edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh);
if (!wd) return;
edje_object_size_min_calc(wd->frm, &minw, &minh);
evas_object_size_hint_min_get(obj, &cminw, &cminh);
if ((minw == cminw) && (minh == cminh)) return;
evas_object_size_hint_min_set(obj, minw, minh);
evas_object_size_hint_max_set(obj, -1, -1);
}
static Eina_Bool
_elm_frame_smart_focus_next(const Evas_Object *obj,
Elm_Focus_Direction dir,
Evas_Object **next)
static void
_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
Evas_Object *content;
content = elm_layout_content_get(obj, NULL);
if (!content) return EINA_FALSE;
/* attempt to follow focus cycle into sub-object */
return elm_widget_focus_next_get(content, dir, next);
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return;
if (wd->anim) return;
// FIXME: why is this needed? how does edje get this unswallowed or
// lose its callbacks to edje
edje_object_part_swallow(wd->frm, "elm.swallow.content", wd->content);
_sizing_eval(data);
}
static void
_recalc(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
{
elm_layout_sizing_eval(data);
}
static void
_on_recalc_done(void *data,
Evas_Object *obj __UNUSED__,
const char *sig __UNUSED__,
const char *src __UNUSED__)
{
ELM_FRAME_DATA_GET(data, sd);
evas_object_smart_callback_del
(ELM_WIDGET_DATA(sd)->resize_obj, "recalc", _recalc);
sd->anim = EINA_FALSE;
elm_layout_sizing_eval(data);
}
static void
_on_frame_clicked(void *data,
Evas_Object *obj __UNUSED__,
const char *sig __UNUSED__,
const char *src __UNUSED__)
{
ELM_FRAME_DATA_GET(data, sd);
if (sd->anim) return;
if (sd->collapsible)
Widget_Data *wd = elm_widget_data_get(obj);
Evas_Object *sub = event_info;
if (!wd) return;
if (sub == wd->content)
{
evas_object_smart_callback_add
(ELM_WIDGET_DATA(sd)->resize_obj, "recalc", _recalc, data);
elm_layout_signal_emit(data, "elm,action,toggle", "elm");
sd->collapsed++;
sd->anim = EINA_TRUE;
evas_object_event_callback_del_full(sub,
EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_changed_size_hints, obj);
wd->content = NULL;
_sizing_eval(obj);
}
}
static void
_elm_frame_label_set(Evas_Object *obj, const char *item, const char *label)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (item && strcmp(item, "default")) return;
if (!wd) return;
eina_stringshare_replace(&(wd->label), label);
edje_object_part_text_escaped_set(wd->frm, "elm.text", wd->label);
_sizing_eval(obj);
}
static const char *
_elm_frame_label_get(const Evas_Object *obj, const char *item)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
if (item && strcmp(item, "default")) return NULL;
return wd->label;
}
static void
_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd;
if (part && strcmp(part, "default")) return;
wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->content == content) return;
if (wd->content) evas_object_del(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);
}
static Evas_Object *
_content_get_hook(const Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd;
if (part && strcmp(part, "default")) return NULL;
wd = elm_widget_data_get(obj);
if (!wd) return NULL;
return wd->content;
}
static Evas_Object *
_content_unset_hook(Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd;
Evas_Object *content;
if (part && strcmp(part, "default")) return NULL;
wd = elm_widget_data_get(obj);
if (!wd || !wd->content) return NULL;
content = wd->content;
elm_widget_sub_object_del(obj, wd->content);
edje_object_part_unswallow(wd->frm, content);
return content;
}
static void
_recalc(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
_sizing_eval(data);
}
static void
_recalc_done(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *src __UNUSED__)
{
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return;
evas_object_smart_callback_del(wd->frm, "recalc", _recalc);
wd->anim = EINA_FALSE;
_sizing_eval(data);
}
static void
_signal_click(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *src __UNUSED__)
{
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return;
if (wd->anim) return;
if (wd->collapsible)
{
evas_object_smart_callback_add(wd->frm, "recalc", _recalc, data);
edje_object_signal_emit(wd->frm, "elm,action,toggle", "elm");
wd->collapsed++;
wd->anim = EINA_TRUE;
}
evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
}
/* using deferred sizing evaluation, just like the parent */
static void
_elm_frame_smart_calculate(Evas_Object *obj)
{
ELM_FRAME_DATA_GET(obj, sd);
if (ELM_LAYOUT_DATA(sd)->needs_size_calc)
{
/* calling OWN sizing evaluate code here */
_sizing_eval(obj, sd);
ELM_LAYOUT_DATA(sd)->needs_size_calc = EINA_FALSE;
}
}
static void
_elm_frame_smart_add(Evas_Object *obj)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Frame_Smart_Data);
ELM_WIDGET_CLASS(_elm_frame_parent_sc)->base.add(obj);
edje_object_signal_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, "elm,anim,done", "elm",
_on_recalc_done, obj);
edje_object_signal_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,click", "elm",
_on_frame_clicked, obj);
elm_widget_can_focus_set(obj, EINA_FALSE);
elm_layout_theme_set(obj, "frame", "base", elm_widget_style_get(obj));
}
static void
_elm_frame_smart_set_user(Elm_Layout_Smart_Class *sc)
{
ELM_WIDGET_CLASS(sc)->base.add = _elm_frame_smart_add;
ELM_WIDGET_CLASS(sc)->base.calculate = _elm_frame_smart_calculate;
ELM_WIDGET_CLASS(sc)->focus_next = _elm_frame_smart_focus_next;
sc->content_aliases = _content_aliases;
sc->text_aliases = _text_aliases;
}
EAPI Evas_Object *
elm_frame_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
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);
elm_widget_focus_next_hook_set(obj, _elm_frame_focus_next_hook);
elm_widget_can_focus_set(obj, EINA_FALSE);
elm_widget_text_set_hook_set(obj, _elm_frame_label_set);
elm_widget_text_get_hook_set(obj, _elm_frame_label_get);
elm_widget_content_set_hook_set(obj, _content_set_hook);
elm_widget_content_get_hook_set(obj, _content_get_hook);
elm_widget_content_unset_hook_set(obj, _content_unset_hook);
obj = evas_object_smart_add(e, _elm_frame_smart_class_new());
wd->frm = edje_object_add(e);
_elm_theme_object_set(obj, wd->frm, "frame", "base", "default");
elm_widget_resize_object_set(obj, wd->frm);
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
elm_layout_sizing_eval(obj);
evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
edje_object_signal_callback_add(wd->frm, "elm,anim,done", "elm",
_recalc_done, obj);
edje_object_signal_callback_add(wd->frm, "elm,action,click", "elm",
_signal_click, obj);
evas_object_smart_callbacks_descriptions_set(obj, _signals);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_sizing_eval(obj);
return obj;
}
EAPI void
elm_frame_autocollapse_set(Evas_Object *obj,
Eina_Bool autocollapse)
elm_frame_autocollapse_set(Evas_Object *obj, Eina_Bool autocollapse)
{
ELM_FRAME_CHECK(obj);
ELM_FRAME_DATA_GET_OR_RETURN(obj, sd);
sd->collapsible = !!autocollapse;
Widget_Data *wd;
ELM_CHECK_WIDTYPE(obj, widtype);
wd = elm_widget_data_get(obj);
if (!wd) return;
wd->collapsible = !!autocollapse;
}
EAPI Eina_Bool
elm_frame_autocollapse_get(const Evas_Object *obj)
{
ELM_FRAME_CHECK(obj) EINA_FALSE;
ELM_FRAME_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE);
return sd->collapsible;
Widget_Data *wd;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->collapsible;
}
EAPI void
elm_frame_collapse_set(Evas_Object *obj,
Eina_Bool collapse)
elm_frame_collapse_set(Evas_Object *obj, Eina_Bool collapse)
{
ELM_FRAME_CHECK(obj);
ELM_FRAME_DATA_GET_OR_RETURN(obj, sd);
Widget_Data *wd;
ELM_CHECK_WIDTYPE(obj, widtype);
wd = elm_widget_data_get(obj);
if (!wd) return;
collapse = !!collapse;
if (sd->collapsed == collapse) return;
elm_layout_signal_emit(obj, "elm,action,switch", "elm");
edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
sd->collapsed = !!collapse;
sd->anim = EINA_FALSE;
_sizing_eval(obj, sd);
if (wd->collapsed == collapse) return;
edje_object_signal_emit(wd->frm, "elm,action,switch", "elm");
edje_object_message_signal_process(wd->frm);
wd->collapsed = !!collapse;
wd->anim = EINA_FALSE;
_sizing_eval(obj);
}
EAPI void
elm_frame_collapse_go(Evas_Object *obj,
Eina_Bool collapse)
elm_frame_collapse_go(Evas_Object *obj, Eina_Bool collapse)
{
ELM_FRAME_CHECK(obj);
ELM_FRAME_DATA_GET_OR_RETURN(obj, sd);
Widget_Data *wd;
ELM_CHECK_WIDTYPE(obj, widtype);
wd = elm_widget_data_get(obj);
if (!wd) return;
collapse = !!collapse;
if (sd->collapsed == collapse) return;
elm_layout_signal_emit(obj, "elm,action,toggle", "elm");
evas_object_smart_callback_add
(ELM_WIDGET_DATA(sd)->resize_obj, "recalc", _recalc, obj);
sd->collapsed = collapse;
sd->anim = EINA_TRUE;
if (wd->collapsed == collapse) return;
edje_object_signal_emit(wd->frm, "elm,action,toggle", "elm");
evas_object_smart_callback_add(wd->frm, "recalc", _recalc, obj);
wd->collapsed = collapse;
wd->anim = EINA_TRUE;
}
EAPI Eina_Bool
elm_frame_collapse_get(const Evas_Object *obj)
{
ELM_FRAME_CHECK(obj) EINA_FALSE;
ELM_FRAME_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE);
return sd->collapsed;
Widget_Data *wd;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->collapsed;
}

View File

@ -19,11 +19,7 @@
*
* Of all this styles only default shows the title.
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for frame objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* Smart callbacks one can listen to:
* - @c "clicked" - The user has clicked the frame's label
*
* Default content parts of the frame widget that you can use for are:

View File

@ -1,385 +1,330 @@
#include <Elementary.h>
#include "elm_priv.h"
static const char GLVIEW_SMART_NAME[] = "elm_glview";
typedef struct _Widget_Data Widget_Data;
#define ELM_GLVIEW_DATA_GET(o, sd) \
Elm_Glview_Smart_Data * sd = evas_object_smart_data_get(o)
#define ELM_GLVIEW_DATA_GET_OR_RETURN(o, ptr) \
ELM_GLVIEW_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define ELM_GLVIEW_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_GLVIEW_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_GLVIEW_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), GLVIEW_SMART_NAME, __func__)) \
return
typedef struct _Elm_Glview_Smart_Data Elm_Glview_Smart_Data;
struct _Elm_Glview_Smart_Data
struct _Widget_Data
{
Elm_Widget_Smart_Data base; /* base widget smart data as
* first member obligatory, as
* we're inheriting from it */
Evas_Object *glview_image;
Elm_GLView_Mode mode;
Elm_GLView_Resize_Policy scale_policy;
Elm_GLView_Render_Policy render_policy;
Elm_GLView_Mode mode;
Elm_GLView_Resize_Policy scale_policy;
Elm_GLView_Render_Policy render_policy;
Evas_GL *evasgl;
Evas_GL_Config *config;
Evas_GL_Surface *surface;
Evas_GL_Context *context;
Evas_GL *evasgl;
Evas_GL_Config *config;
Evas_GL_Surface *surface;
Evas_GL_Context *context;
Evas_Coord w, h;
Evas_Coord w, h;
Elm_GLView_Func_Cb init_func;
Elm_GLView_Func_Cb del_func;
Elm_GLView_Func_Cb resize_func;
Elm_GLView_Func_Cb render_func;
Elm_GLView_Func_Cb init_func;
Elm_GLView_Func_Cb del_func;
Elm_GLView_Func_Cb resize_func;
Elm_GLView_Func_Cb render_func;
Ecore_Idle_Enterer *render_idle_enterer;
Ecore_Idle_Enterer *render_idle_enterer;
Eina_Bool initialized : 1;
Eina_Bool resized : 1;
Eina_Bool initialized;
Eina_Bool resized;
};
static const char *widtype = NULL;
static void _del_hook(Evas_Object *obj);
static void _on_focus_hook(void *data, Evas_Object *obj);
static const char SIG_FOCUSED[] = "focused";
static const char SIG_UNFOCUSED[] = "unfocused";
/* smart callbacks coming from elm glview objects: */
static const Evas_Smart_Cb_Description _smart_callbacks[] = {
{SIG_FOCUSED, ""},
{SIG_UNFOCUSED, ""},
{NULL, NULL}
};
EVAS_SMART_SUBCLASS_NEW
(GLVIEW_SMART_NAME, _elm_glview, Elm_Widget_Smart_Class,
Elm_Widget_Smart_Class, elm_widget_smart_class_get, _smart_callbacks);
static Eina_Bool
_elm_glview_smart_on_focus(Evas_Object *obj)
static void
_del_hook(Evas_Object *obj)
{
ELM_GLVIEW_DATA_GET(obj, sd);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
// Call delete func if it's registered
if (wd->del_func)
{
evas_gl_make_current(wd->evasgl, wd->surface, wd->context);
wd->del_func(obj);
}
if (wd->render_idle_enterer) ecore_idle_enterer_del(wd->render_idle_enterer);
if (wd->surface) evas_gl_surface_destroy(wd->evasgl, wd->surface);
if (wd->context) evas_gl_context_destroy(wd->evasgl, wd->context);
if (wd->config) evas_gl_config_free(wd->config);
if (wd->evasgl) evas_gl_free(wd->evasgl);
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))
{
evas_object_focus_set(ELM_WIDGET_DATA(sd)->resize_obj, EINA_TRUE);
evas_object_focus_set(wd->glview_image, EINA_TRUE);
evas_object_smart_callback_call(obj, SIG_FOCUSED, NULL);
}
else
{
evas_object_focus_set(ELM_WIDGET_DATA(sd)->resize_obj, EINA_FALSE);
evas_object_focus_set(wd->glview_image, EINA_FALSE);
evas_object_smart_callback_call(obj, SIG_UNFOCUSED, NULL);
}
return EINA_TRUE;
}
static void
_glview_update_surface(Evas_Object *obj)
{
ELM_GLVIEW_DATA_GET(obj, sd);
if (!sd) return;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (sd->surface)
if (wd->surface)
{
evas_object_image_native_surface_set
(ELM_WIDGET_DATA(sd)->resize_obj, NULL);
evas_gl_surface_destroy(sd->evasgl, sd->surface);
sd->surface = NULL;
evas_object_image_native_surface_set(wd->glview_image, NULL);
evas_gl_surface_destroy(wd->evasgl, wd->surface);
wd->surface = NULL;
}
evas_object_image_size_set(ELM_WIDGET_DATA(sd)->resize_obj, sd->w, sd->h);
evas_object_image_size_set(wd->glview_image, wd->w, wd->h);
if (!sd->surface)
if (!wd->surface)
{
Evas_Native_Surface ns;
sd->surface = evas_gl_surface_create
(sd->evasgl, sd->config, sd->w, sd->h);
evas_gl_native_surface_get(sd->evasgl, sd->surface, &ns);
evas_object_image_native_surface_set
(ELM_WIDGET_DATA(sd)->resize_obj, &ns);
wd->surface = evas_gl_surface_create(wd->evasgl, wd->config,
wd->w, wd->h);
evas_gl_native_surface_get(wd->evasgl, wd->surface, &ns);
evas_object_image_native_surface_set(wd->glview_image, &ns);
elm_glview_changed_set(obj);
}
}
static void
_elm_glview_smart_resize(Evas_Object *obj,
Evas_Coord w,
Evas_Coord h)
_glview_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
ELM_GLVIEW_DATA_GET(obj, sd);
Widget_Data *wd = elm_widget_data_get(data);
Evas_Coord w, h;
_elm_glview_parent_sc->base.resize(obj, w, h);
if (!wd) return;
sd->resized = EINA_TRUE;
wd->resized = EINA_TRUE;
if (sd->scale_policy == ELM_GLVIEW_RESIZE_POLICY_RECREATE)
if (wd->scale_policy == ELM_GLVIEW_RESIZE_POLICY_RECREATE)
{
evas_object_geometry_get(wd->glview_image, NULL, NULL, &w, &h);
if ((w == 0) || (h == 0))
{
w = 64;
h = 64;
}
if ((sd->w == w) && (sd->h == h)) return;
sd->w = w;
sd->h = h;
_glview_update_surface(obj);
if ((wd->w == w) && (wd->h == h)) return;
wd->w = w;
wd->h = h;
_glview_update_surface(data);
}
}
static Eina_Bool
_render_cb(void *obj)
{
ELM_GLVIEW_DATA_GET(obj, sd);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
// Do a make current
if (!evas_gl_make_current(sd->evasgl, sd->surface, sd->context))
if (!evas_gl_make_current(wd->evasgl, wd->surface, wd->context))
{
sd->render_idle_enterer = NULL;
wd->render_idle_enterer = NULL;
ERR("Failed doing make current.\n");
return EINA_FALSE;
}
// Call the init function if it hasn't been called already
if (!sd->initialized)
if (!wd->initialized)
{
if (sd->init_func) sd->init_func(obj);
sd->initialized = EINA_TRUE;
if (wd->init_func) wd->init_func(obj);
wd->initialized = EINA_TRUE;
}
if (sd->resized)
if (wd->resized)
{
if (sd->resize_func) sd->resize_func(obj);
sd->resized = EINA_FALSE;
if (wd->resize_func) wd->resize_func(obj);
wd->resized = EINA_FALSE;
}
// Call the render function
if (sd->render_func) sd->render_func(obj);
if (wd->render_func) wd->render_func(obj);
// Depending on the policy return true or false
if (sd->render_policy == ELM_GLVIEW_RENDER_POLICY_ON_DEMAND)
if (wd->render_policy == ELM_GLVIEW_RENDER_POLICY_ON_DEMAND)
return EINA_TRUE;
else if (sd->render_policy == ELM_GLVIEW_RENDER_POLICY_ALWAYS)
else if (wd->render_policy == ELM_GLVIEW_RENDER_POLICY_ALWAYS)
{
// Return false so it only runs once
sd->render_idle_enterer = NULL;
wd->render_idle_enterer = NULL;
return EINA_FALSE;
}
else
{
ERR("Invalid Render Policy.\n");
sd->render_idle_enterer = NULL;
wd->render_idle_enterer = NULL;
return EINA_FALSE;
}
return EINA_TRUE;
}
static void
_set_render_policy_callback(Evas_Object *obj)
{
ELM_GLVIEW_DATA_GET(obj, sd);
Widget_Data *wd = elm_widget_data_get(obj);
switch (sd->render_policy)
switch (wd->render_policy)
{
case ELM_GLVIEW_RENDER_POLICY_ON_DEMAND:
// Delete idle_enterer if it for some reason is around
if (sd->render_idle_enterer)
{
ecore_idle_enterer_del(sd->render_idle_enterer);
sd->render_idle_enterer = NULL;
}
// Set pixel getter callback
evas_object_image_pixels_get_callback_set
(ELM_WIDGET_DATA(sd)->resize_obj,
(Evas_Object_Image_Pixels_Get_Cb)_render_cb,
obj);
break;
// Delete idle_enterer if it for some reason is around
if (wd->render_idle_enterer)
{
ecore_idle_enterer_del(wd->render_idle_enterer);
wd->render_idle_enterer = NULL;
}
// Set pixel getter callback
evas_object_image_pixels_get_callback_set
(wd->glview_image, (Evas_Object_Image_Pixels_Get_Cb)_render_cb, obj);
break;
case ELM_GLVIEW_RENDER_POLICY_ALWAYS:
// Unset the pixel getter callback if set already
evas_object_image_pixels_get_callback_set
(ELM_WIDGET_DATA(sd)->resize_obj, NULL, NULL);
break;
// Unset the pixel getter callback if set already
evas_object_image_pixels_get_callback_set(wd->glview_image, NULL, NULL);
break;
default:
ERR("Invalid Render Policy.\n");
return;
ERR("Invalid Render Policy.\n");
return;
}
}
static void
_elm_glview_smart_add(Evas_Object *obj)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Glview_Smart_Data);
// Create image to render Evas_GL Surface
ELM_WIDGET_DATA(priv)->resize_obj =
evas_object_image_filled_add(evas_object_evas_get(obj));
evas_object_image_size_set(ELM_WIDGET_DATA(priv)->resize_obj, 1, 1);
_elm_glview_parent_sc->base.add(obj);
}
static void
_elm_glview_smart_del(Evas_Object *obj)
{
ELM_GLVIEW_DATA_GET(obj, sd);
// Call delete func if it's registered
if (sd->del_func)
{
evas_gl_make_current(sd->evasgl, sd->surface, sd->context);
sd->del_func(obj);
}
if (sd->render_idle_enterer) ecore_idle_enterer_del(sd->render_idle_enterer);
if (sd->surface) evas_gl_surface_destroy(sd->evasgl, sd->surface);
if (sd->context) evas_gl_context_destroy(sd->evasgl, sd->context);
if (sd->config) evas_gl_config_free(sd->config);
if (sd->evasgl) evas_gl_free(sd->evasgl);
_elm_glview_parent_sc->base.del(obj); /* handles freeing sd */
}
static void
_elm_glview_smart_set_user(Elm_Widget_Smart_Class *sc)
{
sc->base.add = _elm_glview_smart_add;
sc->base.del = _elm_glview_smart_del;
sc->base.resize = _elm_glview_smart_resize;
sc->on_focus = _elm_glview_smart_on_focus;
}
EAPI Evas_Object *
elm_glview_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
obj = evas_object_smart_add(e, _elm_glview_smart_class_new());
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
ELM_GLVIEW_DATA_GET(obj, sd);
ELM_SET_WIDTYPE(widtype, "glview");
elm_widget_type_set(obj, "glview");
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);
// Evas_GL
sd->evasgl = evas_gl_new(e);
if (!sd->evasgl)
wd->evasgl = evas_gl_new(e);
if (!wd->evasgl)
{
ERR("Failed Creating an Evas GL Object.\n");
return NULL;
}
// Create a default config
sd->config = evas_gl_config_new();
if (!sd->config)
wd->config = evas_gl_config_new();
if (!wd->config)
{
ERR("Failed Creating a Config Object.\n");
evas_object_del(obj);
evas_gl_free(wd->evasgl);
return NULL;
}
sd->config->color_format = EVAS_GL_RGB_888;
wd->config->color_format = EVAS_GL_RGB_888;
// Create image to render Evas_GL Surface
wd->glview_image = evas_object_image_filled_add(e);
evas_object_image_size_set(wd->glview_image, 1, 1);
evas_object_event_callback_add(wd->glview_image, EVAS_CALLBACK_RESIZE,
_glview_resize, obj);
elm_widget_resize_object_set(obj, wd->glview_image);
evas_object_show(wd->glview_image);
// Initialize variables
sd->mode = 0;
sd->scale_policy = ELM_GLVIEW_RESIZE_POLICY_RECREATE;
sd->render_policy = ELM_GLVIEW_RENDER_POLICY_ON_DEMAND;
sd->surface = NULL;
wd->mode = 0;
wd->scale_policy = ELM_GLVIEW_RESIZE_POLICY_RECREATE;
wd->render_policy = ELM_GLVIEW_RENDER_POLICY_ON_DEMAND;
wd->surface = NULL;
// Initialize it to (64,64) (It's an arbitrary value)
sd->w = 64;
sd->h = 64;
wd->w = 64;
wd->h = 64;
// Initialize the rest of the values
sd->init_func = NULL;
sd->del_func = NULL;
sd->render_func = NULL;
sd->render_idle_enterer = NULL;
sd->initialized = EINA_FALSE;
sd->resized = EINA_FALSE;
wd->init_func = NULL;
wd->del_func = NULL;
wd->render_func = NULL;
wd->render_idle_enterer = NULL;
wd->initialized = EINA_FALSE;
wd->resized = EINA_FALSE;
// Create Context
sd->context = evas_gl_context_create(sd->evasgl, NULL);
if (!sd->context)
if (!wd->context)
{
ERR("Error Creating an Evas_GL Context.\n");
evas_object_del(obj);
return NULL;
wd->context = evas_gl_context_create(wd->evasgl, NULL);
if (!wd->context)
{
ERR("Error Creating an Evas_GL Context.\n");
return NULL;
}
}
return obj;
}
EAPI Evas_GL_API *
elm_glview_gl_api_get(const Evas_Object *obj)
{
ELM_GLVIEW_CHECK(obj) NULL;
ELM_GLVIEW_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
return evas_gl_api_get(sd->evasgl);
return evas_gl_api_get(wd->evasgl);
}
EAPI Eina_Bool
elm_glview_mode_set(Evas_Object *obj,
Elm_GLView_Mode mode)
elm_glview_mode_set(Evas_Object *obj, Elm_GLView_Mode mode)
{
ELM_GLVIEW_CHECK(obj) EINA_FALSE;
ELM_GLVIEW_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
// Set the configs
if (mode & ELM_GLVIEW_ALPHA) sd->config->color_format = EVAS_GL_RGBA_8888;
else sd->config->color_format = EVAS_GL_RGB_888;
if (mode & ELM_GLVIEW_ALPHA)
wd->config->color_format = EVAS_GL_RGBA_8888;
else
wd->config->color_format = EVAS_GL_RGB_888;
if (mode & ELM_GLVIEW_DEPTH) sd->config->depth_bits = EVAS_GL_DEPTH_BIT_24;
else sd->config->depth_bits = EVAS_GL_DEPTH_NONE;
if (mode & ELM_GLVIEW_DEPTH)
wd->config->depth_bits = EVAS_GL_DEPTH_BIT_24;
else
wd->config->depth_bits = EVAS_GL_DEPTH_NONE;
if (mode & ELM_GLVIEW_STENCIL)
sd->config->stencil_bits = EVAS_GL_STENCIL_BIT_8;
else sd->config->stencil_bits = EVAS_GL_STENCIL_NONE;
wd->config->stencil_bits = EVAS_GL_STENCIL_BIT_8;
else
wd->config->stencil_bits = EVAS_GL_STENCIL_NONE;
if (mode & ELM_GLVIEW_DIRECT)
sd->config->options_bits = EVAS_GL_OPTIONS_DIRECT;
else sd->config->options_bits = EVAS_GL_OPTIONS_NONE;
wd->config->options_bits = EVAS_GL_OPTIONS_DIRECT;
else
wd->config->options_bits = EVAS_GL_OPTIONS_NONE;
// Check for Alpha Channel and enable it
if (mode & ELM_GLVIEW_ALPHA)
evas_object_image_alpha_set(ELM_WIDGET_DATA(sd)->resize_obj, EINA_TRUE);
evas_object_image_alpha_set(wd->glview_image, EINA_TRUE);
else
evas_object_image_alpha_set(ELM_WIDGET_DATA(sd)->resize_obj, EINA_FALSE);
evas_object_image_alpha_set(wd->glview_image, EINA_FALSE);
sd->mode = mode;
wd->mode = mode;
elm_glview_changed_set(obj);
@ -387,34 +332,33 @@ elm_glview_mode_set(Evas_Object *obj,
}
EAPI Eina_Bool
elm_glview_resize_policy_set(Evas_Object *obj,
Elm_GLView_Resize_Policy policy)
elm_glview_resize_policy_set(Evas_Object *obj, Elm_GLView_Resize_Policy policy)
{
ELM_GLVIEW_CHECK(obj) EINA_FALSE;
ELM_GLVIEW_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
if (policy == sd->scale_policy) return EINA_TRUE;
if (policy == wd->scale_policy) return EINA_TRUE;
switch (policy)
{
case ELM_GLVIEW_RESIZE_POLICY_RECREATE:
case ELM_GLVIEW_RESIZE_POLICY_SCALE:
sd->scale_policy = policy;
_glview_update_surface(obj);
elm_glview_changed_set(obj);
return EINA_TRUE;
wd->scale_policy = policy;
_glview_update_surface(obj);
elm_glview_changed_set(obj);
return EINA_TRUE;
default:
ERR("Invalid Scale Policy.\n");
return EINA_FALSE;
ERR("Invalid Scale Policy.\n");
return EINA_FALSE;
}
}
EAPI Eina_Bool
elm_glview_render_policy_set(Evas_Object *obj,
Elm_GLView_Render_Policy policy)
elm_glview_render_policy_set(Evas_Object *obj, Elm_GLView_Render_Policy policy)
{
ELM_GLVIEW_CHECK(obj) EINA_FALSE;
ELM_GLVIEW_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
if ((policy != ELM_GLVIEW_RENDER_POLICY_ON_DEMAND) &&
(policy != ELM_GLVIEW_RENDER_POLICY_ALWAYS))
@ -422,97 +366,97 @@ elm_glview_render_policy_set(Evas_Object *obj,
ERR("Invalid Render Policy.\n");
return EINA_FALSE;
}
if (sd->render_policy == policy) return EINA_TRUE;
sd->render_policy = policy;
if (wd->render_policy == policy) return EINA_TRUE;
wd->render_policy = policy;
_set_render_policy_callback(obj);
_glview_update_surface(obj);
return EINA_TRUE;
}
EAPI void
elm_glview_size_set(Evas_Object *obj,
int w,
int h)
elm_glview_size_set(Evas_Object *obj, int w, int h)
{
ELM_GLVIEW_CHECK(obj);
ELM_GLVIEW_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if ((w == sd->w) && (h == sd->h)) return;
sd->w = w;
sd->h = h;
if ((w == wd->w) && (h == wd->h)) return;
wd->w = w;
wd->h = h;
_glview_update_surface(obj);
elm_glview_changed_set(obj);
}
EAPI void
elm_glview_size_get(const Evas_Object *obj,
int *w,
int *h)
elm_glview_size_get(const Evas_Object *obj, int *w, int *h)
{
ELM_GLVIEW_CHECK(obj);
ELM_GLVIEW_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (w) *w = sd->w;
if (h) *h = sd->h;
if (w) *w = wd->w;
if (h) *h = wd->h;
}
EAPI void
elm_glview_init_func_set(Evas_Object *obj,
Elm_GLView_Func_Cb func)
elm_glview_init_func_set(Evas_Object *obj, Elm_GLView_Func_Cb func)
{
ELM_GLVIEW_CHECK(obj);
ELM_GLVIEW_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
sd->initialized = EINA_FALSE;
sd->init_func = func;
wd->initialized = EINA_FALSE;
wd->init_func = func;
}
EAPI void
elm_glview_del_func_set(Evas_Object *obj,
Elm_GLView_Func_Cb func)
elm_glview_del_func_set(Evas_Object *obj, Elm_GLView_Func_Cb func)
{
ELM_GLVIEW_CHECK(obj);
ELM_GLVIEW_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
sd->del_func = func;
wd->del_func = func;
}
EAPI void
elm_glview_resize_func_set(Evas_Object *obj,
Elm_GLView_Func_Cb func)
elm_glview_resize_func_set(Evas_Object *obj, Elm_GLView_Func_Cb func)
{
ELM_GLVIEW_CHECK(obj);
ELM_GLVIEW_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd)
{
ERR("Invalid Widget Object.\n");
return;
}
sd->resize_func = func;
wd->resize_func = func;
}
EAPI void
elm_glview_render_func_set(Evas_Object *obj,
Elm_GLView_Func_Cb func)
elm_glview_render_func_set(Evas_Object *obj, Elm_GLView_Func_Cb func)
{
ELM_GLVIEW_CHECK(obj);
ELM_GLVIEW_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
sd->render_func = func;
wd->render_func = func;
_set_render_policy_callback(obj);
}
EAPI void
elm_glview_changed_set(Evas_Object *obj)
{
ELM_GLVIEW_CHECK(obj);
ELM_GLVIEW_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_image_pixels_dirty_set
(ELM_WIDGET_DATA(sd)->resize_obj, EINA_TRUE);
if (sd->render_policy == ELM_GLVIEW_RENDER_POLICY_ALWAYS &&
!sd->render_idle_enterer)
sd->render_idle_enterer =
ecore_idle_enterer_before_add((Ecore_Task_Cb)_render_cb, obj);
evas_object_image_pixels_dirty_set(wd->glview_image, EINA_TRUE);
if (wd->render_policy == ELM_GLVIEW_RENDER_POLICY_ALWAYS)
{
if (!wd->render_idle_enterer)
wd->render_idle_enterer = ecore_idle_enterer_before_add((Ecore_Task_Cb)_render_cb, obj);
}
}
/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0 :*/

View File

@ -1,50 +1,35 @@
#include <Elementary.h>
#include "elm_priv.h"
static const char GRID_SMART_NAME[] = "elm_grid";
typedef struct _Widget_Data Widget_Data;
typedef struct _Elm_Grid_Smart_Data Elm_Grid_Smart_Data;
struct _Widget_Data
{
Evas_Object *obj, *grd;
};
#define ELM_GRID_DATA_GET(o, sd) \
Elm_Widget_Smart_Data * sd = evas_object_smart_data_get(o)
static const char *widtype = NULL;
static void _del_hook(Evas_Object *obj);
static void _theme_hook(Evas_Object *obj);
#define ELM_GRID_DATA_GET_OR_RETURN(o, ptr) \
ELM_GRID_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define ELM_GRID_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_GRID_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_GRID_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), GRID_SMART_NAME, __func__)) \
return
EVAS_SMART_SUBCLASS_NEW
(GRID_SMART_NAME, _elm_grid, Elm_Widget_Smart_Class,
Elm_Widget_Smart_Class, elm_widget_smart_class_get, NULL);
static void
_del_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
free(wd);
}
static Eina_Bool
_elm_grid_smart_focus_next(const Evas_Object *obj,
Elm_Focus_Direction dir,
Evas_Object **next)
_elm_grid_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
{
Eina_Bool ret;
Widget_Data *wd = elm_widget_data_get(obj);
const Eina_List *items;
Eina_List *(*list_free)(Eina_List *list);
void *(*list_data_get)(const Eina_List *list);
void *(*list_data_get) (const Eina_List *list);
Eina_List *(*list_free) (Eina_List *list);
ELM_GRID_DATA_GET(obj, sd);
if ((!wd) || (!wd->grd))
return EINA_FALSE;
/* Focus chain */
/* TODO: Change this to use other chain */
@ -55,16 +40,18 @@ _elm_grid_smart_focus_next(const Evas_Object *obj,
}
else
{
items = evas_object_grid_children_get(sd->resize_obj);
items = evas_object_grid_children_get(wd->grd);
list_data_get = eina_list_data_get;
list_free = eina_list_free;
if (!items) return EINA_FALSE;
}
ret = elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next);
Eina_Bool ret = elm_widget_focus_list_next_get(obj, items, list_data_get,
dir, next);
if (list_free) list_free((Eina_List *)items);
if (list_free)
list_free((Eina_List *)items);
return ret;
}
@ -72,190 +59,119 @@ _elm_grid_smart_focus_next(const Evas_Object *obj,
static void
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
ELM_GRID_DATA_GET(obj, sd);
evas_object_grid_mirrored_set(sd->resize_obj, rtl);
Widget_Data *wd = elm_widget_data_get(obj);
if ((!wd) || (!wd->grd)) return;
evas_object_grid_mirrored_set(wd->grd, rtl);
}
static Eina_Bool
_elm_grid_smart_theme(Evas_Object *obj)
static void
_theme_hook(Evas_Object *obj)
{
if (!_elm_grid_parent_sc->theme(obj)) return EINA_FALSE;
_elm_widget_mirrored_reload(obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
return EINA_TRUE;
}
static void
_elm_grid_smart_add(Evas_Object *obj)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Widget_Smart_Data);
priv->resize_obj = evas_object_grid_add(evas_object_evas_get(obj));
evas_object_grid_size_set(priv->resize_obj, 100, 100);
_elm_grid_parent_sc->base.add(obj);
elm_widget_can_focus_set(obj, EINA_FALSE);
_elm_grid_smart_theme(obj);
}
static void
_elm_grid_smart_del(Evas_Object *obj)
{
Eina_List *l;
Evas_Object *child;
ELM_GRID_DATA_GET(obj, sd);
/* let's make our grid object the *last* to be processed, since it
* may (smart) parent other sub objects here */
EINA_LIST_FOREACH (sd->subobjs, l, child)
{
if (child == sd->resize_obj)
{
sd->subobjs = eina_list_demote_list(sd->subobjs, l);
break;
}
}
_elm_grid_parent_sc->base.del(obj);
}
static void
_elm_grid_smart_set_user(Elm_Widget_Smart_Class *sc)
{
sc->base.add = _elm_grid_smart_add;
sc->base.del = _elm_grid_smart_del;
sc->theme = _elm_grid_smart_theme;
sc->focus_next = _elm_grid_smart_focus_next;
}
EAPI Evas_Object *
elm_grid_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
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_focus_next_hook_set(obj, _elm_grid_focus_next_hook);
elm_widget_can_focus_set(obj, EINA_FALSE);
elm_widget_theme_hook_set(obj, _theme_hook);
e = evas_object_evas_get(parent);
if (!e) return NULL;
obj = evas_object_smart_add(e, _elm_grid_smart_class_new());
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
wd->grd = evas_object_grid_add(e);
evas_object_grid_size_set(wd->grd, 100, 100);
elm_widget_resize_object_set(obj, wd->grd);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
return obj;
}
EAPI void
elm_grid_size_set(Evas_Object *obj,
Evas_Coord w,
Evas_Coord h)
elm_grid_size_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
{
ELM_GRID_CHECK(obj);
ELM_GRID_DATA_GET(obj, sd);
evas_object_grid_size_set(sd->resize_obj, w, h);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_grid_size_set(wd->grd, w, h);
}
EAPI void
elm_grid_size_get(const Evas_Object *obj,
Evas_Coord *w,
Evas_Coord *h)
elm_grid_size_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
{
ELM_GRID_CHECK(obj);
ELM_GRID_DATA_GET(obj, sd);
evas_object_grid_size_get(sd->resize_obj, w, h);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_grid_size_get(wd->grd, w, h);
}
EAPI void
elm_grid_pack(Evas_Object *obj,
Evas_Object *subobj,
Evas_Coord x,
Evas_Coord y,
Evas_Coord w,
Evas_Coord h)
elm_grid_pack(Evas_Object *obj, Evas_Object *subobj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
{
ELM_GRID_CHECK(obj);
ELM_GRID_DATA_GET(obj, sd);
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_grid_pack(sd->resize_obj, subobj, x, y, w, h);
evas_object_grid_pack(wd->grd, subobj, x, y, w, h);
}
EAPI void
elm_grid_unpack(Evas_Object *obj,
Evas_Object *subobj)
elm_grid_unpack(Evas_Object *obj, Evas_Object *subobj)
{
ELM_GRID_CHECK(obj);
ELM_GRID_DATA_GET(obj, sd);
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_grid_unpack(sd->resize_obj, subobj);
evas_object_grid_unpack(wd->grd, subobj);
}
EAPI void
elm_grid_clear(Evas_Object *obj,
Eina_Bool clear)
elm_grid_clear(Evas_Object *obj, Eina_Bool clear)
{
Eina_List *chld;
Evas_Object *o;
ELM_GRID_CHECK(obj);
ELM_GRID_DATA_GET(obj, sd);
if (!clear)
{
chld = evas_object_grid_children_get(sd->resize_obj);
EINA_LIST_FREE (chld, o)
elm_widget_sub_object_del(obj, o);
}
evas_object_grid_clear(sd->resize_obj, clear);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
chld = evas_object_grid_children_get(wd->grd);
EINA_LIST_FREE(chld, o) elm_widget_sub_object_del(obj, o);
evas_object_grid_clear(wd->grd, clear);
}
EAPI void
elm_grid_pack_set(Evas_Object *subobj,
Evas_Coord x,
Evas_Coord y,
Evas_Coord w,
Evas_Coord h)
elm_grid_pack_set(Evas_Object *subobj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
{
Evas_Object *obj = elm_widget_parent_widget_get(subobj);
ELM_GRID_CHECK(obj);
ELM_GRID_DATA_GET(obj, sd);
evas_object_grid_pack(sd->resize_obj, subobj, x, y, w, h);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_grid_pack(wd->grd, subobj, x, y, w, h);
}
EAPI void
elm_grid_pack_get(Evas_Object *subobj,
int *x,
int *y,
int *w,
int *h)
elm_grid_pack_get(Evas_Object *subobj, int *x, int *y, int *w, int *h)
{
Evas_Object *obj = elm_widget_parent_widget_get(subobj);
ELM_GRID_CHECK(obj);
ELM_GRID_DATA_GET(obj, sd);
evas_object_grid_pack_get(sd->resize_obj, subobj, x, y, w, h);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_grid_pack_get(wd->grd, subobj, x, y, w, h);
}
EAPI Eina_List *
elm_grid_children_get(const Evas_Object *obj)
{
ELM_GRID_CHECK(obj) NULL;
ELM_GRID_DATA_GET(obj, sd);
return evas_object_grid_children_get(sd->resize_obj);
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
return evas_object_grid_children_get(wd->grd);
}

File diff suppressed because it is too large Load Diff

View File

@ -24,26 +24,34 @@
* @li menu
* @li hoversel_vertical
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for hover objects.
* The following are the available position for content:
* @li left
* @li top-left
* @li top
* @li top-right
* @li right
* @li bottom-right
* @li bottom
* @li bottom-left
* @li middle
* @li smart
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* @li @c "clicked" - the user clicked the empty space in the hover to dismiss
* @li @c "smart,changed" - a content object placed under the "smart"
* Signals that you can add callbacks for are:
* @li "clicked" - the user clicked the empty space in the hover to dismiss
* @li "smart,changed" - a content object placed under the "smart"
* policy was replaced to a new slot direction.
*
* Default content parts of the hover widget that you can use for are:
* @li @c "left"
* @li @c "top-left"
* @li @c "top"
* @li @c "top-right"
* @li @c "right"
* @li @c "bottom-right"
* @li @c "bottom"
* @li @c "bottom-left"
* @li @c "middle"
* @li @c "smart"
* @li "left"
* @li "top-left"
* @li "top"
* @li "top-right"
* @li "right"
* @li "bottom-right"
* @li "bottom"
* @li "bottom-left"
* @li "middle"
* @li "smart"
*
* @note These content parts indicates the direction that the content will be
* displayed

File diff suppressed because it is too large Load Diff

View File

@ -21,11 +21,7 @@
* List "lists", @ref Genlist "generic lists" or @ref Gengrid
* "general grids".
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for index objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* Smart events one can add callbacks for are:
* - @c "changed" - When the selected index item changes. @c
* event_info is the selected item's data pointer.
* - @c "delay,changed" - When the selected index item changes, but

View File

@ -1,213 +1,138 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_layout.h"
static const char LABEL_SMART_NAME[] = "elm_label";
typedef struct _Widget_Data Widget_Data;
typedef struct _Elm_Label_Smart_Data Elm_Label_Smart_Data;
struct _Elm_Label_Smart_Data
struct _Widget_Data
{
Elm_Layout_Smart_Data base;
const char *format;
double slide_duration;
Evas_Coord lastw;
Evas_Coord wrap_w;
Elm_Wrap_Type linewrap;
Eina_Bool ellipsis : 1;
Eina_Bool slidingmode : 1;
Eina_Bool slidingellipsis : 1;
Evas_Object *lbl;
const char *label;
const char *format;
Ecore_Job *deferred_recalc_job;
double slide_duration;
Evas_Coord lastw;
Evas_Coord wrap_w;
Elm_Wrap_Type linewrap;
Eina_Bool changed : 1;
Eina_Bool ellipsis : 1;
Eina_Bool slidingmode : 1;
Eina_Bool slidingellipsis : 1;
};
#define ELM_LABEL_DATA_GET(o, sd) \
Elm_Label_Smart_Data * sd = evas_object_smart_data_get(o)
#define ELM_LABEL_DATA_GET_OR_RETURN(o, ptr) \
ELM_LABEL_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define ELM_LABEL_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_LABEL_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_LABEL_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), LABEL_SMART_NAME, __func__)) \
return
static const Elm_Layout_Part_Alias_Description _text_aliases[] =
{
{"default", "elm.text"},
{NULL, NULL}
};
/* Inheriting from elm_layout. Besides, we need no more than what is
* there */
EVAS_SMART_SUBCLASS_NEW
(LABEL_SMART_NAME, _elm_label, Elm_Layout_Smart_Class,
Elm_Layout_Smart_Class, elm_layout_smart_class_get, NULL);
static const char *widtype = NULL;
static void _del_hook(Evas_Object *obj);
static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
static void _theme_hook(Evas_Object *obj);
static void _sizing_eval(Evas_Object *obj);
static int _get_value_in_key_string(const char *oldstring, const char *key, char **value);
static int _strbuf_key_value_replace(Eina_Strbuf *srcbuf, const char *key, const char *value, int deleteflag);
static int _stringshare_key_value_replace(const char **srcstring, const char *key, const char *value, int deleteflag);
static void _label_sliding_change(Evas_Object *obj);
static void _label_format_set(Evas_Object *obj, const char *format);
static void
_recalc(void *data)
_elm_recalc_job(void *data)
{
ELM_LABEL_DATA_GET(data, sd);
Widget_Data *wd = elm_widget_data_get(data);
Evas_Coord minw = -1, minh = -1;
Evas_Coord resw;
if (!wd) return;
evas_event_freeze(evas_object_evas_get(data));
evas_object_geometry_get
(ELM_WIDGET_DATA(sd)->resize_obj, NULL, NULL, &resw, NULL);
if (sd->wrap_w > resw)
resw = sd->wrap_w;
edje_object_size_min_restricted_calc
(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, resw, 0);
wd->deferred_recalc_job = NULL;
evas_object_geometry_get(wd->lbl, NULL, NULL, &resw, NULL);
if (wd->wrap_w > resw)
resw = wd->wrap_w;
edje_object_size_min_restricted_calc(wd->lbl, &minw, &minh, resw, 0);
/* This is a hack to workaround the way min size hints are treated.
* If the minimum width is smaller than the restricted width, it means
* the mininmum doesn't matter. */
if ((minw <= resw) && (minw != sd->wrap_w))
if ((minw <= resw) && (minw != wd->wrap_w))
{
Evas_Coord ominw = -1;
evas_object_size_hint_min_get(data, &ominw, NULL);
minw = ominw;
}
evas_object_size_hint_min_set(data, minw, minh);
evas_event_thaw(evas_object_evas_get(data));
evas_event_thaw_eval(evas_object_evas_get(data));
}
static void
_label_format_set(Evas_Object *obj,
const char *format)
_del_hook(Evas_Object *obj)
{
if (format)
edje_object_part_text_style_user_push(obj, "elm.text", format);
else
edje_object_part_text_style_user_pop(obj, "elm.text");
}
static void
_label_sliding_change(Evas_Object *obj)
{
char *plaintxt;
int plainlen = 0;
ELM_LABEL_DATA_GET(obj, sd);
// doesn't support multiline sliding effect
if (sd->linewrap)
{
sd->slidingmode = EINA_FALSE;
return;
}
plaintxt = _elm_util_mkup_to_text
(edje_object_part_text_get
(ELM_WIDGET_DATA(sd)->resize_obj, "elm.text"));
if (plaintxt != NULL)
{
plainlen = strlen(plaintxt);
free(plaintxt);
}
// too short to slide label
if (plainlen < 1)
{
sd->slidingmode = EINA_TRUE;
return;
}
if (sd->slidingmode)
{
Edje_Message_Float_Set *msg =
alloca(sizeof(Edje_Message_Float_Set) + (sizeof(double)));
if (sd->ellipsis)
{
sd->slidingellipsis = EINA_TRUE;
elm_label_ellipsis_set(obj, EINA_FALSE);
}
msg->count = 1;
msg->val[0] = sd->slide_duration;
edje_object_message_send
(ELM_WIDGET_DATA(sd)->resize_obj, EDJE_MESSAGE_FLOAT_SET, 0, msg);
edje_object_signal_emit
(ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,slide,start", "elm");
}
else
{
edje_object_signal_emit
(ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,slide,stop", "elm");
if (sd->slidingellipsis)
{
sd->slidingellipsis = EINA_FALSE;
elm_label_ellipsis_set(obj, EINA_TRUE);
}
}
}
static Eina_Bool
_elm_label_smart_theme(Evas_Object *obj)
{
Eina_Bool ret;
ELM_LABEL_DATA_GET(obj, sd);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_event_freeze(evas_object_evas_get(obj));
ret = ELM_WIDGET_CLASS(_elm_label_parent_sc)->theme(obj);
if (!ret) goto end;
_label_format_set(ELM_WIDGET_DATA(sd)->resize_obj, sd->format);
_label_sliding_change(obj);
end:
if (wd->deferred_recalc_job) ecore_job_del(wd->deferred_recalc_job);
if (wd->label) eina_stringshare_del(wd->label);
free(wd);
evas_event_thaw(evas_object_evas_get(obj));
evas_event_thaw_eval(evas_object_evas_get(obj));
return ret;
}
static void
_elm_label_smart_sizing_eval(Evas_Object *obj)
_theme_change(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
_elm_theme_object_set(obj, wd->lbl, "label", "base",
elm_widget_style_get(obj));
}
static void
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
edje_object_mirrored_set(wd->lbl, rtl);
}
static void
_theme_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_event_freeze(evas_object_evas_get(obj));
_elm_widget_mirrored_reload(obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_theme_change(obj);
_label_format_set(wd->lbl, wd->format);
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);
_label_sliding_change(obj);
_sizing_eval(obj);
evas_event_thaw(evas_object_evas_get(obj));
evas_event_thaw_eval(evas_object_evas_get(obj));
}
static void
_sizing_eval(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
Evas_Coord minw = -1, minh = -1;
Evas_Coord resw, resh;
if (!wd) return;
ELM_LABEL_DATA_GET(obj, sd);
if (sd->linewrap)
if (wd->linewrap)
{
evas_object_geometry_get
(ELM_WIDGET_DATA(sd)->resize_obj, NULL, NULL, &resw, &resh);
if (resw == sd->lastw) return;
sd->lastw = resw;
_recalc(obj);
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_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_recalc_job, obj);
}
else
{
evas_event_freeze(evas_object_evas_get(obj));
evas_object_geometry_get
(ELM_WIDGET_DATA(sd)->resize_obj, NULL, NULL, &resw, &resh);
edje_object_size_min_calc
(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh);
if (sd->wrap_w > 0 && minw > sd->wrap_w) minw = sd->wrap_w;
evas_object_geometry_get(wd->lbl, NULL, NULL, &resw, &resh);
edje_object_size_min_calc(wd->lbl, &minw, &minh);
if (wd->wrap_w > 0 && minw > wd->wrap_w) minw = wd->wrap_w;
evas_object_size_hint_min_set(obj, minw, minh);
evas_event_thaw(evas_object_evas_get(obj));
evas_event_thaw_eval(evas_object_evas_get(obj));
@ -215,20 +140,24 @@ _elm_label_smart_sizing_eval(Evas_Object *obj)
}
static void
_on_label_resize(void *data,
Evas *e __UNUSED__,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_lbl_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
ELM_LABEL_DATA_GET(data, sd);
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return;
if (wd->linewrap) _sizing_eval(data);
}
if (sd->linewrap) elm_layout_sizing_eval(data);
static void
_label_format_set(Evas_Object *obj, const char *format)
{
if (format)
edje_object_part_text_style_user_push(obj, "elm.text", format);
else
edje_object_part_text_style_user_pop(obj, "elm.text");
}
static int
_get_value_in_key_string(const char *oldstring,
const char *key,
char **value)
_get_value_in_key_string(const char *oldstring, const char *key, char **value)
{
char *curlocater, *endtag;
int firstindex = 0, foundflag = -1;
@ -259,11 +188,9 @@ _get_value_in_key_string(const char *oldstring,
return -1;
}
static int
_strbuf_key_value_replace(Eina_Strbuf *srcbuf,
const char *key,
const char *value,
int deleteflag)
_strbuf_key_value_replace(Eina_Strbuf *srcbuf, const char *key, const char *value, int deleteflag)
{
char *kvalue;
const char *srcstring = NULL;
@ -278,9 +205,9 @@ _strbuf_key_value_replace(Eina_Strbuf *srcbuf,
val_end = strchr(kvalue, ' ');
if (val_end)
val_end_idx = val_end - srcstring;
val_end_idx = val_end - srcstring;
else
val_end_idx = kvalue - srcstring + strlen(kvalue) - 1;
val_end_idx = kvalue - srcstring + strlen(kvalue) - 1;
/* -1 is because of the '=' */
key_start_idx = kvalue - srcstring - 1 - strlen(key);
@ -288,7 +215,7 @@ _strbuf_key_value_replace(Eina_Strbuf *srcbuf,
if (!deleteflag)
{
eina_strbuf_insert_printf(srcbuf, "%s=%s", key_start_idx, key,
value);
value);
}
}
else if (!deleteflag)
@ -296,24 +223,19 @@ _strbuf_key_value_replace(Eina_Strbuf *srcbuf,
if (*srcstring)
{
/* -1 because we want it before the ' */
eina_strbuf_insert_printf
(srcbuf, " %s=%s", eina_strbuf_length_get(srcbuf) - 1, key,
value);
eina_strbuf_insert_printf(srcbuf, " %s=%s",
eina_strbuf_length_get(srcbuf) - 1, key, value);
}
else
{
eina_strbuf_append_printf(srcbuf, "DEFAULT='%s=%s'", key, value);
}
}
return 0;
}
static int
_stringshare_key_value_replace(const char **srcstring,
const char *key,
const char *value,
int deleteflag)
_stringshare_key_value_replace(const char **srcstring, const char *key, const char *value, int deleteflag)
{
Eina_Strbuf *sharebuf = NULL;
@ -327,190 +249,223 @@ _stringshare_key_value_replace(const char **srcstring,
return 0;
}
static Eina_Bool
_elm_label_smart_text_set(Evas_Object *obj,
const char *item,
const char *label)
static void
_label_sliding_change(Evas_Object *obj)
{
ELM_LABEL_DATA_GET(obj, sd);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
char *plaintxt;
int plainlen = 0;
if (!label) label = "";
_label_format_set(ELM_WIDGET_DATA(sd)->resize_obj, sd->format);
// dosen't support multiline sliding effect
if (wd->linewrap)
{
wd->slidingmode = EINA_FALSE;
return;
}
return _elm_label_parent_sc->text_set(obj, item, label);
plaintxt = _elm_util_mkup_to_text(edje_object_part_text_get(wd->lbl, "elm.text"));
if (plaintxt != NULL)
{
plainlen = strlen(plaintxt);
free(plaintxt);
}
// too short to slide label
if (plainlen < 1)
{
wd->slidingmode = EINA_TRUE;
return;
}
if (wd->slidingmode)
{
Edje_Message_Float_Set *msg = alloca(sizeof(Edje_Message_Float_Set) + (sizeof(double)));
if (wd->ellipsis)
{
wd->slidingellipsis = EINA_TRUE;
elm_label_ellipsis_set(obj, EINA_FALSE);
}
msg->count = 1;
msg->val[0] = wd->slide_duration;
edje_object_message_send(wd->lbl, EDJE_MESSAGE_FLOAT_SET, 0, msg);
edje_object_signal_emit(wd->lbl, "elm,state,slide,start", "elm");
}
else
{
edje_object_signal_emit(wd->lbl, "elm,state,slide,stop", "elm");
if (wd->slidingellipsis)
{
wd->slidingellipsis = EINA_FALSE;
elm_label_ellipsis_set(obj, EINA_TRUE);
}
}
}
static Eina_Bool
_elm_label_smart_translate(Evas_Object *obj)
static void
_elm_label_label_set(Evas_Object *obj, const char *item, const char *label)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (item && strcmp(item, "default")) return;
if (!label) label = "";
eina_stringshare_replace(&wd->label, label);
_label_format_set(wd->lbl, wd->format);
edje_object_part_text_set(wd->lbl, "elm.text", wd->label);
wd->changed = 1;
_sizing_eval(obj);
}
static const char *
_elm_label_label_get(const Evas_Object *obj, const char *item)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (item && strcmp(item, "default")) return NULL;
if (!wd) return NULL;
return wd->label;
}
static void
_translate_hook(Evas_Object *obj)
{
evas_object_smart_callback_call(obj, "language,changed", NULL);
return EINA_TRUE;
}
static void
_elm_label_smart_add(Evas_Object *obj)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Label_Smart_Data);
ELM_WIDGET_CLASS(_elm_label_parent_sc)->base.add(obj);
priv->linewrap = ELM_WRAP_NONE;
priv->ellipsis = EINA_FALSE;
priv->slidingmode = EINA_FALSE;
priv->slidingellipsis = EINA_FALSE;
priv->wrap_w = -1;
priv->slide_duration = 10;
priv->format = eina_stringshare_add("");
_label_format_set(ELM_WIDGET_DATA(priv)->resize_obj, priv->format);
evas_object_event_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, EVAS_CALLBACK_RESIZE,
_on_label_resize, obj);
elm_widget_can_focus_set(obj, EINA_FALSE);
elm_layout_theme_set(obj, "label", "base", elm_widget_style_get(obj));
elm_layout_text_set(obj, NULL, "<br>");
}
static void
_elm_label_smart_set_user(Elm_Layout_Smart_Class *sc)
{
ELM_WIDGET_CLASS(sc)->base.add = _elm_label_smart_add;
ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */
ELM_WIDGET_CLASS(sc)->theme = _elm_label_smart_theme;
ELM_WIDGET_CLASS(sc)->translate = _elm_label_smart_translate;
sc->sizing_eval = _elm_label_smart_sizing_eval;
sc->text_set = _elm_label_smart_text_set;
sc->text_aliases = _text_aliases;
}
EAPI Evas_Object *
elm_label_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
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, EINA_FALSE);
elm_widget_text_set_hook_set(obj, _elm_label_label_set);
elm_widget_text_get_hook_set(obj, _elm_label_label_get);
elm_widget_translate_hook_set(obj, _translate_hook);
obj = evas_object_smart_add(e, _elm_label_smart_class_new());
wd->linewrap = ELM_WRAP_NONE;
wd->ellipsis = EINA_FALSE;
wd->slidingmode = EINA_FALSE;
wd->slidingellipsis = EINA_FALSE;
wd->wrap_w = -1;
wd->slide_duration = 10;
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
wd->lbl = edje_object_add(e);
_elm_theme_object_set(obj, wd->lbl, "label", "base", "default");
wd->format = eina_stringshare_add("");
wd->label = eina_stringshare_add("<br>");
_label_format_set(wd->lbl, wd->format);
edje_object_part_text_set(wd->lbl, "elm.text", wd->label);
elm_layout_sizing_eval(obj);
elm_widget_resize_object_set(obj, wd->lbl);
evas_object_event_callback_add(wd->lbl, EVAS_CALLBACK_RESIZE, _lbl_resize, obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
wd->changed = 1;
_sizing_eval(obj);
return obj;
}
EAPI void
elm_label_line_wrap_set(Evas_Object *obj,
Elm_Wrap_Type wrap)
elm_label_line_wrap_set(Evas_Object *obj, Elm_Wrap_Type wrap)
{
const char *wrap_str, *text;
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
const char *wrap_str;
int len;
ELM_LABEL_CHECK(obj);
ELM_LABEL_DATA_GET(obj, sd);
if (sd->linewrap == wrap) return;
sd->linewrap = wrap;
text = elm_layout_text_get(obj, NULL);
if (!text) return;
len = strlen(text);
if (!wd) return;
if (wd->linewrap == wrap) return;
wd->linewrap = wrap;
len = strlen(wd->label);
if (len <= 0) return;
switch (wrap)
{
case ELM_WRAP_CHAR:
wrap_str = "char";
break;
wrap_str = "char";
break;
case ELM_WRAP_WORD:
wrap_str = "word";
break;
wrap_str = "word";
break;
case ELM_WRAP_MIXED:
wrap_str = "mixed";
break;
wrap_str = "mixed";
break;
default:
wrap_str = "none";
break;
wrap_str = "none";
break;
}
if (_stringshare_key_value_replace(&sd->format, "wrap", wrap_str, 0) == 0)
if (_stringshare_key_value_replace(&wd->format,
"wrap", wrap_str, 0) == 0)
{
_label_format_set(ELM_WIDGET_DATA(sd)->resize_obj, sd->format);
elm_layout_sizing_eval(obj);
_label_format_set(wd->lbl, wd->format);
edje_object_part_text_set(wd->lbl, "elm.text", wd->label);
wd->changed = 1;
_sizing_eval(obj);
}
}
EAPI Elm_Wrap_Type
elm_label_line_wrap_get(const Evas_Object *obj)
{
ELM_LABEL_CHECK(obj) EINA_FALSE;
ELM_LABEL_DATA_GET(obj, sd);
return sd->linewrap;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->linewrap;
}
EAPI void
elm_label_wrap_width_set(Evas_Object *obj,
Evas_Coord w)
elm_label_wrap_width_set(Evas_Object *obj, Evas_Coord w)
{
ELM_LABEL_CHECK(obj);
ELM_LABEL_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (w < 0) w = 0;
if (sd->wrap_w == w) return;
if (sd->ellipsis)
_label_format_set(ELM_WIDGET_DATA(sd)->resize_obj, sd->format);
sd->wrap_w = w;
elm_layout_sizing_eval(obj);
if (wd->wrap_w == w) return;
if (wd->ellipsis)
{
_label_format_set(wd->lbl, wd->format);
edje_object_part_text_set(wd->lbl, "elm.text", wd->label);
}
wd->wrap_w = w;
_sizing_eval(obj);
}
EAPI Evas_Coord
elm_label_wrap_width_get(const Evas_Object *obj)
{
ELM_LABEL_CHECK(obj) 0;
ELM_LABEL_DATA_GET(obj, sd);
return sd->wrap_w;
ELM_CHECK_WIDTYPE(obj, widtype) 0;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return 0;
return wd->wrap_w;
}
EAPI void
elm_label_ellipsis_set(Evas_Object *obj,
Eina_Bool ellipsis)
elm_label_ellipsis_set(Evas_Object *obj, Eina_Bool ellipsis)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
Eina_Strbuf *fontbuf = NULL;
int len, removeflag = 0;
const char *text;
ELM_LABEL_CHECK(obj);
ELM_LABEL_DATA_GET(obj, sd);
if (sd->ellipsis == ellipsis) return;
sd->ellipsis = ellipsis;
text = elm_layout_text_get(obj, NULL);
if (!text) return;
len = strlen(text);
if (!wd) return;
if (wd->ellipsis == ellipsis) return;
wd->ellipsis = ellipsis;
len = strlen(wd->label);
if (len <= 0) return;
if (ellipsis == EINA_FALSE) removeflag = 1; // remove fontsize tag
@ -518,69 +473,71 @@ elm_label_ellipsis_set(Evas_Object *obj,
fontbuf = eina_strbuf_new();
eina_strbuf_append_printf(fontbuf, "%f", 1.0);
if (_stringshare_key_value_replace
(&sd->format, "ellipsis", eina_strbuf_string_get
(fontbuf), removeflag) == 0)
if (_stringshare_key_value_replace(&wd->format,
"ellipsis", eina_strbuf_string_get(fontbuf), removeflag) == 0)
{
_label_format_set(ELM_WIDGET_DATA(sd)->resize_obj, sd->format);
elm_layout_sizing_eval(obj);
_label_format_set(wd->lbl, wd->format);
edje_object_part_text_set(wd->lbl, "elm.text", wd->label);
wd->changed = 1;
_sizing_eval(obj);
}
eina_strbuf_free(fontbuf);
}
EAPI Eina_Bool
elm_label_ellipsis_get(const Evas_Object *obj)
{
ELM_LABEL_CHECK(obj) EINA_FALSE;
ELM_LABEL_DATA_GET(obj, sd);
return sd->ellipsis;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->ellipsis;
}
EAPI void
elm_label_slide_set(Evas_Object *obj,
Eina_Bool slide)
Eina_Bool slide)
{
ELM_LABEL_CHECK(obj);
ELM_LABEL_DATA_GET(obj, sd);
if (sd->slidingmode == slide) return;
sd->slidingmode = slide;
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->slidingmode == slide) return;
wd->slidingmode = slide;
_label_sliding_change(obj);
elm_layout_sizing_eval(obj);
wd->changed = 1;
_sizing_eval(obj);
}
EAPI Eina_Bool
elm_label_slide_get(const Evas_Object *obj)
{
ELM_LABEL_CHECK(obj) EINA_FALSE;
ELM_LABEL_DATA_GET(obj, sd);
return sd->slidingmode;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->slidingmode;
}
EAPI void
elm_label_slide_duration_set(Evas_Object *obj, double duration)
{
ELM_LABEL_CHECK(obj);
ELM_LABEL_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
Edje_Message_Float_Set *msg = alloca(sizeof(Edje_Message_Float_Set) + (sizeof(double)));
Edje_Message_Float_Set *msg =
alloca(sizeof(Edje_Message_Float_Set) + (sizeof(double)));
sd->slide_duration = duration;
if (!wd) return;
wd->slide_duration = duration;
msg->count = 1;
msg->val[0] = sd->slide_duration;
edje_object_message_send
(ELM_WIDGET_DATA(sd)->resize_obj, EDJE_MESSAGE_FLOAT_SET, 0, msg);
msg->val[0] = wd->slide_duration;
edje_object_message_send(wd->lbl, EDJE_MESSAGE_FLOAT_SET, 0, msg);
}
EAPI double
elm_label_slide_duration_get(const Evas_Object *obj)
{
ELM_LABEL_CHECK(obj) 0.0;
ELM_LABEL_DATA_GET(obj, sd);
return sd->slide_duration;
ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return 0;
return wd->slide_duration;
}

View File

@ -25,12 +25,8 @@
* Custom themes can of course invent new markup tags and style them any way
* they like.
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for label objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* @li @c "language,changed": The program's language changed.
* The following signals may be emitted by the label widget:
* @li "language,changed": The program's language changed.
*
* See @ref tutorial_label for a demonstration of how to use a label widget.
* @{

File diff suppressed because it is too large Load Diff

View File

@ -188,70 +188,10 @@ EAPI Eina_Bool elm_layout_file_set(Evas_Object *obj, const ch
*
* @return (1 = success, 0 = error)
*
* Note that @a style will be the new style of @a obj too, as in an
* elm_object_style_set() call.
*
* @ingroup Layout
*/
EAPI Eina_Bool elm_layout_theme_set(Evas_Object *obj, const char *clas, const char *group, const char *style);
/**
* Send a (Edje) signal to a given layout widget's underlying Edje
* object.
*
* @param obj The layout object handle
* @param emission The signal's name string
* @param source The signal's source string
*
* This function sends a signal to the underlying Edje object of @a
* obj. An Edje program on that Edje object's definition can respond
* to a signal by specifying matching 'signal' and 'source' fields.
*
* @ingroup Layout
*/
EAPI void elm_layout_signal_emit(Evas_Object *obj, const char *emission, const char *source);
/**
* Add a callback for a (Edje) signal emitted by a layout widget's
* underlying Edje object.
*
* @param obj The layout object handle
* @param emission The signal's name string
* @param source The signal's source string
* @param func The callback function to be executed when the signal is
* emitted.
* @param data A pointer to data to pass in to the callback function.
*
* This function connects a callback function to a signal emitted by
* the underlying Edje object of @a obj. Globs are accepted in either
* the emission or source strings (see @c
* edje_object_signal_callback_add()).
*
* @ingroup Layout
*/
EAPI void elm_layout_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func, void *data);
/**
* Remove a signal-triggered callback from a given layout widget.
*
* @param obj The layout object handle
* @param emission The signal's name string
* @param source The signal's source string
* @param func The callback function being executed when the signal
* was emitted.
* @return The data pointer of the signal callback (passed on
* elm_layout_signal_callback_add()) or @c NULL, on errors.
*
* This function removes the @b last callback attached to a signal
* emitted by the undelying Edje object of @a obj, with parameters @a
* emission, @a source and @c func matching exactly those passed to a
* previous call to elm_object_signal_callback_add(). The data pointer
* that was passed to this call will be returned.
*
* @ingroup Layout
*/
EAPI void *elm_layout_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func);
/**
* Append child to layout box part.
*
@ -637,71 +577,6 @@ EAPI Eina_Bool elm_layout_part_cursor_engine_only_set(Evas_Ob
*/
EAPI Eina_Bool elm_layout_part_cursor_engine_only_get(const Evas_Object *obj, const char *part_name);
/**
* Set the layout content.
*
* @param obj The layout object
* @param swallow The swallow part name in the edje file
* @param content The child that will be added in this layout object
* @return @c EINA_TRUE on success, @c EINA_FALSE otherwise
*
* Once the content object is set, a previously set one will be deleted.
* If you want to keep that old content object, use the
* elm_object_part_content_unset() function.
*
* @note In an Edje theme, the part used as a content container is called @c
* SWALLOW. This is why the parameter name is called @p swallow, but it is
* expected to be a part name just like the second parameter of
* elm_layout_box_append().
*
* @see elm_layout_box_append()
* @see elm_object_part_content_get()
* @see elm_object_part_content_unset()
* @see @ref secBox
*/
EAPI Eina_Bool elm_layout_content_set(Evas_Object *obj, const char *swallow, Evas_Object *content);
/**
* Get the child object in the given content part.
*
* @param obj The layout object
* @param swallow The SWALLOW part to get its content
*
* @return The swallowed object or NULL if none or an error occurred
*/
EAPI Evas_Object *elm_layout_content_get(const Evas_Object *obj, const char *swallow);
/**
* Unset the layout content.
*
* @param obj The layout object
* @param swallow The swallow part name in the edje file
* @return The content that was being used
*
* Unparent and return the content object which was set for this part.
*/
EAPI Evas_Object *elm_layout_content_unset(Evas_Object *obj, const char *swallow);
/**
* Set the text of the given part
*
* @param obj The layout object
* @param part The TEXT part where to set the text
* @param text The text to set
* @return @c EINA_TRUE on success, @c EINA_FALSE otherwise
*/
EAPI Eina_Bool elm_layout_text_set(Evas_Object *obj, const char *part, const char *text);
/**
* Get the text set in the given part
*
* @param obj The layout object
* @param part The TEXT part to retrieve the text off
*
* @return The text set in @p part
*/
EAPI const char *elm_layout_text_get(const Evas_Object *obj, const char *part);
/**
* @def elm_layout_icon_set
* Convenience macro to set the icon object in a layout that follows the
@ -754,6 +629,10 @@ EAPI const char *elm_layout_text_get(const Evas_Object *obj, co
#define elm_layout_end_get(_ly) \
elm_object_part_content_get((_ly), "elm.swallow.end")
/* smart callbacks called:
* "theme,changed" - when elm theme is changed.
*/
/**
* @}
*/

View File

@ -1,371 +1,305 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_container.h"
static const char MAPBUF_SMART_NAME[] = "elm_mapbuf";
typedef struct _Widget_Data Widget_Data;
typedef struct _Elm_Mapbuf_Smart_Data Elm_Mapbuf_Smart_Data;
struct _Elm_Mapbuf_Smart_Data
struct _Widget_Data
{
Elm_Widget_Smart_Data base;
Evas_Object *content;
Eina_Bool enabled : 1;
Eina_Bool smooth : 1;
Eina_Bool alpha : 1;
Evas_Object *content, *clip;
Eina_Bool enabled : 1;
Eina_Bool alpha : 1;
Eina_Bool smooth : 1;
};
#define ELM_MAPBUF_DATA_GET(o, sd) \
Elm_Mapbuf_Smart_Data * sd = evas_object_smart_data_get(o)
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);
#define ELM_MAPBUF_DATA_GET_OR_RETURN(o, ptr) \
ELM_MAPBUF_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
static void
_del_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
free(wd);
}
#define ELM_MAPBUF_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_MAPBUF_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_MAPBUF_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), MAPBUF_SMART_NAME, __func__)) \
return
EVAS_SMART_SUBCLASS_NEW
(MAPBUF_SMART_NAME, _elm_mapbuf, Elm_Container_Smart_Class,
Elm_Container_Smart_Class, elm_container_smart_class_get, NULL);
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;
ELM_MAPBUF_DATA_GET(obj, sd);
if (sd->content)
if (!wd) return;
if (wd->content)
{
evas_object_size_hint_min_get(sd->content, &minw, &minh);
evas_object_size_hint_max_get(sd->content, &maxw, &maxh);
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 Eina_Bool
_elm_mapbuf_smart_theme(Evas_Object *obj)
{
if (!ELM_WIDGET_CLASS(_elm_mapbuf_parent_sc)->theme(obj)) return EINA_FALSE;
_sizing_eval(obj);
return EINA_TRUE;
}
static void
_changed_size_hints_cb(void *data,
Evas *e __UNUSED__,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_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 Eina_Bool
_elm_mapbuf_smart_sub_object_del(Evas_Object *obj,
Evas_Object *sobj)
static void
_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
{
ELM_MAPBUF_DATA_GET(obj, sd);
if (!ELM_WIDGET_CLASS(_elm_mapbuf_parent_sc)->sub_object_del(obj, sobj))
return EINA_FALSE;
if (sobj == sd->content)
Widget_Data *wd = elm_widget_data_get(obj);
Evas_Object *sub = event_info;
if (!wd) return;
if (sub == wd->content)
{
evas_object_data_del(sobj, "_elm_leaveme");
evas_object_smart_member_del(sobj);
evas_object_clip_unset(sobj);
evas_object_event_callback_del_full
(sobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints_cb,
obj);
sd->content = NULL;
evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_changed_size_hints, obj);
wd->content = NULL;
_sizing_eval(obj);
}
return EINA_TRUE;
}
static void
_mapbuf(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
Evas_Coord x, y, w, h;
ELM_MAPBUF_DATA_GET(obj, sd);
evas_object_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, &x, &y, &w, &h);
if (sd->enabled)
if (!wd) return;
evas_object_geometry_get(wd->clip, &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, sd->smooth);
evas_map_alpha_set(m, sd->alpha);
evas_object_map_set(sd->content, m);
evas_object_map_enable_set(sd->content, EINA_TRUE);
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, EINA_TRUE);
evas_map_free(m);
}
else
{
evas_object_map_set(sd->content, NULL);
evas_object_map_enable_set(sd->content, EINA_FALSE);
evas_object_move(sd->content, x, y);
evas_object_resize(sd->content, w, h);
evas_object_map_set(wd->content, NULL);
evas_object_map_enable_set(wd->content, EINA_FALSE);
evas_object_move(wd->content, x, y);
evas_object_resize(wd->content, w, h);
}
}
static void
_configure(Evas_Object *obj)
{
ELM_MAPBUF_DATA_GET(obj, sd);
if (sd->content)
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->content)
{
Evas_Coord x, y, w, h, x2, y2;
evas_object_geometry_get
(ELM_WIDGET_DATA(sd)->resize_obj, &x, &y, &w, &h);
evas_object_geometry_get(sd->content, &x2, &y2, NULL, NULL);
evas_object_geometry_get(wd->clip, &x, &y, &w, &h);
evas_object_geometry_get(wd->content, &x2, &y2, NULL, NULL);
if ((x != x2) || (y != y2))
{
if (!sd->enabled)
evas_object_move(sd->content, x, y);
if (!wd->enabled)
evas_object_move(wd->content, x, y);
else
{
Evas *e = evas_object_evas_get(obj);
evas_smart_objects_calculate(e);
evas_nochange_push(e);
evas_object_move(sd->content, x, y);
evas_object_move(wd->content, x, y);
evas_smart_objects_calculate(e);
evas_nochange_pop(e);
}
}
evas_object_resize(sd->content, w, h);
evas_object_resize(wd->content, w, h);
_mapbuf(obj);
}
}
static void
_elm_mapbuf_smart_move(Evas_Object *obj,
Evas_Coord x,
Evas_Coord y)
_move(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
ELM_WIDGET_CLASS(_elm_mapbuf_parent_sc)->base.move(obj, x, y);
_configure(obj);
_configure(data);
}
static void
_elm_mapbuf_smart_resize(Evas_Object *obj,
Evas_Coord x,
Evas_Coord y)
_resize(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
ELM_WIDGET_CLASS(_elm_mapbuf_parent_sc)->base.resize(obj, x, y);
_configure(obj);
_configure(data);
}
static Eina_Bool
_elm_mapbuf_smart_content_set(Evas_Object *obj,
const char *part,
Evas_Object *content)
static void
_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
{
ELM_MAPBUF_DATA_GET(obj, sd);
if (part && strcmp(part, "default")) return EINA_FALSE;
if (sd->content == content) return EINA_TRUE;
if (sd->content) evas_object_del(sd->content);
sd->content = content;
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd;
if (part && strcmp(part, "default")) return;
wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->content == content) return;
if (wd->content) evas_object_del(wd->content);
wd->content = content;
if (content)
{
evas_object_data_set(content, "_elm_leaveme", (void *)1);
elm_widget_sub_object_add(obj, content);
evas_object_smart_member_add(content, obj);
evas_object_clip_set(content, ELM_WIDGET_DATA(sd)->resize_obj);
evas_object_color_set
(ELM_WIDGET_DATA(sd)->resize_obj, 255, 255, 255, 255);
evas_object_event_callback_add
(content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_changed_size_hints_cb, obj);
evas_object_clip_set(content, wd->clip);
evas_object_color_set(wd->clip, 255, 255, 255, 255);
evas_object_event_callback_add(content,
EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_changed_size_hints, obj);
}
else
evas_object_color_set(ELM_WIDGET_DATA(sd)->resize_obj, 0, 0, 0, 0);
evas_object_color_set(wd->clip, 0, 0, 0, 0);
_sizing_eval(obj);
_configure(obj);
return EINA_TRUE;
}
static Evas_Object *
_elm_mapbuf_smart_content_get(const Evas_Object *obj,
const char *part)
_content_get_hook(const Evas_Object *obj, const char *part)
{
ELM_MAPBUF_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd;
if (part && strcmp(part, "default")) return NULL;
return sd->content;
wd = elm_widget_data_get(obj);
if (!wd) return NULL;
return wd->content;
}
static Evas_Object *
_elm_mapbuf_smart_content_unset(Evas_Object *obj,
const char *part)
_content_unset_hook(Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd;
Evas_Object *content;
ELM_MAPBUF_DATA_GET(obj, sd);
if (part && strcmp(part, "default")) return NULL;
if (!sd->content) return NULL;
content = sd->content;
wd = elm_widget_data_get(obj);
if (!wd) return NULL;
if (!wd->content) return NULL;
content = wd->content;
elm_widget_sub_object_del(obj, content);
evas_object_smart_member_del(content);
evas_object_color_set(wd->clip, 0, 0, 0, 0);
evas_object_data_del(content, "_elm_leaveme");
evas_object_color_set(ELM_WIDGET_DATA(sd)->resize_obj, 0, 0, 0, 0);
return content;
}
static void
_elm_mapbuf_smart_add(Evas_Object *obj)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Mapbuf_Smart_Data);
ELM_WIDGET_DATA(priv)->resize_obj =
evas_object_rectangle_add(evas_object_evas_get(obj));
ELM_WIDGET_CLASS(_elm_mapbuf_parent_sc)->base.add(obj);
evas_object_static_clip_set(ELM_WIDGET_DATA(priv)->resize_obj, EINA_TRUE);
evas_object_pass_events_set(ELM_WIDGET_DATA(priv)->resize_obj, EINA_TRUE);
evas_object_color_set(ELM_WIDGET_DATA(priv)->resize_obj, 0, 0, 0, 0);
priv->enabled = 0;
priv->alpha = 1;
priv->smooth = 1;
elm_widget_can_focus_set(obj, EINA_FALSE);
_sizing_eval(obj);
}
static void
_elm_mapbuf_smart_set_user(Elm_Container_Smart_Class *sc)
{
ELM_WIDGET_CLASS(sc)->base.add = _elm_mapbuf_smart_add;
ELM_WIDGET_CLASS(sc)->base.resize = _elm_mapbuf_smart_resize;
ELM_WIDGET_CLASS(sc)->base.move = _elm_mapbuf_smart_move;
ELM_WIDGET_CLASS(sc)->theme = _elm_mapbuf_smart_theme;
ELM_WIDGET_CLASS(sc)->sub_object_del = _elm_mapbuf_smart_sub_object_del;
sc->content_set = _elm_mapbuf_smart_content_set;
sc->content_get = _elm_mapbuf_smart_content_get;
sc->content_unset = _elm_mapbuf_smart_content_unset;
}
EAPI Evas_Object *
elm_mapbuf_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
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);
elm_widget_content_set_hook_set(obj, _content_set_hook);
elm_widget_content_get_hook_set(obj, _content_get_hook);
elm_widget_content_unset_hook_set(obj, _content_unset_hook);
elm_widget_can_focus_set(obj, EINA_FALSE);
obj = evas_object_smart_add(e, _elm_mapbuf_smart_class_new());
wd->clip = evas_object_rectangle_add(e);
evas_object_static_clip_set(wd->clip, EINA_TRUE);
evas_object_pass_events_set(wd->clip, EINA_TRUE);
evas_object_color_set(wd->clip, 0, 0, 0, 0);
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
evas_object_event_callback_add(wd->clip, EVAS_CALLBACK_MOVE, _move, obj);
evas_object_event_callback_add(wd->clip, EVAS_CALLBACK_RESIZE, _resize, obj);
evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
elm_widget_resize_object_set(obj, wd->clip);
wd->enabled = 0;
wd->alpha = 1;
wd->smooth = 1;
_sizing_eval(obj);
return obj;
}
EAPI void
elm_mapbuf_enabled_set(Evas_Object *obj,
Eina_Bool enabled)
elm_mapbuf_enabled_set(Evas_Object *obj, Eina_Bool enabled)
{
ELM_MAPBUF_CHECK(obj);
ELM_MAPBUF_DATA_GET(obj, sd);
if (sd->enabled == enabled) return;
sd->enabled = enabled;
if (sd->content) evas_object_static_clip_set(sd->content, sd->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;
if (wd->content) evas_object_static_clip_set(wd->content, wd->enabled);
_configure(obj);
}
EAPI Eina_Bool
elm_mapbuf_enabled_get(const Evas_Object *obj)
{
ELM_MAPBUF_CHECK(obj) EINA_FALSE;
ELM_MAPBUF_DATA_GET(obj, sd);
return sd->enabled;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->enabled;
}
EAPI void
elm_mapbuf_smooth_set(Evas_Object *obj,
Eina_Bool smooth)
elm_mapbuf_smooth_set(Evas_Object *obj, Eina_Bool smooth)
{
ELM_MAPBUF_CHECK(obj);
ELM_MAPBUF_DATA_GET(obj, sd);
if (sd->smooth == smooth) return;
sd->smooth = 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);
}
EAPI Eina_Bool
elm_mapbuf_smooth_get(const Evas_Object *obj)
{
ELM_MAPBUF_CHECK(obj) EINA_FALSE;
ELM_MAPBUF_DATA_GET(obj, sd);
return sd->smooth;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->smooth;
}
EAPI void
elm_mapbuf_alpha_set(Evas_Object *obj,
Eina_Bool alpha)
elm_mapbuf_alpha_set(Evas_Object *obj, Eina_Bool alpha)
{
ELM_MAPBUF_CHECK(obj);
ELM_MAPBUF_DATA_GET(obj, sd);
if (sd->alpha == alpha) return;
sd->alpha = 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);
}
EAPI Eina_Bool
elm_mapbuf_alpha_get(const Evas_Object *obj)
{
ELM_MAPBUF_CHECK(obj) EINA_FALSE;
ELM_MAPBUF_DATA_GET(obj, sd);
return sd->alpha;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->alpha;
}

View File

@ -12,16 +12,14 @@
* need to resize or move it frequently (the content object and its
* children).
*
* This widget inherits from @ref elm-container-class, so that the
* functions meant to act on it will wor work for mapbuf objects:
* Default content parts of the mapbuf widget that you can use for are:
* @li "default" - A content of the mapbuf
*
* Supported elm_object common APIs.
* @li @ref elm_object_part_content_set
* @li @ref elm_object_part_content_get
* @li @ref elm_object_part_content_unset
*
* Default content parts of the mapbuf widget that you can use are:
* @li "default" - The main content of the mapbuf
*
* To enable map, elm_mapbuf_enabled_set() should be used.
*
* See how to use this widget in this example:

File diff suppressed because it is too large Load Diff

View File

@ -14,16 +14,14 @@
* @li "timeout" - when timeout happens on notify and it's hidden
* @li "block,clicked" - when a click outside of the notify happens
*
* This widget inherits from @ref elm-container-class, so that the
* functions meant to act on it will wor work for mapbuf objects:
* Default content parts of the notify widget that you can use for are:
* @li "default" - A content of the notify
*
* Supported elm_object common APIs.
* @li @ref elm_object_part_content_set
* @li @ref elm_object_part_content_get
* @li @ref elm_object_part_content_unset
*
* Default content parts of the notify widget that you can use are:
* @li @c "default" - The main content of the notify
*
* @ref tutorial_notify show usage of the API.
*
* @{

View File

@ -1,6 +1,5 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_layout.h"
/**
* TODO
@ -9,142 +8,131 @@
* Add events (move, start ...)
*/
static const char PANES_SMART_NAME[] = "elm_panes";
typedef struct _Widget_Data Widget_Data;
typedef struct _Elm_Panes_Smart_Data Elm_Panes_Smart_Data;
struct _Elm_Panes_Smart_Data
struct _Widget_Data
{
Elm_Layout_Smart_Data base;
Evas_Object *panes;
struct
{
int x_diff;
int y_diff;
Eina_Bool move;
} move;
{
Evas_Object *left;
Evas_Object *right;
} contents;
Eina_Bool double_clicked : 1;
Eina_Bool horizontal : 1;
Eina_Bool fixed : 1;
struct
{
int x_diff;
int y_diff;
Eina_Bool move;
} move;
Eina_Bool clicked_double;
Eina_Bool horizontal;
Eina_Bool fixed;
};
static const char *widtype = NULL;
static void _del_hook(Evas_Object *obj);
static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
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 const char SIG_CLICKED[] = "clicked";
static const char SIG_PRESS[] = "press";
static const char SIG_UNPRESS[] = "unpress";
static const char SIG_DOUBLE_CLICKED[] = "clicked,double";
static const Evas_Smart_Cb_Description _smart_callbacks[] = {
static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
static const Evas_Smart_Cb_Description _signals[] = {
{SIG_CLICKED, ""},
{SIG_PRESS, ""},
{SIG_UNPRESS, ""},
{SIG_DOUBLE_CLICKED, ""},
{SIG_CLICKED_DOUBLE, ""},
{NULL, NULL}
};
static const Elm_Layout_Part_Alias_Description _content_aliases[] =
static void
_del_hook(Evas_Object *obj)
{
{"left", "elm.swallow.left"},
{"right", "elm.swallow.right"},
{NULL, NULL}
};
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
free(wd);
}
#define ELM_PANES_DATA_GET(o, sd) \
Elm_Panes_Smart_Data * sd = evas_object_smart_data_get(o)
#define ELM_PANES_DATA_GET_OR_RETURN(o, ptr) \
ELM_PANES_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define ELM_PANES_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_PANES_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_PANES_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), PANES_SMART_NAME, __func__)) \
return
/* Inheriting from elm_layout. Besides, we need no more than what is
* there */
EVAS_SMART_SUBCLASS_NEW
(PANES_SMART_NAME, _elm_panes, Elm_Layout_Smart_Class,
Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks);
static Eina_Bool
_elm_panes_smart_theme(Evas_Object *obj)
static void
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
edje_object_mirrored_set(wd->panes, rtl);
}
static void
_theme_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
const char *style = elm_widget_style_get(obj);
double size;
ELM_PANES_DATA_GET(obj, sd);
if (sd->horizontal)
eina_stringshare_replace(&(ELM_LAYOUT_DATA(sd)->group), "horizontal");
else
eina_stringshare_replace(&(ELM_LAYOUT_DATA(sd)->group), "vertical");
if (!ELM_WIDGET_CLASS(_elm_panes_parent_sc)->theme(obj)) return EINA_FALSE;
if (!wd) return;
_elm_widget_mirrored_reload(obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
size = elm_panes_content_left_size_get(obj);
if (sd->fixed) elm_layout_signal_emit(obj, "elm.panes.fixed", "elm");
if (wd->horizontal)
_elm_theme_object_set(obj, wd->panes, "panes", "horizontal", style);
else
_elm_theme_object_set(obj, wd->panes, "panes", "vertical", style);
elm_layout_sizing_eval(obj);
if (wd->contents.left)
edje_object_part_swallow(wd->panes, "elm.swallow.left", wd->contents.left);
if (wd->contents.right)
edje_object_part_swallow(wd->panes, "elm.swallow.right", wd->contents.right);
if (wd->fixed)
edje_object_signal_emit(wd->panes, "elm.panes.fixed", "elm");
edje_object_scale_set(wd->panes, elm_widget_scale_get(obj) *
_elm_config->scale);
_sizing_eval(obj);
elm_panes_content_left_size_set(obj, size);
return EINA_TRUE;
}
static Eina_Bool
_elm_panes_smart_focus_next(const Evas_Object *obj,
Elm_Focus_Direction dir,
Evas_Object **next)
_elm_panes_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
double w, h;
unsigned char i;
Evas_Object *to_focus;
edje_object_part_drag_value_get(wd->panes, "elm.bar", &w, &h);
if (((wd->horizontal) && ( h == 0.0 )) || ((!wd->horizontal) && ( w == 0.0 )))
return elm_widget_focus_next_get(wd->contents.right, dir, next);
Evas_Object *chain[2];
Evas_Object *left, *right;
ELM_PANES_DATA_GET(obj, sd);
edje_object_part_drag_value_get
(ELM_WIDGET_DATA(sd)->resize_obj, "elm.bar", &w, &h);
left = elm_layout_content_get(obj, "left");
right = elm_layout_content_get(obj, "right");
if (((sd->horizontal) && (h == 0.0)) || ((!sd->horizontal) && (w == 0.0)))
return elm_widget_focus_next_get(right, dir, next);
/* Direction */
if (dir == ELM_FOCUS_PREVIOUS)
{
chain[0] = right;
chain[1] = left;
chain[0] = wd->contents.right;
chain[1] = wd->contents.left;
}
else if (dir == ELM_FOCUS_NEXT)
{
chain[0] = left;
chain[1] = right;
chain[0] = wd->contents.left;
chain[1] = wd->contents.right;
}
else return EINA_FALSE;
else
return EINA_FALSE;
i = elm_widget_focus_get(chain[1]);
unsigned char i = elm_widget_focus_get(chain[1]);
if (elm_widget_focus_next_get(chain[i], dir, next)) return EINA_TRUE;
if (elm_widget_focus_next_get(chain[i], dir, next))
return EINA_TRUE;
i = !i;
Evas_Object *to_focus;
if (elm_widget_focus_next_get(chain[i], dir, &to_focus))
{
*next = to_focus;
@ -155,233 +143,328 @@ _elm_panes_smart_focus_next(const Evas_Object *obj,
}
static void
_on_clicked(void *data,
Evas_Object *obj __UNUSED__,
const char *emission __UNUSED__,
const char *source __UNUSED__)
_sizing_eval(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
}
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__)
{
Widget_Data *wd = elm_widget_data_get(obj);
Evas_Object *sub = event_info;
if (!wd) return;
if (sub == wd->contents.left)
{
evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_changed_size_hints, obj);
edje_object_part_unswallow(wd->panes, sub);
wd->contents.left = NULL;
_sizing_eval(obj);
}
else if (sub == wd->contents.right)
{
evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_changed_size_hints, obj);
edje_object_part_unswallow(wd->panes, sub);
wd->contents.right= NULL;
_sizing_eval(obj);
}
}
static void
_clicked(void *data, Evas_Object *obj __UNUSED__ , const char *emission __UNUSED__, const char *source __UNUSED__)
{
evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
}
static void
_double_clicked(void *data,
Evas_Object *obj __UNUSED__,
const char *emission __UNUSED__,
const char *source __UNUSED__)
_clicked_double(void *data, Evas_Object *obj __UNUSED__ , const char *emission __UNUSED__, const char *source __UNUSED__)
{
ELM_PANES_DATA_GET(data, sd);
Widget_Data *wd = elm_widget_data_get(data);
sd->double_clicked = EINA_TRUE;
wd->clicked_double = EINA_TRUE;
}
static void
_on_pressed(void *data,
Evas_Object *obj __UNUSED__,
const char *emission __UNUSED__,
const char *source __UNUSED__)
_press(void *data, Evas_Object *obj __UNUSED__ , const char *emission __UNUSED__, const char *source __UNUSED__)
{
evas_object_smart_callback_call(data, SIG_PRESS, NULL);
}
static void
_on_unpressed(void *data,
Evas_Object *obj __UNUSED__,
const char *emission __UNUSED__,
const char *source __UNUSED__)
_unpress(void *data, Evas_Object *obj __UNUSED__ , const char *emission __UNUSED__, const char *source __UNUSED__)
{
ELM_PANES_DATA_GET(data, sd);
Widget_Data *wd = elm_widget_data_get(data);
evas_object_smart_callback_call(data, SIG_UNPRESS, NULL);
if (sd->double_clicked)
if (wd->clicked_double)
{
evas_object_smart_callback_call(data, SIG_DOUBLE_CLICKED, NULL);
sd->double_clicked = EINA_FALSE;
evas_object_smart_callback_call(data, SIG_CLICKED_DOUBLE, NULL);
wd->clicked_double = EINA_FALSE;
}
}
static void
_elm_panes_smart_add(Evas_Object *obj)
_content_left_set(Evas_Object *obj, Evas_Object *content)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Panes_Smart_Data);
ELM_WIDGET_CLASS(_elm_panes_parent_sc)->base.add(obj);
elm_layout_theme_set(obj, "panes", "vertical", elm_widget_style_get(obj));
elm_panes_content_left_size_set(obj, 0.5);
edje_object_signal_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,click", "",
_on_clicked, obj);
edje_object_signal_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,click,double", "",
_double_clicked, obj);
edje_object_signal_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,press", "",
_on_pressed, obj);
edje_object_signal_callback_add
(ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,unpress", "",
_on_unpressed, obj);
elm_widget_can_focus_set(obj, EINA_FALSE);
elm_layout_sizing_eval(obj);
Widget_Data *wd = elm_widget_data_get(obj);
if (wd->contents.left == content) return;
if (wd->contents.left)
evas_object_del(wd->contents.left);
wd->contents.left = content;
if (content)
{
elm_widget_sub_object_add(obj, content);
edje_object_part_swallow(wd->panes, "elm.swallow.left", content);
}
}
static void
_elm_panes_smart_set_user(Elm_Layout_Smart_Class *sc)
_content_right_set(Evas_Object *obj, Evas_Object *content)
{
ELM_WIDGET_CLASS(sc)->base.add = _elm_panes_smart_add;
Widget_Data *wd = elm_widget_data_get(obj);
if (wd->contents.right == content) return;
if (wd->contents.right)
evas_object_del(wd->contents.right);
wd->contents.right = content;
if (content)
{
elm_widget_sub_object_add(obj, content);
edje_object_part_swallow(wd->panes, "elm.swallow.right", content);
}
}
ELM_WIDGET_CLASS(sc)->theme = _elm_panes_smart_theme;
ELM_WIDGET_CLASS(sc)->focus_next = _elm_panes_smart_focus_next;
static Evas_Object *
_content_left_unset(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd->contents.left) return NULL;
Evas_Object *content = wd->contents.left;
elm_widget_sub_object_del(obj, content);
return content;
}
sc->content_aliases = _content_aliases;
static Evas_Object *
_content_right_unset(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd->contents.right) return NULL;
Evas_Object *content = wd->contents.right;
elm_widget_sub_object_del(obj, content);
return content;
}
static void
_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (part && (!strncmp(part, "elm.swallow.", 12))) part += 12;
if (!part || !strcmp(part, "left"))
_content_left_set(obj, content);
else if (!strcmp(part, "right"))
_content_right_set(obj, content);
}
static Evas_Object *
_content_get_hook(const Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
if (part && (!strncmp(part, "elm.swallow.", 12))) part += 12;
if (!part || !strcmp(part, "left"))
return wd->contents.left;
else if (!strcmp(part, "right"))
return wd->contents.right;
return NULL;
}
static Evas_Object *
_content_unset_hook(Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
if (part && (!strncmp(part, "elm.swallow.", 12))) part += 12;
if (!part || !strcmp(part, "left"))
return _content_left_unset(obj);
else if (!strcmp(part, "right"))
return _content_right_unset(obj);
return NULL;
}
EAPI Evas_Object *
elm_panes_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
ELM_SET_WIDTYPE(widtype, "panes");
elm_widget_type_set(obj, "panes");
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_focus_next_hook_set(obj, _elm_panes_focus_next_hook);
elm_widget_content_set_hook_set(obj, _content_set_hook);
elm_widget_content_get_hook_set(obj, _content_get_hook);
elm_widget_content_unset_hook_set(obj, _content_unset_hook);
elm_widget_can_focus_set(obj, EINA_FALSE);
obj = evas_object_smart_add(e, _elm_panes_smart_class_new());
wd->panes = edje_object_add(e);
_elm_theme_object_set(obj, wd->panes, "panes", "vertical", "default");
elm_widget_resize_object_set(obj, wd->panes);
evas_object_show(wd->panes);
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
elm_panes_content_left_size_set(obj, 0.5);
edje_object_signal_callback_add(wd->panes, "elm,action,click", "",
_clicked, obj);
edje_object_signal_callback_add(wd->panes, "elm,action,click,double", "",
_clicked_double, obj);
edje_object_signal_callback_add(wd->panes, "elm,action,press", "",
_press, obj);
edje_object_signal_callback_add(wd->panes, "elm,action,unpress", "",
_unpress, 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);
evas_object_smart_callbacks_descriptions_set(obj, _signals);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_sizing_eval(obj);
return obj;
}
EINA_DEPRECATED EAPI void
elm_panes_content_left_set(Evas_Object *obj,
Evas_Object *content)
elm_panes_content_left_set(Evas_Object *obj, Evas_Object *content)
{
elm_layout_content_set(obj, "left", content);
_content_set_hook(obj, "left", content);
}
EINA_DEPRECATED EAPI void
elm_panes_content_right_set(Evas_Object *obj,
Evas_Object *content)
elm_panes_content_right_set(Evas_Object *obj, Evas_Object *content)
{
elm_layout_content_set(obj, "right", content);
_content_set_hook(obj, "right", content);
}
EINA_DEPRECATED EAPI Evas_Object *
elm_panes_content_left_get(const Evas_Object *obj)
{
return elm_layout_content_get(obj, "left");
return _content_get_hook(obj, "left");
}
EINA_DEPRECATED EAPI Evas_Object *
elm_panes_content_right_get(const Evas_Object *obj)
{
return elm_layout_content_get(obj, "right");
return _content_get_hook(obj, "right");
}
EINA_DEPRECATED EAPI Evas_Object *
elm_panes_content_left_unset(Evas_Object *obj)
{
return elm_layout_content_unset(obj, "left");
return _content_unset_hook(obj, "left");
}
EINA_DEPRECATED EAPI Evas_Object *
elm_panes_content_right_unset(Evas_Object *obj)
{
return elm_layout_content_unset(obj, "right");
return _content_unset_hook(obj, "right");
}
EAPI double
elm_panes_content_left_size_get(const Evas_Object *obj)
{
ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
Widget_Data *wd = elm_widget_data_get(obj);
double w, h;
ELM_PANES_CHECK(obj) 0.0;
ELM_PANES_DATA_GET(obj, sd);
edje_object_part_drag_value_get
(ELM_WIDGET_DATA(sd)->resize_obj, "elm.bar", &w, &h);
if (sd->horizontal) return h;
if (!wd) return 0;
edje_object_part_drag_value_get(wd->panes, "elm.bar", &w, &h);
if (wd->horizontal) return h;
else return w;
}
EAPI void
elm_panes_content_left_size_set(Evas_Object *obj,
double size)
elm_panes_content_left_size_set(Evas_Object *obj, double size)
{
ELM_PANES_CHECK(obj);
ELM_PANES_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (size < 0.0) size = 0.0;
else if (size > 1.0)
size = 1.0;
if (sd->horizontal)
edje_object_part_drag_value_set
(ELM_WIDGET_DATA(sd)->resize_obj, "elm.bar", 0.0, size);
else if (size > 1.0) size = 1.0;
if (wd->horizontal)
edje_object_part_drag_value_set(wd->panes, "elm.bar", 0.0, size);
else
edje_object_part_drag_value_set
(ELM_WIDGET_DATA(sd)->resize_obj, "elm.bar", size, 0.0);
edje_object_part_drag_value_set(wd->panes, "elm.bar", size, 0.0);
}
EAPI double
elm_panes_content_right_size_get(const Evas_Object *obj)
{
return 1.0 - elm_panes_content_left_size_get(obj);
return (1.0 - elm_panes_content_left_size_get(obj));
}
EAPI void
elm_panes_content_right_size_set(Evas_Object *obj,
double size)
elm_panes_content_right_size_set(Evas_Object *obj, double size)
{
elm_panes_content_left_size_set(obj, (1.0 - size));
}
EAPI void
elm_panes_horizontal_set(Evas_Object *obj,
Eina_Bool horizontal)
elm_panes_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
{
ELM_PANES_CHECK(obj);
ELM_PANES_DATA_GET(obj, sd);
sd->horizontal = horizontal;
_elm_panes_smart_theme(obj);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
wd->horizontal = horizontal;
_theme_hook(obj);
elm_panes_content_left_size_set(obj, 0.5);
}
EAPI Eina_Bool
elm_panes_horizontal_get(const Evas_Object *obj)
{
ELM_PANES_CHECK(obj) EINA_FALSE;
ELM_PANES_DATA_GET(obj, sd);
return sd->horizontal;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->horizontal;
}
EAPI void
elm_panes_fixed_set(Evas_Object *obj, Eina_Bool fixed)
{
ELM_PANES_CHECK(obj);
ELM_PANES_DATA_GET(obj, sd);
sd->fixed = !!fixed;
if (sd->fixed == EINA_TRUE)
elm_layout_signal_emit(obj, "elm.panes.fixed", "elm");
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
wd->fixed = !!fixed;
if (wd->fixed == EINA_TRUE)
edje_object_signal_emit(wd->panes, "elm.panes.fixed", "elm");
else
elm_layout_signal_emit(obj, "elm.panes.unfixed", "elm");
edje_object_signal_emit(wd->panes, "elm.panes.unfixed", "elm");
}
EAPI Eina_Bool
elm_panes_fixed_get(const Evas_Object *obj)
{
ELM_PANES_CHECK(obj) EINA_FALSE;
ELM_PANES_DATA_GET(obj, sd);
return sd->fixed;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->fixed;
}

View File

@ -14,15 +14,11 @@
* Panes can be displayed vertically or horizontally, and contents
* size proportion can be customized (homogeneous by default).
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for panes objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* - @c "press" - The panes has been pressed (button wasn't released yet).
* - @c "unpressed" - The panes was released after being pressed.
* - @c "clicked" - The panes has been clicked>
* - @c "clicked,double" - The panes has been double clicked
* Smart callbacks one can listen to:
* - "press" - The panes has been pressed (button wasn't released yet).
* - "unpressed" - The panes was released after being pressed.
* - "clicked" - The panes has been clicked>
* - "clicked,double" - The panes has been double clicked
*
* Available styles for it:
* - @c "default"

View File

@ -1,297 +1,350 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_layout.h"
static const char PROGRESSBAR_SMART_NAME[] = "elm_progressbar";
#define MIN_RATIO_LVL 0.0
#define MAX_RATIO_LVL 1.0
typedef struct _Elm_Progressbar_Smart_Data Elm_Progressbar_Smart_Data;
typedef struct _Widget_Data Widget_Data;
struct _Elm_Progressbar_Smart_Data
struct _Widget_Data
{
Elm_Layout_Smart_Data base;
Evas_Object *spacer;
const char *units;
Evas_Coord size;
double val;
Eina_Bool horizontal : 1;
Eina_Bool inverted : 1;
Eina_Bool pulse : 1;
Eina_Bool pulse_state : 1;
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;
};
#define ELM_PROGRESSBAR_DATA_GET(o, sd) \
Elm_Progressbar_Smart_Data * sd = evas_object_smart_data_get(o)
#define ELM_PROGRESSBAR_DATA_GET_OR_RETURN(o, ptr) \
ELM_PROGRESSBAR_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define ELM_PROGRESSBAR_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_PROGRESSBAR_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_PROGRESSBAR_CHECK(obj) \
if (!obj || !elm_widget_type_check \
((obj), PROGRESSBAR_SMART_NAME, __func__)) \
return
/* Inheriting from elm_layout. Besides, we need no more than what is
* there */
EVAS_SMART_SUBCLASS_NEW
(PROGRESSBAR_SMART_NAME, _elm_progressbar, Elm_Layout_Smart_Class,
Elm_Layout_Smart_Class, elm_layout_smart_class_get, NULL);
static const Elm_Layout_Part_Alias_Description _content_aliases[] =
{
{"icon", "elm.swallow.icon"},
{NULL, NULL}
};
static const Elm_Layout_Part_Alias_Description _text_aliases[] =
{
{"default", "elm.text"},
{NULL, NULL}
};
static const char *widtype = NULL;
static void _del_hook(Evas_Object *obj);
static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
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
_units_set(Evas_Object *obj)
_del_hook(Evas_Object *obj)
{
ELM_PROGRESSBAR_DATA_GET(obj, sd);
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);
}
if (sd->units)
static void
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
edje_object_mirrored_set(wd->progressbar, rtl);
}
static void
_theme_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
_elm_widget_mirrored_reload(obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
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->icon)
{
char buf[1024];
snprintf(buf, sizeof(buf), sd->units, 100 * sd->val);
elm_layout_text_set(obj, "elm.text.status", buf);
edje_object_part_swallow(wd->progressbar, "elm.swallow.content", wd->icon);
edje_object_signal_emit(wd->progressbar, "elm,state,icon,visible", "elm");
}
else elm_layout_text_set(obj, "elm.text.status", NULL);
}
static void
_val_set(Evas_Object *obj)
{
Eina_Bool rtl;
double pos;
ELM_PROGRESSBAR_DATA_GET(obj, sd);
pos = sd->val;
rtl = elm_widget_mirrored_get(obj);
if ((!rtl && sd->inverted) ||
(rtl && ((!sd->horizontal && sd->inverted) ||
(sd->horizontal && !sd->inverted))))
pos = MAX_RATIO_LVL - pos;
edje_object_part_drag_value_set
(ELM_WIDGET_DATA(sd)->resize_obj, "elm.cur.progressbar", pos, pos);
}
static Eina_Bool
_elm_progressbar_smart_theme(Evas_Object *obj)
{
ELM_PROGRESSBAR_DATA_GET(obj, sd);
if (sd->horizontal)
eina_stringshare_replace(&ELM_LAYOUT_DATA(sd)->group, "horizontal");
else eina_stringshare_replace(&ELM_LAYOUT_DATA(sd)->group, "vertical");
if (!ELM_WIDGET_CLASS(_elm_progressbar_parent_sc)->theme(obj))
return EINA_FALSE;
if (sd->pulse)
elm_layout_signal_emit(obj, "elm,state,pulse", "elm");
if (wd->label)
{
edje_object_part_text_escaped_set(wd->progressbar, "elm.text", wd->label);
edje_object_signal_emit(wd->progressbar, "elm,state,text,visible", "elm");
}
if (wd->pulse)
edje_object_signal_emit(wd->progressbar, "elm,state,pulse", "elm");
else
elm_layout_signal_emit(obj, "elm,state,fraction", "elm");
edje_object_signal_emit(wd->progressbar, "elm,state,fraction", "elm");
if (wd->pulse_state)
edje_object_signal_emit(wd->progressbar, "elm,state,pulse,start", "elm");
if (sd->pulse_state)
elm_layout_signal_emit(obj, "elm,state,pulse,start", "elm");
if ((wd->units) && (!wd->pulse))
edje_object_signal_emit(wd->progressbar, "elm,state,units,visible", "elm");
if ((sd->units) && (!sd->pulse))
elm_layout_signal_emit(obj, "elm,state,units,visible", "elm");
if (sd->horizontal)
evas_object_size_hint_min_set
(sd->spacer, (double)sd->size * elm_widget_scale_get(obj) *
elm_config_scale_get(), 1);
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
(sd->spacer, 1, (double)sd->size * elm_widget_scale_get(obj) *
elm_config_scale_get());
evas_object_size_hint_min_set(wd->spacer, 1, (double)wd->size * elm_widget_scale_get(obj) * _elm_config->scale);
if (sd->inverted)
elm_layout_signal_emit(obj, "elm,state,inverted,on", "elm");
edje_object_part_swallow(wd->progressbar, "elm.swallow.bar", wd->spacer);
if (wd->inverted)
edje_object_signal_emit(wd->progressbar, "elm,state,inverted,on", "elm");
_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);
edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
elm_layout_sizing_eval(obj);
return EINA_TRUE;
_sizing_eval(obj);
}
static void
_elm_progressbar_smart_sizing_eval(Evas_Object *obj)
_sizing_eval(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
Evas_Coord minw = -1, minh = -1;
ELM_PROGRESSBAR_DATA_GET(obj, sd);
edje_object_size_min_restricted_calc
(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh);
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
_elm_progressbar_smart_add(Evas_Object *obj)
_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Progressbar_Smart_Data);
ELM_WIDGET_CLASS(_elm_progressbar_parent_sc)->base.add(obj);
priv->horizontal = EINA_TRUE;
priv->inverted = EINA_FALSE;
priv->pulse = EINA_FALSE;
priv->pulse_state = EINA_FALSE;
priv->units = eina_stringshare_add("%.0f %%");
priv->val = MIN_RATIO_LVL;
elm_layout_theme_set
(obj, "progressbar", "horizontal", elm_widget_style_get(obj));
priv->spacer = evas_object_rectangle_add(evas_object_evas_get(obj));
evas_object_color_set(priv->spacer, 0, 0, 0, 0);
evas_object_pass_events_set(priv->spacer, EINA_TRUE);
elm_layout_content_set(obj, "elm.swallow.bar", priv->spacer);
_units_set(obj);
_val_set(obj);
elm_widget_can_focus_set(obj, EINA_FALSE);
elm_layout_sizing_eval(obj);
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return;
if (obj != wd->icon) return;
_sizing_eval(data);
}
static void
_elm_progressbar_smart_del(Evas_Object *obj)
_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
{
ELM_PROGRESSBAR_DATA_GET(obj, sd);
if (sd->units) eina_stringshare_del(sd->units);
ELM_WIDGET_CLASS(_elm_progressbar_parent_sc)->base.del(obj);
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;
edje_object_message_signal_process(wd->progressbar);
_sizing_eval(obj);
}
}
static void
_elm_progressbar_smart_set_user(Elm_Layout_Smart_Class *sc)
_val_set(Evas_Object *obj)
{
ELM_WIDGET_CLASS(sc)->base.add = _elm_progressbar_smart_add;
ELM_WIDGET_CLASS(sc)->base.del = _elm_progressbar_smart_del;
ELM_WIDGET_CLASS(sc)->theme = _elm_progressbar_smart_theme;
ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */
sc->sizing_eval = _elm_progressbar_smart_sizing_eval;
sc->content_aliases = _content_aliases;
sc->text_aliases = _text_aliases;
Widget_Data *wd = elm_widget_data_get(obj);
Eina_Bool rtl;
double pos;
if (!wd) return;
pos = wd->val;
rtl = elm_widget_mirrored_get(obj);
if ((!rtl && wd->inverted) || (rtl &&
((!wd->horizontal && wd->inverted) ||
(wd->horizontal && !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_escaped_set(wd->progressbar, "elm.text.status", buf);
}
else
edje_object_part_text_escaped_set(wd->progressbar, "elm.text.status", NULL);
}
static void
_elm_progressbar_label_set(Evas_Object *obj, const char *item, const char *label)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (item && strcmp(item, "default")) return;
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_escaped_set(wd->progressbar, "elm.text", label);
_sizing_eval(obj);
}
static const char *
_elm_progressbar_label_get(const Evas_Object *obj, const char *item)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (item && strcmp(item, "default")) return NULL;
if (!wd) return NULL;
return wd->label;
}
static void
_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd;
if (part && strcmp(part, "icon")) return;
wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->icon == content) return;
if (wd->icon) evas_object_del(wd->icon);
wd->icon = 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->progressbar, "elm.swallow.content", content);
edje_object_signal_emit(wd->progressbar, "elm,state,icon,visible", "elm");
edje_object_message_signal_process(wd->progressbar);
}
_sizing_eval(obj);
}
static Evas_Object *
_content_get_hook(const Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd;
if (part && strcmp(part, "icon")) return NULL;
wd = elm_widget_data_get(obj);
if (!wd) return NULL;
return wd->icon;
}
static Evas_Object *
_content_unset_hook(Evas_Object *obj, const char *part)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd;
Evas_Object *icon;
if (part && strcmp(part, "icon")) return NULL;
wd = elm_widget_data_get(obj);
if (!wd) return NULL;
if (!wd->icon) return NULL;
icon = wd->icon;
elm_widget_sub_object_del(obj, wd->icon);
evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_changed_size_hints, obj);
edje_object_part_unswallow(wd->progressbar, wd->icon);
wd->icon = NULL;
return icon;
}
EAPI Evas_Object *
elm_progressbar_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
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);
elm_widget_can_focus_set(obj, EINA_FALSE);
elm_widget_text_set_hook_set(obj, _elm_progressbar_label_set);
elm_widget_text_get_hook_set(obj, _elm_progressbar_label_get);
elm_widget_content_set_hook_set(obj, _content_set_hook);
elm_widget_content_get_hook_set(obj, _content_get_hook);
elm_widget_content_unset_hook_set(obj, _content_unset_hook);
obj = evas_object_smart_add(e, _elm_progressbar_smart_class_new());
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;
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
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, EINA_TRUE);
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);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_sizing_eval(obj);
return obj;
}
EAPI void
elm_progressbar_pulse_set(Evas_Object *obj,
Eina_Bool pulse)
elm_progressbar_pulse_set(Evas_Object *obj, Eina_Bool pulse)
{
ELM_PROGRESSBAR_CHECK(obj);
ELM_PROGRESSBAR_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
pulse = !!pulse;
if (sd->pulse == pulse) return;
sd->pulse = pulse;
_elm_progressbar_smart_theme(obj);
if (wd->pulse == pulse) return;
wd->pulse = pulse;
_theme_hook(obj);
}
EAPI Eina_Bool
elm_progressbar_pulse_get(const Evas_Object *obj)
{
ELM_PROGRESSBAR_CHECK(obj) EINA_FALSE;
ELM_PROGRESSBAR_DATA_GET(obj, sd);
return sd->pulse;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->pulse;
}
EAPI void
elm_progressbar_pulse(Evas_Object *obj,
Eina_Bool state)
elm_progressbar_pulse(Evas_Object *obj, Eina_Bool state)
{
ELM_PROGRESSBAR_CHECK(obj);
ELM_PROGRESSBAR_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
state = !!state;
if ((!sd->pulse) && (sd->pulse_state == state)) return;
sd->pulse_state = state;
if (sd->pulse_state)
elm_layout_signal_emit(obj, "elm,state,pulse,start", "elm");
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
elm_layout_signal_emit(obj, "elm,state,pulse,stop", "elm");
edje_object_signal_emit(wd->progressbar, "elm,state,pulse,stop", "elm");
}
EAPI void
elm_progressbar_value_set(Evas_Object *obj,
double val)
elm_progressbar_value_set(Evas_Object *obj, double val)
{
ELM_PROGRESSBAR_CHECK(obj);
ELM_PROGRESSBAR_DATA_GET(obj, sd);
if (sd->val == val) return;
sd->val = val;
if (sd->val < MIN_RATIO_LVL) sd->val = MIN_RATIO_LVL;
if (sd->val > MAX_RATIO_LVL) sd->val = MAX_RATIO_LVL;
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);
}
@ -299,117 +352,102 @@ elm_progressbar_value_set(Evas_Object *obj,
EAPI double
elm_progressbar_value_get(const Evas_Object *obj)
{
ELM_PROGRESSBAR_CHECK(obj) 0.0;
ELM_PROGRESSBAR_DATA_GET(obj, sd);
return sd->val;
ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return 0.0;
return wd->val;
}
EAPI void
elm_progressbar_span_size_set(Evas_Object *obj,
Evas_Coord size)
elm_progressbar_span_size_set(Evas_Object *obj, Evas_Coord size)
{
ELM_PROGRESSBAR_CHECK(obj);
ELM_PROGRESSBAR_DATA_GET(obj, sd);
if (sd->size == size) return;
sd->size = size;
if (sd->horizontal)
evas_object_size_hint_min_set
(sd->spacer, (double)sd->size * elm_widget_scale_get(obj) *
elm_config_scale_get(), 1);
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
(sd->spacer, 1, (double)sd->size * elm_widget_scale_get(obj) *
elm_config_scale_get());
elm_layout_sizing_eval(obj);
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);
}
EAPI Evas_Coord
elm_progressbar_span_size_get(const Evas_Object *obj)
{
ELM_PROGRESSBAR_CHECK(obj) 0;
ELM_PROGRESSBAR_DATA_GET(obj, sd);
return sd->size;
ELM_CHECK_WIDTYPE(obj, widtype) 0;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return 0;
return wd->size;
}
EAPI void
elm_progressbar_unit_format_set(Evas_Object *obj,
const char *units)
elm_progressbar_unit_format_set(Evas_Object *obj, const char *units)
{
ELM_PROGRESSBAR_CHECK(obj);
ELM_PROGRESSBAR_DATA_GET(obj, sd);
eina_stringshare_replace(&sd->units, 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)
{
elm_layout_signal_emit(obj, "elm,state,units,visible", "elm");
edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
edje_object_signal_emit(wd->progressbar, "elm,state,units,visible", "elm");
edje_object_message_signal_process(wd->progressbar);
}
else
{
elm_layout_signal_emit(obj, "elm,state,units,hidden", "elm");
edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
edje_object_signal_emit(wd->progressbar, "elm,state,units,hidden", "elm");
edje_object_message_signal_process(wd->progressbar);
}
_units_set(obj);
elm_layout_sizing_eval(obj);
_sizing_eval(obj);
}
EAPI const char *
elm_progressbar_unit_format_get(const Evas_Object *obj)
{
ELM_PROGRESSBAR_CHECK(obj) NULL;
ELM_PROGRESSBAR_DATA_GET(obj, sd);
return sd->units;
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
return wd->units;
}
EAPI void
elm_progressbar_horizontal_set(Evas_Object *obj,
Eina_Bool horizontal)
elm_progressbar_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
{
ELM_PROGRESSBAR_CHECK(obj);
ELM_PROGRESSBAR_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
horizontal = !!horizontal;
if (sd->horizontal == horizontal) return;
sd->horizontal = horizontal;
_elm_progressbar_smart_theme(obj);
if (wd->horizontal == horizontal) return;
wd->horizontal = horizontal;
_theme_hook(obj);
}
EAPI Eina_Bool
elm_progressbar_horizontal_get(const Evas_Object *obj)
{
ELM_PROGRESSBAR_CHECK(obj) EINA_FALSE;
ELM_PROGRESSBAR_DATA_GET(obj, sd);
return sd->horizontal;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->horizontal;
}
EAPI void
elm_progressbar_inverted_set(Evas_Object *obj,
Eina_Bool inverted)
elm_progressbar_inverted_set(Evas_Object *obj, Eina_Bool inverted)
{
ELM_PROGRESSBAR_CHECK(obj);
ELM_PROGRESSBAR_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
inverted = !!inverted;
if (sd->inverted == inverted) return;
sd->inverted = inverted;
if (sd->inverted)
elm_layout_signal_emit(obj, "elm,state,inverted,on", "elm");
if (wd->inverted == inverted) return;
wd->inverted = inverted;
if (wd->inverted)
edje_object_signal_emit(wd->progressbar, "elm,state,inverted,on", "elm");
else
elm_layout_signal_emit(obj, "elm,state,inverted,off", "elm");
edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
edje_object_signal_emit(wd->progressbar, "elm,state,inverted,off", "elm");
edje_object_message_signal_process(wd->progressbar);
_val_set(obj);
_units_set(obj);
}
@ -417,8 +455,8 @@ elm_progressbar_inverted_set(Evas_Object *obj,
EAPI Eina_Bool
elm_progressbar_inverted_get(const Evas_Object *obj)
{
ELM_PROGRESSBAR_CHECK(obj) EINA_FALSE;
ELM_PROGRESSBAR_DATA_GET(obj, sd);
return sd->inverted;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->inverted;
}

View File

@ -27,11 +27,7 @@
* Applications can query the progress bar for its value with
* elm_progressbar_value_get().
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for progress bar objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* Available widget styles for progress bars:
* - @c "default"
* - @c "wheel" (simple style, no text, no progression, only
* "pulse" effect is available)

View File

@ -1,410 +1,502 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_layout.h"
static const char RADIO_SMART_NAME[] = "elm_radio";
typedef struct _Elm_Radio_Smart_Data Elm_Radio_Smart_Data;
typedef struct _Group Group;
typedef struct _Widget_Data Widget_Data;
typedef struct _Group Group;
struct _Group
{
int value;
int *valuep;
int value;
int *valuep;
Eina_List *radios;
};
struct _Elm_Radio_Smart_Data
struct _Widget_Data
{
Elm_Layout_Smart_Data base;
int value;
Eina_Bool state;
Group *group;
Evas_Object *radio;
Evas_Object *icon;
int value;
const char *label;
Eina_Bool state;
Group *group;
};
#define ELM_RADIO_DATA_GET(o, sd) \
Elm_Radio_Smart_Data * sd = evas_object_smart_data_get(o)
#define ELM_RADIO_DATA_GET_OR_RETURN(o, ptr) \
ELM_RADIO_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define ELM_RADIO_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_RADIO_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_RADIO_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), RADIO_SMART_NAME, __func__)) \
return
static const Elm_Layout_Part_Alias_Description _content_aliases[] =
{
{"icon", "elm.swallow.icon"},
{NULL, NULL}
};
static const Elm_Layout_Part_Alias_Description _text_aliases[] =
{
{"default", "elm.text"},
{NULL, NULL}
};
static const char *widtype = NULL;
static void _state_set(Evas_Object *obj, Eina_Bool state);
static void _del_hook(Evas_Object *obj);
static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
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 void _on_focus_hook(void *data, Evas_Object *obj);
static void _activate(Evas_Object *obj);
static void _activate_hook(Evas_Object *obj);
static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src,
Evas_Callback_Type type, void *event_info);
static const char SIG_CHANGED[] = "changed";
static const Evas_Smart_Cb_Description _smart_callbacks[] = {
{SIG_CHANGED, ""},
{NULL, NULL}
static const Evas_Smart_Cb_Description _signals[] = {
{SIG_CHANGED, ""},
{NULL, NULL}
};
/* Inheriting from elm_layout. Besides, we need no more than what is
* there */
EVAS_SMART_SUBCLASS_NEW
(RADIO_SMART_NAME, _elm_radio, Elm_Layout_Smart_Class,
Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks);
static void
_state_set(Evas_Object *obj, Eina_Bool state)
{
ELM_RADIO_DATA_GET(obj, sd);
if ((state != sd->state) && (!elm_widget_disabled_get(obj)))
{
sd->state = state;
if (sd->state)
elm_layout_signal_emit(obj, "elm,state,radio,on", "elm");
else
elm_layout_signal_emit(obj, "elm,state,radio,off", "elm");
}
}
static void
_state_set_all(Elm_Radio_Smart_Data *sd)
{
const Eina_List *l;
Eina_Bool disabled = EINA_FALSE;
Evas_Object *child, *selected = NULL;
EINA_LIST_FOREACH (sd->group->radios, l, child)
{
ELM_RADIO_DATA_GET(child, sdc);
if (sdc->state) selected = child;
if (sdc->value == sd->group->value)
{
_state_set(child, EINA_TRUE);
if (!sdc->state) disabled = EINA_TRUE;
}
else _state_set(child, EINA_FALSE);
}
if ((disabled) && (selected)) _state_set(selected, 1);
}
static void
_activate(Evas_Object *obj)
{
ELM_RADIO_DATA_GET(obj, sd);
if (sd->group->value == sd->value) return;
if ((_elm_config->access_mode == ELM_ACCESS_MODE_OFF) ||
(_elm_access_2nd_click_timeout(obj)))
{
sd->group->value = sd->value;
if (sd->group->valuep) *(sd->group->valuep) = sd->group->value;
_state_set_all(sd);
if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
_elm_access_say(E_("State: On"));
evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);
}
}
static Eina_Bool
_elm_radio_smart_event(Evas_Object *obj,
Evas_Object *src __UNUSED__,
Evas_Callback_Type type,
void *event_info)
_event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info)
{
Evas_Event_Key_Down *ev;
if (elm_widget_disabled_get(obj)) return EINA_FALSE;
if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
ev = event_info;
Evas_Event_Key_Down *ev = event_info;
if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
if (elm_widget_disabled_get(obj)) return EINA_FALSE;
if ((strcmp(ev->keyname, "Return")) &&
(strcmp(ev->keyname, "KP_Enter")) &&
(strcmp(ev->keyname, "space")))
return EINA_FALSE;
_activate(obj);
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
return EINA_TRUE;
}
static Eina_Bool
_elm_radio_smart_theme(Evas_Object *obj)
{
ELM_RADIO_DATA_GET(obj, sd);
if (!ELM_WIDGET_CLASS(_elm_radio_parent_sc)->theme(obj)) return EINA_FALSE;
if (sd->state) elm_layout_signal_emit(obj, "elm,state,radio,on", "elm");
else elm_layout_signal_emit(obj, "elm,state,radio,off", "elm");
if (elm_widget_disabled_get(obj) && sd->state) _state_set(obj, EINA_FALSE);
edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
elm_layout_sizing_eval(obj);
return EINA_TRUE;
}
static Eina_Bool
_elm_radio_smart_disable(Evas_Object *obj)
{
ELM_RADIO_DATA_GET(obj, sd);
if (!ELM_WIDGET_CLASS(_elm_radio_parent_sc)->disable(obj)) return EINA_FALSE;
if (elm_widget_disabled_get(obj) && sd->state) _state_set(obj, EINA_FALSE);
return EINA_TRUE;
}
static void
_elm_radio_smart_sizing_eval(Evas_Object *obj)
_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
_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->radio, "elm,action,focus", "elm");
evas_object_focus_set(wd->radio, EINA_TRUE);
}
else
{
edje_object_signal_emit(wd->radio, "elm,action,unfocus", "elm");
evas_object_focus_set(wd->radio, EINA_FALSE);
}
}
static void
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
edje_object_mirrored_set(wd->radio, rtl);
}
static void
_theme_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
_elm_widget_mirrored_reload(obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_elm_theme_object_set(obj, wd->radio, "radio", "base", elm_widget_style_get(obj));
if (wd->icon)
edje_object_signal_emit(wd->radio, "elm,state,icon,visible", "elm");
else
edje_object_signal_emit(wd->radio, "elm,state,icon,hidden", "elm");
if (wd->state)
edje_object_signal_emit(wd->radio, "elm,state,radio,on", "elm");
else
edje_object_signal_emit(wd->radio, "elm,state,radio,off", "elm");
if (wd->label)
edje_object_signal_emit(wd->radio, "elm,state,text,visible", "elm");
else
edje_object_signal_emit(wd->radio, "elm,state,text,hidden", "elm");
edje_object_part_text_escaped_set(wd->radio, "elm.text", wd->label);
if (elm_widget_disabled_get(obj))
{
edje_object_signal_emit(wd->radio, "elm,state,disabled", "elm");
if (wd->state) _state_set(obj, 0);
}
edje_object_message_signal_process(wd->radio);
edje_object_scale_set(wd->radio, 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->radio, "elm,state,disabled", "elm");
if (wd->state) _state_set(obj, 0);
}
else
edje_object_signal_emit(wd->radio, "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;
ELM_RADIO_DATA_GET(obj, sd);
if (!wd) return;
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
edje_object_size_min_restricted_calc
(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh);
edje_object_size_min_restricted_calc(wd->radio, &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
_radio_on_cb(void *data,
Evas_Object *obj __UNUSED__,
const char *emission __UNUSED__,
const char *source __UNUSED__)
_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->radio, "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->radio, "elm,state,radio,on", "elm");
else
edje_object_signal_emit(wd->radio, "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
_activate(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->group->value == wd->value) return;
if ((_elm_config->access_mode == ELM_ACCESS_MODE_OFF) ||
(_elm_access_2nd_click_timeout(obj)))
{
wd->group->value = wd->value;
if (wd->group->valuep) *(wd->group->valuep) = wd->group->value;
_state_set_all(wd);
if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
_elm_access_say(E_("State: On"));
evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);
}
}
static void
_activate_hook(Evas_Object *obj)
{
_activate(obj);
}
static void
_signal_radio_on(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
_activate(data);
}
static void
_elm_radio_label_set(Evas_Object *obj, const char *item, const char *label)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (item && strcmp(item, "default")) return;
if (!wd) return;
eina_stringshare_replace(&wd->label, label);
if (label)
{
edje_object_signal_emit(wd->radio, "elm,state,text,visible", "elm");
edje_object_message_signal_process(wd->radio);
}
else
{
edje_object_signal_emit(wd->radio, "elm,state,text,hidden", "elm");
edje_object_message_signal_process(wd->radio);
}
edje_object_part_text_escaped_set(wd->radio, "elm.text", label);
_sizing_eval(obj);
}
static const char *
_elm_radio_label_get(const Evas_Object *obj, const char *item)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (item && strcmp(item, "default")) return NULL;
if (!wd) return NULL;
return wd->label;
}
static char *
_access_info_cb(void *data __UNUSED__,
Evas_Object *obj,
Elm_Widget_Item *item __UNUSED__)
_access_info_cb(void *data __UNUSED__, Evas_Object *obj, Elm_Widget_Item *item __UNUSED__)
{
const char *txt = elm_widget_access_info_get(obj);
if (!txt) txt = elm_layout_text_get(obj, NULL);
if (!txt) txt = _elm_radio_label_get(obj, NULL);
if (txt) return strdup(txt);
return NULL;
}
static char *
_access_state_cb(void *data __UNUSED__,
Evas_Object *obj,
Elm_Widget_Item *item __UNUSED__)
_access_state_cb(void *data __UNUSED__, Evas_Object *obj, Elm_Widget_Item *item __UNUSED__)
{
ELM_RADIO_DATA_GET(obj, sd);
if (elm_widget_disabled_get(obj)) return strdup(E_("State: Disabled"));
if (sd->state) return strdup(E_("State: On"));
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
if (elm_widget_disabled_get(obj))
return strdup(E_("State: Disabled"));
if (wd->state)
return strdup(E_("State: On"));
return strdup(E_("State: Off"));
}
static void
_elm_radio_smart_add(Evas_Object *obj)
_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Radio_Smart_Data);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd;
ELM_WIDGET_CLASS(_elm_radio_parent_sc)->base.add(obj);
elm_layout_theme_set(obj, "radio", "base", elm_widget_style_get(obj));
elm_layout_signal_callback_add
(obj, "elm,action,radio,on", "", _radio_on_cb, obj);
elm_layout_signal_callback_add
(obj, "elm,action,radio,toggle", "", _radio_on_cb, obj);
priv->group = calloc(1, sizeof(Group));
priv->group->radios = eina_list_append(priv->group->radios, obj);
priv->state = EINA_FALSE;
elm_widget_can_focus_set(obj, EINA_TRUE);
elm_layout_sizing_eval(obj);
_elm_access_object_register(obj, ELM_WIDGET_DATA(priv)->resize_obj);
_elm_access_text_set
(_elm_access_object_get(obj), ELM_ACCESS_TYPE, E_("Radio"));
_elm_access_callback_set
(_elm_access_object_get(obj), ELM_ACCESS_INFO, _access_info_cb, obj);
_elm_access_callback_set
(_elm_access_object_get(obj), ELM_ACCESS_STATE, _access_state_cb, obj);
if (part && strcmp(part, "icon")) return;
wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->icon == content) return;
if (wd->icon) evas_object_del(wd->icon);
wd->icon = 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->radio, "elm.swallow.content", content);
edje_object_signal_emit(wd->radio, "elm,state,icon,visible", "elm");
edje_object_message_signal_process(wd->radio);
}
_sizing_eval(obj);
}
static void
_elm_radio_smart_del(Evas_Object *obj)
static Evas_Object *
_content_get_hook(const Evas_Object *obj, const char *part)
{
ELM_RADIO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd;
sd->group->radios = eina_list_remove(sd->group->radios, obj);
if (!sd->group->radios) free(sd->group);
ELM_WIDGET_CLASS(_elm_radio_parent_sc)->base.del(obj);
if (part && strcmp(part, "icon")) return NULL;
wd = elm_widget_data_get(obj);
if (!wd) return NULL;
return wd->icon;
}
static void
_elm_radio_smart_set_user(Elm_Layout_Smart_Class *sc)
static Evas_Object *
_content_unset_hook(Evas_Object *obj, const char *part)
{
ELM_WIDGET_CLASS(sc)->base.add = _elm_radio_smart_add;
ELM_WIDGET_CLASS(sc)->base.del = _elm_radio_smart_del;
ELM_WIDGET_CLASS(sc)->disable = _elm_radio_smart_disable;
ELM_WIDGET_CLASS(sc)->theme = _elm_radio_smart_theme;
ELM_WIDGET_CLASS(sc)->event = _elm_radio_smart_event;
ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */
sc->sizing_eval = _elm_radio_smart_sizing_eval;
sc->content_aliases = _content_aliases;
sc->text_aliases = _text_aliases;
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd;
Evas_Object *icon;
if (part && strcmp(part, "icon")) return NULL;
wd = elm_widget_data_get(obj);
if (!wd) return NULL;
if (!wd->icon) return NULL;
icon = wd->icon;
elm_widget_sub_object_del(obj, wd->icon);
evas_object_event_callback_del_full(wd->icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_changed_size_hints, obj);
edje_object_part_unswallow(wd->radio, wd->icon);
wd->icon = NULL;
return icon;
}
EAPI Evas_Object *
elm_radio_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
ELM_SET_WIDTYPE(widtype, "radio");
elm_widget_type_set(obj, "radio");
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, EINA_TRUE);
elm_widget_activate_hook_set(obj, _activate_hook);
elm_widget_event_hook_set(obj, _event_hook);
elm_widget_text_set_hook_set(obj, _elm_radio_label_set);
elm_widget_text_get_hook_set(obj, _elm_radio_label_get);
elm_widget_content_set_hook_set(obj, _content_set_hook);
elm_widget_content_get_hook_set(obj, _content_get_hook);
elm_widget_content_unset_hook_set(obj, _content_unset_hook);
obj = evas_object_smart_add(e, _elm_radio_smart_class_new());
wd->radio = edje_object_add(e);
_elm_theme_object_set(obj, wd->radio, "radio", "base", "default");
edje_object_signal_callback_add(wd->radio, "elm,action,radio,on", "", _signal_radio_on, obj);
edje_object_signal_callback_add(wd->radio, "elm,action,radio,toggle", "", _signal_radio_on, obj);
elm_widget_resize_object_set(obj, wd->radio);
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
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;
_mirrored_set(obj, elm_widget_mirrored_get(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);
_elm_access_object_register(obj, wd->radio);
_elm_access_text_set(_elm_access_object_get(obj),
ELM_ACCESS_TYPE, E_("Radio"));
_elm_access_callback_set(_elm_access_object_get(obj),
ELM_ACCESS_INFO, _access_info_cb, obj);
_elm_access_callback_set(_elm_access_object_get(obj),
ELM_ACCESS_STATE, _access_state_cb, obj);
return obj;
}
EAPI void
elm_radio_group_add(Evas_Object *obj,
Evas_Object *group)
elm_radio_group_add(Evas_Object *obj, Evas_Object *group)
{
ELM_RADIO_CHECK(obj);
ELM_RADIO_DATA_GET(obj, sd);
ELM_RADIO_DATA_GET(group, sdg);
if (!sdg)
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(sd->group->radios) == 1) return;
sd->group->radios = eina_list_remove(sd->group->radios, obj);
sd->group = calloc(1, sizeof(Group));
sd->group->radios = eina_list_append(sd->group->radios, obj);
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 (sd->group == sdg->group)
return;
else if (wd->group == wd2->group) return;
else
{
sd->group->radios = eina_list_remove(sd->group->radios, obj);
if (!sd->group->radios) free(sd->group);
sd->group = sdg->group;
sd->group->radios = eina_list_append(sd->group->radios, obj);
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 (sd->value == sd->group->value) _state_set(obj, EINA_TRUE);
else _state_set(obj, EINA_FALSE);
if (wd->value == wd->group->value) _state_set(obj, 1);
else _state_set(obj, 0);
}
EAPI void
elm_radio_state_value_set(Evas_Object *obj,
int value)
elm_radio_state_value_set(Evas_Object *obj, int value)
{
ELM_RADIO_CHECK(obj);
ELM_RADIO_DATA_GET(obj, sd);
sd->value = value;
if (sd->value == sd->group->value) _state_set(obj, EINA_TRUE);
else _state_set(obj, EINA_FALSE);
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);
}
EAPI int
elm_radio_state_value_get(const Evas_Object *obj)
{
ELM_RADIO_CHECK(obj) 0;
ELM_RADIO_DATA_GET(obj, sd);
return sd->value;
ELM_CHECK_WIDTYPE(obj, widtype) 0;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return 0;
return wd->value;
}
EAPI void
elm_radio_value_set(Evas_Object *obj,
int value)
elm_radio_value_set(Evas_Object *obj, int value)
{
ELM_RADIO_CHECK(obj);
ELM_RADIO_DATA_GET(obj, sd);
if (value == sd->group->value) return;
sd->group->value = value;
if (sd->group->valuep) *(sd->group->valuep) = sd->group->value;
_state_set_all(sd);
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);
}
EAPI int
elm_radio_value_get(const Evas_Object *obj)
{
ELM_RADIO_CHECK(obj) 0;
ELM_RADIO_DATA_GET(obj, sd);
return sd->group->value;
ELM_CHECK_WIDTYPE(obj, widtype) 0;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return 0;
return wd->group->value;
}
EAPI void
elm_radio_value_pointer_set(Evas_Object *obj,
int *valuep)
elm_radio_value_pointer_set(Evas_Object *obj, int *valuep)
{
ELM_RADIO_CHECK(obj);
ELM_RADIO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (valuep)
{
sd->group->valuep = valuep;
if (*(sd->group->valuep) != sd->group->value)
wd->group->valuep = valuep;
if (*(wd->group->valuep) != wd->group->value)
{
sd->group->value = *(sd->group->valuep);
_state_set_all(sd);
wd->group->value = *(wd->group->valuep);
_state_set_all(wd);
}
}
else sd->group->valuep = NULL;
else
{
wd->group->valuep = NULL;
}
}
EAPI Evas_Object *
@ -412,16 +504,17 @@ elm_radio_selected_object_get(Evas_Object *obj)
{
Eina_List *l;
Evas_Object *child;
Widget_Data *wd2;
ELM_RADIO_CHECK(obj) NULL;
ELM_RADIO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return NULL;
EINA_LIST_FOREACH (sd->group->radios, l, child)
EINA_LIST_FOREACH(wd->group->radios, l, child)
{
ELM_RADIO_DATA_GET(child, sdc);
if (sdc->value == sd->group->value) return child;
wd2 = elm_widget_data_get(child);
if (wd2->value == wd->group->value)
return child;
}
return NULL;
}

View File

@ -30,11 +30,7 @@
* The radio objects will modify this directly. That implies the pointer must
* point to valid memory for as long as the radio objects exist.
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for radio objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* Signals that you can add callbacks for are:
* @li 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.
*

File diff suppressed because it is too large Load Diff

View File

@ -18,12 +18,8 @@
* Only one segment item can be at selected state. A segment item can display
* combination of Text and any Evas_Object like Images or other widget.
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for segment control objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* - @c "changed" - When the user clicks on a segment item which is not
* Smart callbacks one can listen to:
* - "changed" - When the user clicks on a segment item which is not
* previously selected and get selected. The event_info parameter is the
* segment item pointer.
*

View File

@ -1,144 +1,106 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_layout.h"
static const char SEPARATOR_SMART_NAME[] = "elm_separator";
typedef struct _Widget_Data Widget_Data;
typedef struct _Elm_Separator_Smart_Data Elm_Separator_Smart_Data;
struct _Elm_Separator_Smart_Data
struct _Widget_Data
{
Elm_Layout_Smart_Data base;
Eina_Bool horizontal : 1;
Evas_Object *sep;
Eina_Bool horizontal;
};
#define ELM_SEPARATOR_DATA_GET(o, sd) \
Elm_Separator_Smart_Data * sd = evas_object_smart_data_get(o)
static const char *widtype = NULL;
static void _del_hook(Evas_Object *obj);
static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
static void _theme_hook(Evas_Object *obj);
static void _sizing_eval(Evas_Object *obj);
#define ELM_SEPARATOR_DATA_GET_OR_RETURN(o, ptr) \
ELM_SEPARATOR_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define ELM_SEPARATOR_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_SEPARATOR_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_SEPARATOR_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), SEPARATOR_SMART_NAME, __func__)) \
return
/* Inheriting from elm_layout. Besides, we need no more than what is
* there */
EVAS_SMART_SUBCLASS_NEW
(SEPARATOR_SMART_NAME, _elm_separator, Elm_Layout_Smart_Class,
Elm_Layout_Smart_Class, elm_layout_smart_class_get, NULL);
static Eina_Bool
_elm_separator_smart_theme(Evas_Object *obj)
static void
_del_hook(Evas_Object *obj)
{
ELM_SEPARATOR_DATA_GET(obj, sd);
if (sd->horizontal)
eina_stringshare_replace(&(ELM_LAYOUT_DATA(sd)->group), "horizontal");
else
eina_stringshare_replace(&(ELM_LAYOUT_DATA(sd)->group), "vertical");
if (!ELM_WIDGET_CLASS(_elm_separator_parent_sc)->theme(obj)) return EINA_FALSE;
return EINA_TRUE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
free(wd);
}
static void
_elm_separator_smart_sizing_eval(Evas_Object *obj)
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
edje_object_mirrored_set(wd->sep, rtl);
}
static void
_theme_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
_elm_widget_mirrored_reload(obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
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;
ELM_SEPARATOR_DATA_GET(obj, sd);
edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh);
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);
}
static void
_elm_separator_smart_add(Evas_Object *obj)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Separator_Smart_Data);
ELM_WIDGET_CLASS(_elm_separator_parent_sc)->base.add(obj);
priv->horizontal = EINA_FALSE;
elm_widget_can_focus_set(obj, EINA_FALSE);
elm_layout_theme_set
(obj, "separator", "vertical", elm_widget_style_get(obj));
elm_layout_sizing_eval(obj);
}
static void
_elm_separator_smart_set_user(Elm_Layout_Smart_Class *sc)
{
ELM_WIDGET_CLASS(sc)->base.add = _elm_separator_smart_add;
ELM_WIDGET_CLASS(sc)->theme = _elm_separator_smart_theme;
ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */
sc->sizing_eval = _elm_separator_smart_sizing_eval;
}
EAPI Evas_Object *
elm_separator_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
obj = evas_object_smart_add(e, _elm_separator_smart_class_new());
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
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, EINA_FALSE);
wd->sep = edje_object_add(e);
_elm_theme_object_set(obj, wd->sep, "separator", "vertical", "default");
elm_widget_resize_object_set(obj, wd->sep);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_sizing_eval(obj);
return obj;
}
EAPI void
elm_separator_horizontal_set(Evas_Object *obj,
Eina_Bool horizontal)
elm_separator_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
{
ELM_SEPARATOR_CHECK(obj);
ELM_SEPARATOR_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
horizontal = !!horizontal;
if (sd->horizontal == horizontal) return;
sd->horizontal = horizontal;
_elm_separator_smart_theme(obj);
if (wd->horizontal == horizontal) return;
wd->horizontal = horizontal;
_theme_hook(obj);
}
EAPI Eina_Bool
elm_separator_horizontal_get(const Evas_Object *obj)
{
ELM_SEPARATOR_CHECK(obj) EINA_FALSE;
ELM_SEPARATOR_DATA_GET(obj, sd);
return sd->horizontal;
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return wd->horizontal;
}

View File

@ -6,15 +6,9 @@
*
* A separator can be vertical or horizontal.
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for separator objects.
*
* This widget emits the signals coming from @ref Layout.
*
* @ref tutorial_separator is a good example of how to use a separator.
* @{
*/
/**
* @brief Add a separator object to @p parent
*
@ -25,7 +19,6 @@
* @ingroup Separator
*/
EAPI Evas_Object *elm_separator_add(Evas_Object *parent);
/**
* @brief Set the horizontal mode of a separator object
*
@ -35,7 +28,6 @@ EAPI Evas_Object *elm_separator_add(Evas_Object *parent);
* @ingroup Separator
*/
EAPI void elm_separator_horizontal_set(Evas_Object *obj, Eina_Bool horizontal);
/**
* @brief Get the horizontal mode of a separator object
*
@ -47,7 +39,6 @@ EAPI void elm_separator_horizontal_set(Evas_Object *obj, Eina_Bool horizont
* @ingroup Separator
*/
EAPI Eina_Bool elm_separator_horizontal_get(const Evas_Object *obj);
/**
* @}
*/

File diff suppressed because it is too large Load Diff

View File

@ -26,15 +26,11 @@
* the object or applications scaling factor. At any point code can query the
* slider for its value with elm_slider_value_get().
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for slider objects.
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* - @c "changed" - Whenever the slider value is changed by the user.
* - @c "slider,drag,start" - dragging the slider indicator around has started.
* - @c "slider,drag,stop" - dragging the slider indicator around has stopped.
* - @c "delay,changed" - A short time after the value is changed by the user.
* Smart callbacks one can listen to:
* - "changed" - Whenever the slider value is changed by the user.
* - "slider,drag,start" - dragging the slider indicator around has started.
* - "slider,drag,stop" - dragging the slider indicator around has stopped.
* - "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

File diff suppressed because it is too large Load Diff

View File

@ -45,11 +45,8 @@
* cached @b before and @b after the current item, in the widget's
* item list.
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for slideshow objects.
* Smart events one can add callbacks for are:
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* - @c "changed" - when the slideshow switches its view to a new
* item. event_info parameter in callback contains the current visible item
* - @c "transition,end" - when a slide transition ends. event_info parameter

View File

@ -1,48 +1,48 @@
#include <Elementary.h>
#include "elm_priv.h"
static const char TABLE_SMART_NAME[] = "elm_table";
typedef struct _Widget_Data Widget_Data;
#define ELM_TABLE_DATA_GET(o, sd) \
Elm_Widget_Smart_Data * sd = evas_object_smart_data_get(o)
struct _Widget_Data
{
Evas_Object *tbl;
};
#define ELM_TABLE_DATA_GET_OR_RETURN(o, ptr) \
ELM_TABLE_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
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 _theme_hook(Evas_Object *obj);
#define ELM_TABLE_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_TABLE_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
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);
}
#define ELM_TABLE_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), TABLE_SMART_NAME, __func__)) \
return
EVAS_SMART_SUBCLASS_NEW
(TABLE_SMART_NAME, _elm_table, Elm_Widget_Smart_Class,
Elm_Widget_Smart_Class, elm_widget_smart_class_get, NULL);
static void
_del_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
free(wd);
}
static Eina_Bool
_elm_table_smart_focus_next(const Evas_Object *obj,
Elm_Focus_Direction dir,
Evas_Object **next)
_elm_table_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
{
Eina_Bool ret;
Widget_Data *wd = elm_widget_data_get(obj);
const Eina_List *items;
Eina_List *(*list_free)(Eina_List *list);
void *(*list_data_get)(const Eina_List *list);
void *(*list_data_get) (const Eina_List *list);
Eina_List *(*list_free) (Eina_List *list);
ELM_TABLE_DATA_GET(obj, sd);
if ((!wd) || (!wd->tbl))
return EINA_FALSE;
/* Focus chain */
/* TODO: Change this to use other chain */
@ -53,16 +53,18 @@ _elm_table_smart_focus_next(const Evas_Object *obj,
}
else
{
items = evas_object_table_children_get(sd->resize_obj);
items = evas_object_table_children_get(wd->tbl);
list_data_get = eina_list_data_get;
list_free = eina_list_free;
if (!items) return EINA_FALSE;
}
ret = elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next);
Eina_Bool ret = elm_widget_focus_list_next_get(obj, items, list_data_get,
dir, next);
if (list_free) list_free((Eina_List *)items);
if (list_free)
list_free((Eina_List *)items);
return ret;
}
@ -70,31 +72,29 @@ _elm_table_smart_focus_next(const Evas_Object *obj,
static void
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
ELM_TABLE_DATA_GET(obj, sd);
Widget_Data *wd = elm_widget_data_get(obj);
if ((!wd) || (!wd->tbl))
return;
evas_object_table_mirrored_set(sd->resize_obj, rtl);
evas_object_table_mirrored_set(wd->tbl, rtl);
}
static Eina_Bool
_elm_table_smart_theme(Evas_Object *obj)
static void
_theme_hook(Evas_Object *obj)
{
if (!_elm_table_parent_sc->theme(obj)) return EINA_FALSE;
_elm_widget_mirrored_reload(obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
return EINA_TRUE;
}
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;
ELM_TABLE_DATA_GET(obj, sd);
evas_object_size_hint_min_get(sd->resize_obj, &minw, &minh);
evas_object_size_hint_max_get(sd->resize_obj, &maxw, &maxh);
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);
@ -106,198 +106,123 @@ _sizing_eval(Evas_Object *obj)
}
static void
_on_size_hints_changed(void *data,
Evas *e __UNUSED__,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
_sizing_eval(data);
}
static Eina_Bool
_elm_table_smart_sub_object_del(Evas_Object *obj,
Evas_Object *child)
static void
_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
if (!_elm_table_parent_sc->sub_object_del(obj, child)) return EINA_FALSE;
_sizing_eval(obj);
return EINA_TRUE;
}
static void
_elm_table_smart_add(Evas_Object *obj)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Widget_Smart_Data);
priv->resize_obj = evas_object_table_add(evas_object_evas_get(obj));
evas_object_event_callback_add
(priv->resize_obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_on_size_hints_changed, obj);
_elm_table_parent_sc->base.add(obj);
elm_widget_can_focus_set(obj, EINA_FALSE);
elm_widget_highlight_ignore_set(obj, EINA_FALSE);
_elm_table_smart_theme(obj);
}
static void
_elm_table_smart_del(Evas_Object *obj)
{
Eina_List *l;
Evas_Object *child;
ELM_TABLE_DATA_GET(obj, sd);
evas_object_event_callback_del_full
(sd->resize_obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_on_size_hints_changed, obj);
/* let's make our table object the *last* to be processed, since it
* may (smart) parent other sub objects here */
EINA_LIST_FOREACH (sd->subobjs, l, child)
{
if (child == sd->resize_obj)
{
sd->subobjs = eina_list_demote_list(sd->subobjs, l);
break;
}
}
_elm_table_parent_sc->base.del(obj);
}
static void
_elm_table_smart_set_user(Elm_Widget_Smart_Class *sc)
{
sc->base.add = _elm_table_smart_add;
sc->base.del = _elm_table_smart_del;
sc->sub_object_del = _elm_table_smart_sub_object_del;
sc->theme = _elm_table_smart_theme;
sc->focus_next = _elm_table_smart_focus_next;
}
EAPI Evas_Object *
elm_table_add(Evas_Object *parent)
{
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
e = evas_object_evas_get(parent);
if (!e) return NULL;
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);
elm_widget_focus_next_hook_set(obj, _elm_table_focus_next_hook);
elm_widget_can_focus_set(obj, EINA_FALSE);
elm_widget_highlight_ignore_set(obj, EINA_FALSE);
elm_widget_theme_hook_set(obj, _theme_hook);
obj = evas_object_smart_add(e, _elm_table_smart_class_new());
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);
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
return obj;
}
EAPI void
elm_table_homogeneous_set(Evas_Object *obj,
Eina_Bool homogeneous)
elm_table_homogeneous_set(Evas_Object *obj, Eina_Bool homogeneous)
{
ELM_TABLE_CHECK(obj);
ELM_TABLE_DATA_GET(obj, sd);
evas_object_table_homogeneous_set(sd->resize_obj, homogeneous);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_table_homogeneous_set(wd->tbl, homogeneous);
}
EAPI Eina_Bool
elm_table_homogeneous_get(const Evas_Object *obj)
{
ELM_TABLE_CHECK(obj) EINA_FALSE;
ELM_TABLE_DATA_GET(obj, sd);
return evas_object_table_homogeneous_get(sd->resize_obj);
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return evas_object_table_homogeneous_get(wd->tbl);
}
EAPI void
elm_table_padding_set(Evas_Object *obj,
Evas_Coord horizontal,
Evas_Coord vertical)
elm_table_padding_set(Evas_Object *obj, Evas_Coord horizontal, Evas_Coord vertical)
{
ELM_TABLE_CHECK(obj);
ELM_TABLE_DATA_GET(obj, sd);
evas_object_table_padding_set
(sd->resize_obj, horizontal, 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);
}
EAPI void
elm_table_padding_get(const Evas_Object *obj,
Evas_Coord *horizontal,
Evas_Coord *vertical)
elm_table_padding_get(const Evas_Object *obj, Evas_Coord *horizontal, Evas_Coord *vertical)
{
ELM_TABLE_CHECK(obj);
ELM_TABLE_DATA_GET(obj, sd);
evas_object_table_padding_get
(sd->resize_obj, horizontal, vertical);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_table_padding_get(wd->tbl, horizontal, vertical);
}
EAPI void
elm_table_pack(Evas_Object *obj,
Evas_Object *subobj,
int x,
int y,
int w,
int h)
elm_table_pack(Evas_Object *obj, Evas_Object *subobj, int x, int y, int w, int h)
{
ELM_TABLE_CHECK(obj);
ELM_TABLE_DATA_GET(obj, sd);
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(sd->resize_obj, subobj, x, y, w, h);
evas_object_table_pack(wd->tbl, subobj, x, y, w, h);
}
EAPI void
elm_table_unpack(Evas_Object *obj,
Evas_Object *subobj)
elm_table_unpack(Evas_Object *obj, Evas_Object *subobj)
{
ELM_TABLE_CHECK(obj);
ELM_TABLE_DATA_GET(obj, sd);
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(sd->resize_obj, subobj);
evas_object_table_unpack(wd->tbl, subobj);
}
EAPI void
elm_table_pack_set(Evas_Object *subobj,
int x,
int y,
int w,
int h)
elm_table_pack_set(Evas_Object *subobj, int x, int y, int w, int h)
{
Evas_Object *obj = elm_widget_parent_widget_get(subobj);
ELM_TABLE_CHECK(obj);
ELM_TABLE_DATA_GET(obj, sd);
evas_object_table_pack(sd->resize_obj, subobj, x, y, w, h);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_table_pack(wd->tbl, subobj, x, y, w, h);
}
EAPI void
elm_table_pack_get(Evas_Object *subobj,
int *x,
int *y,
int *w,
int *h)
elm_table_pack_get(Evas_Object *subobj, int *x, int *y, int *w, int *h)
{
Evas_Object *obj = elm_widget_parent_widget_get(subobj);
unsigned short ix, iy, iw, ih;
ELM_TABLE_CHECK(obj);
ELM_TABLE_DATA_GET(obj, sd);
evas_object_table_pack_get(sd->resize_obj, subobj, &ix, &iy, &iw, &ih);
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_table_pack_get(wd->tbl, subobj, &ix, &iy, &iw, &ih);
if (x) *x = ix;
if (y) *y = iy;
if (w) *w = iw;
@ -305,11 +230,14 @@ elm_table_pack_get(Evas_Object *subobj,
}
EAPI void
elm_table_clear(Evas_Object *obj,
Eina_Bool clear)
elm_table_clear(Evas_Object *obj, Eina_Bool clear)
{
ELM_TABLE_CHECK(obj);
ELM_TABLE_DATA_GET(obj, sd);
evas_object_table_clear(sd->resize_obj, clear);
Eina_List *chld;
Evas_Object *o;
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
chld = evas_object_table_children_get(wd->tbl);
EINA_LIST_FREE(chld, o) elm_widget_sub_object_del(obj, o);
evas_object_table_clear(wd->tbl, clear);
}

View File

@ -1,72 +1,49 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_layout.h"
#ifdef HAVE_EMOTION
# include <Emotion.h>
#endif
/* TODO: add buffering support to Emotion and display buffering
* progress in the theme when needed */
/* TODO: add buffering support to Emotion and display buffering progression in the theme when needed */
static const char VIDEO_SMART_NAME[] = "elm_video";
typedef struct _Elm_Video_Smart_Data Elm_Video_Smart_Data;
struct _Elm_Video_Smart_Data
typedef struct _Widget_Data Widget_Data;
struct _Widget_Data
{
Elm_Layout_Smart_Data base;
Evas_Object *layout;
Evas_Object *emotion;
Evas_Object *emotion;
Ecore_Timer *timer;
Ecore_Timer *timer;
Eina_Bool stop : 1;
Eina_Bool remember : 1;
Eina_Bool stop : 1;
Eina_Bool remember : 1;
};
#define ELM_VIDEO_DATA_GET(o, sd) \
Elm_Video_Smart_Data * sd = evas_object_smart_data_get(o)
#ifdef HAVE_EMOTION
static const char *widtype = NULL;
#define ELM_VIDEO_DATA_GET_OR_RETURN(o, ptr) \
ELM_VIDEO_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
static const Evas_Smart_Cb_Description _signals[] = {
{ NULL, NULL }
};
#define ELM_VIDEO_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_VIDEO_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_VIDEO_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), VIDEO_SMART_NAME, __func__)) \
return
/* Inheriting from elm_layout. Besides, we need no more than what is
* there */
EVAS_SMART_SUBCLASS_NEW
(VIDEO_SMART_NAME, _elm_video, Elm_Layout_Smart_Class,
Elm_Layout_Smart_Class, elm_layout_smart_class_get, NULL);
static void _del_hook(Evas_Object *obj);
static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
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 _on_focus_hook(void *data, Evas_Object *obj);
static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src,
Evas_Callback_Type type, void *event_info);
static Eina_Bool
_elm_video_smart_event(Evas_Object *obj,
Evas_Object *src __UNUSED__,
Evas_Callback_Type type,
void *event_info)
_event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info)
{
#ifdef HAVE_EMOTION
Evas_Event_Key_Down *ev = event_info;
if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
Evas_Event_Key_Down *ev = event_info;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
if (elm_widget_disabled_get(obj)) return EINA_FALSE;
if ((!strcmp(ev->keyname, "Left")) ||
((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
{
@ -82,10 +59,8 @@ _elm_video_smart_event(Evas_Object *obj,
}
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
return EINA_TRUE;
}
if ((!strcmp(ev->keyname, "Right")) ||
((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
{
@ -102,10 +77,8 @@ _elm_video_smart_event(Evas_Object *obj,
}
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
return EINA_TRUE;
}
if (!strcmp(ev->keyname, "space"))
{
if (elm_video_is_playing_get(obj))
@ -113,512 +86,496 @@ _elm_video_smart_event(Evas_Object *obj,
else
elm_video_play(obj);
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
return EINA_TRUE;
}
INF("keyname: '%s' not handled", ev->keyname);
fprintf(stderr, "keyname: '%s' not handle\n", ev->keyname);
return EINA_FALSE;
#else
(void *)obj;
(void *)type;
(void *)event_info;
return EINA_FALSE;
#endif
}
static void
_elm_video_smart_sizing_eval(Evas_Object *obj)
_del_hook(Evas_Object *obj)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_DATA_GET(obj, sd);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->timer) ecore_timer_del(wd->timer);
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->layout, "elm,action,focus", "elm");
evas_object_focus_set(wd->layout, EINA_TRUE);
}
else
{
edje_object_signal_emit(wd->layout, "elm,action,unfocus", "elm");
evas_object_focus_set(wd->layout, EINA_FALSE);
}
}
static void
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
edje_object_mirrored_set(wd->layout, rtl);
}
static void
_theme_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
_elm_widget_mirrored_reload(obj);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_elm_theme_object_set(obj, wd->layout, "video", "base", elm_widget_style_get(obj));
edje_object_scale_set(wd->layout, 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;
Evas_Coord w, h;
evas_object_size_hint_request_get(sd->emotion, &minw, &minh);
evas_object_size_hint_aspect_set
(sd->emotion, EVAS_ASPECT_CONTROL_BOTH, minw, minh);
edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &w, &h);
if (!wd) return;
evas_object_size_hint_request_get(wd->emotion, &minw, &minh);
evas_object_size_hint_aspect_set(wd->emotion, EVAS_ASPECT_CONTROL_BOTH, minw, minh);
edje_object_size_min_calc(wd->layout, &w, &h);
if (w != 0 && h != 0)
{
minw = w;
minh = h;
}
evas_object_size_hint_aspect_set(obj, EVAS_ASPECT_CONTROL_BOTH, minw, minh);
#else
(void *)obj;
#endif
}
#ifdef HAVE_EMOTION
static void
_on_size_hints_changed(void *data,
Evas *e __UNUSED__,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
{
elm_layout_sizing_eval(data);
}
static void
_on_open_done(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
elm_layout_signal_emit(data, "elm,video,open", "elm");
_sizing_eval(data);
}
static void
_on_playback_started(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
elm_layout_signal_emit(data, "elm,video,play", "elm");
Widget_Data *wd = elm_widget_data_get(obj);
if (wd->remember) emotion_object_last_position_save(wd->emotion);
}
static void
_on_playback_finished(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_open_done(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
elm_layout_signal_emit(data, "elm,video,end", "elm");
Widget_Data *wd = elm_widget_data_get(data);
edje_object_signal_emit(wd->layout, "elm,video,open", "elm");
}
static void
_on_aspect_ratio_updated(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_playback_started(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
elm_layout_sizing_eval(data);
Widget_Data *wd = elm_widget_data_get(data);
edje_object_signal_emit(wd->layout, "elm,video,play", "elm");
}
static void
_on_title_changed(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_playback_finished(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
Widget_Data *wd = elm_widget_data_get(data);
edje_object_signal_emit(wd->layout, "elm,video,end", "elm");
}
static void
_update_aspect_ratio(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
_sizing_eval(data);
}
static void
_title_change(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
Widget_Data *wd = elm_widget_data_get(data);
const char *title;
ELM_VIDEO_DATA_GET(data, sd);
title = emotion_object_title_get(sd->emotion);
elm_layout_text_set(data, "elm,title", title);
elm_layout_signal_emit(data, "elm,video,title", "elm");
title = emotion_object_title_get(wd->emotion);
edje_object_part_text_escaped_set(wd->layout, "elm,title", title);
edje_object_signal_emit(wd->layout, "elm,video,title", "elm");
}
static void
_on_audio_level_changed(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
_audio_level_change(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
(void)data;
(void) data;
}
static Eina_Bool
_suspend_cb(void *data)
{
Widget_Data *wd = elm_widget_data_get(data);
double interval;
ELM_VIDEO_DATA_GET(data, sd);
interval = ecore_timer_interval_get(sd->timer);
interval = ecore_timer_interval_get(wd->timer);
if (interval <= 20)
emotion_object_suspend_set(sd->emotion, EMOTION_SLEEP);
emotion_object_suspend_set(wd->emotion, EMOTION_SLEEP);
else if (interval <= 30)
emotion_object_suspend_set(sd->emotion, EMOTION_DEEP_SLEEP);
emotion_object_suspend_set(wd->emotion, EMOTION_DEEP_SLEEP);
else
{
emotion_object_suspend_set(sd->emotion, EMOTION_HIBERNATE);
sd->timer = NULL;
emotion_object_suspend_set(wd->emotion, EMOTION_HIBERNATE);
wd->timer = NULL;
return ECORE_CALLBACK_CANCEL;
}
ecore_timer_interval_set(sd->timer, interval + 10);
ecore_timer_interval_set(wd->timer, interval + 10);
return ECORE_CALLBACK_RENEW;
}
#endif
Eina_Bool
_elm_video_check(Evas_Object *video)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_CHECK(video) EINA_FALSE;
return EINA_TRUE;
ELM_CHECK_WIDTYPE(video, widtype) EINA_FALSE;
return EINA_TRUE;
#else
(void)video;
return EINA_FALSE;
(void) video;
return EINA_FALSE;
#endif
}
static void
_elm_video_smart_add(Evas_Object *obj)
{
EVAS_SMART_DATA_ALLOC(obj, Elm_Video_Smart_Data);
ELM_WIDGET_CLASS(_elm_video_parent_sc)->base.add(obj);
elm_widget_can_focus_set(obj, EINA_TRUE);
#ifdef HAVE_EMOTION
priv->stop = EINA_FALSE;
priv->remember = EINA_FALSE;
priv->emotion = emotion_object_add(evas_object_evas_get(obj));
emotion_object_init(priv->emotion, NULL);
elm_layout_theme_set(obj, "video", "base", elm_widget_style_get(obj));
elm_layout_content_set(obj, "elm.swallow.video", priv->emotion);
evas_object_smart_callback_add
(priv->emotion, "open_done", _on_open_done, obj);
evas_object_smart_callback_add
(priv->emotion, "playback_started", _on_playback_started, obj);
evas_object_smart_callback_add
(priv->emotion, "playback_finished", _on_playback_finished, obj);
evas_object_smart_callback_add
(priv->emotion, "frame_resize", _on_aspect_ratio_updated, obj);
evas_object_smart_callback_add
(priv->emotion, "title_change", _on_title_changed, obj);
evas_object_smart_callback_add
(priv->emotion, "audio_level_change", _on_audio_level_changed, obj);
evas_object_event_callback_add
(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_size_hints_changed, NULL);
priv->timer = ecore_timer_add(20.0, _suspend_cb, obj);
#endif
}
static void
_elm_video_smart_del(Evas_Object *obj)
{
ELM_VIDEO_DATA_GET(obj, sd);
#ifdef HAVE_EMOTION
if (sd->timer) ecore_timer_del(sd->timer);
if (sd->remember) emotion_object_last_position_save(sd->emotion);
#endif
ELM_WIDGET_CLASS(_elm_video_parent_sc)->base.del(obj);
}
static void
_elm_video_smart_set_user(Elm_Layout_Smart_Class *sc)
{
ELM_WIDGET_CLASS(sc)->base.add = _elm_video_smart_add;
ELM_WIDGET_CLASS(sc)->base.del = _elm_video_smart_del;
ELM_WIDGET_CLASS(sc)->event = _elm_video_smart_event;
ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */
sc->sizing_eval = _elm_video_smart_sizing_eval;
}
EAPI Evas_Object *
elm_video_add(Evas_Object *parent)
{
#ifdef HAVE_EMOTION
Evas *e;
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
ELM_SET_WIDTYPE(widtype, "video");
elm_widget_type_set(obj, "video");
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, EINA_TRUE);
elm_widget_event_hook_set(obj, _event_hook);
e = evas_object_evas_get(parent);
if (!e) return NULL;
wd->stop = EINA_FALSE;
wd->remember = EINA_FALSE;
obj = evas_object_smart_add(e, _elm_video_smart_class_new());
wd->layout = edje_object_add(e);
_elm_theme_object_set(obj, wd->layout, "video", "base", "default");
elm_widget_resize_object_set(obj, wd->layout);
evas_object_show(wd->layout);
evas_object_size_hint_weight_set(wd->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
wd->emotion = emotion_object_add(e);
emotion_object_init(wd->emotion, NULL);
elm_widget_sub_object_add(obj, wd->emotion);
edje_object_part_swallow(wd->layout, "elm.swallow.video", wd->emotion);
evas_object_smart_callback_add(wd->emotion, "open_done", _open_done, obj);
evas_object_smart_callback_add(wd->emotion, "playback_started", _playback_started, obj);
evas_object_smart_callback_add(wd->emotion, "playback_finished", _playback_finished, obj);
evas_object_smart_callback_add(wd->emotion, "frame_resize", _update_aspect_ratio, obj);
evas_object_smart_callback_add(wd->emotion, "title_change", _title_change, obj);
evas_object_smart_callback_add(wd->emotion, "audio_level_change", _audio_level_change, 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, NULL);
evas_object_smart_callbacks_descriptions_set(obj, _signals);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_sizing_eval(obj);
wd->timer = ecore_timer_add(20.0, _suspend_cb, obj);
return obj;
#else
(void)parent;
(void) parent;
return NULL;
#endif
}
EAPI Eina_Bool
elm_video_file_set(Evas_Object *obj,
const char *filename)
elm_video_file_set(Evas_Object *video, const char *filename)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_CHECK(obj) EINA_FALSE;
ELM_VIDEO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(video, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(video);
if (sd->remember) emotion_object_last_position_save(sd->emotion);
sd->stop = EINA_FALSE;
if (!emotion_object_file_set(sd->emotion, filename)) return EINA_FALSE;
if (wd->remember) emotion_object_last_position_save(wd->emotion);
wd->stop = EINA_FALSE;
if (!emotion_object_file_set(wd->emotion, filename)) return EINA_FALSE;
if ((!strncmp(filename, "file://", 7)) || (!strstr(filename, "://")))
emotion_object_last_position_load(sd->emotion);
emotion_object_last_position_load(wd->emotion);
elm_layout_signal_emit(obj, "elm,video,load", "elm");
edje_object_signal_emit(wd->layout, "elm,video,load", "elm");
return EINA_TRUE;
#else
(void)obj;
(void)filename;
(void) video;
(void) filename;
return EINA_FALSE;
#endif
}
EAPI Evas_Object *
elm_video_emotion_get(const Evas_Object *obj)
elm_video_emotion_get(const Evas_Object *video)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_CHECK(obj) NULL;
ELM_VIDEO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(video, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(video);
return sd->emotion;
return wd->emotion;
#else
(void)obj;
(void) video;
return NULL;
#endif
}
EAPI void
elm_video_play(Evas_Object *obj)
elm_video_play(Evas_Object *video)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_CHECK(obj);
ELM_VIDEO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(video, widtype);
Widget_Data *wd = elm_widget_data_get(video);
if (emotion_object_play_get(sd->emotion)) return;
if (emotion_object_play_get(wd->emotion)) return ;
if (sd->timer) ecore_timer_del(sd->timer);
sd->timer = NULL;
sd->stop = EINA_FALSE;
emotion_object_play_set(sd->emotion, EINA_TRUE);
if (wd->timer) ecore_timer_del(wd->timer);
wd->timer = NULL;
wd->stop = EINA_FALSE;
emotion_object_play_set(wd->emotion, EINA_TRUE);
#else
(void)obj;
(void) video;
#endif
}
/* FIXME: pause will setup timer and go into sleep or
* hibernate after a while without activity.
*/
EAPI void
elm_video_pause(Evas_Object *obj)
elm_video_pause(Evas_Object *video)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_CHECK(obj);
ELM_VIDEO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(video, widtype);
Widget_Data *wd = elm_widget_data_get(video);
if (!emotion_object_play_get(sd->emotion)) return;
if (!emotion_object_play_get(wd->emotion)) return ;
if (!sd->timer) sd->timer = ecore_timer_add(20.0, _suspend_cb, obj);
emotion_object_play_set(sd->emotion, EINA_FALSE);
elm_layout_signal_emit(obj, "elm,video,pause", "elm");
if (!wd->timer) wd->timer = ecore_timer_add(20.0, _suspend_cb, video);
emotion_object_play_set(wd->emotion, EINA_FALSE);
edje_object_signal_emit(wd->layout, "elm,video,pause", "elm");
#else
(void)obj;
(void) video;
#endif
}
/* FIXME: stop should go into hibernate state directly.
*/
EAPI void
elm_video_stop(Evas_Object *obj)
elm_video_stop(Evas_Object *video)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_CHECK(obj);
ELM_VIDEO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(video, widtype);
Widget_Data *wd = elm_widget_data_get(video);
if (!emotion_object_play_get(sd->emotion) && sd->stop) return;
if (!emotion_object_play_get(wd->emotion) && wd->stop) return ;
if (sd->timer) ecore_timer_del(sd->timer);
sd->timer = NULL;
sd->stop = EINA_TRUE;
emotion_object_play_set(sd->emotion, EINA_FALSE);
elm_layout_signal_emit(obj, "elm,video,stop", "elm");
emotion_object_suspend_set(sd->emotion, EMOTION_HIBERNATE);
if (wd->timer) ecore_timer_del(wd->timer);
wd->timer = NULL;
wd->stop = EINA_TRUE;
emotion_object_play_set(wd->emotion, EINA_FALSE);
edje_object_signal_emit(wd->layout, "elm,video,stop", "elm");
emotion_object_suspend_set(wd->emotion, EMOTION_HIBERNATE);
#else
(void)obj;
(void) video;
#endif
}
EAPI Eina_Bool
elm_video_is_playing_get(const Evas_Object *obj)
elm_video_is_playing_get(const Evas_Object *video)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_CHECK(obj) EINA_FALSE;
ELM_VIDEO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(video, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(video);
return emotion_object_play_get(sd->emotion);
return emotion_object_play_get(wd->emotion);
#else
(void)obj;
(void) video;
return EINA_FALSE;
#endif
}
EAPI Eina_Bool
elm_video_is_seekable_get(const Evas_Object *obj)
elm_video_is_seekable_get(const Evas_Object *video)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_CHECK(obj) EINA_FALSE;
ELM_VIDEO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(video, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(video);
return emotion_object_seekable_get(sd->emotion);
return emotion_object_seekable_get(wd->emotion);
#else
(void)obj;
(void) video;
return EINA_FALSE;
#endif
}
EAPI Eina_Bool
elm_video_audio_mute_get(const Evas_Object *obj)
elm_video_audio_mute_get(const Evas_Object *video)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_CHECK(obj) EINA_FALSE;
ELM_VIDEO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(video, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(video);
return emotion_object_audio_mute_get(sd->emotion);
return emotion_object_audio_mute_get(wd->emotion);
#else
(void)obj;
(void) video;
return EINA_FALSE;
#endif
}
EAPI void
elm_video_audio_mute_set(Evas_Object *obj,
Eina_Bool mute)
elm_video_audio_mute_set(Evas_Object *video, Eina_Bool mute)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_CHECK(obj);
ELM_VIDEO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(video, widtype);
Widget_Data *wd = elm_widget_data_get(video);
emotion_object_audio_mute_set(sd->emotion, mute);
emotion_object_audio_mute_set(wd->emotion, mute);
#else
(void)obj;
(void)mute;
(void) video;
(void) mute;
#endif
}
EAPI double
elm_video_audio_level_get(const Evas_Object *obj)
elm_video_audio_level_get(const Evas_Object *video)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_CHECK(obj) 0.0;
ELM_VIDEO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(video, widtype) 0.0;
Widget_Data *wd = elm_widget_data_get(video);
return emotion_object_audio_volume_get(sd->emotion);
return emotion_object_audio_volume_get(wd->emotion);
#else
(void)obj;
(void) video;
return 0.0;
#endif
}
EAPI void
elm_video_audio_level_set(Evas_Object *obj,
double volume)
elm_video_audio_level_set(Evas_Object *video, double volume)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_CHECK(obj);
ELM_VIDEO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(video, widtype);
Widget_Data *wd = elm_widget_data_get(video);
emotion_object_audio_volume_set(sd->emotion, volume);
emotion_object_audio_volume_set(wd->emotion, volume);
#else
(void)obj;
(void)volume;
(void) video;
(void) volume;
#endif
}
EAPI double
elm_video_play_position_get(const Evas_Object *obj)
elm_video_play_position_get(const Evas_Object *video)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_CHECK(obj) 0.0;
ELM_VIDEO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(video, widtype) 0.0;
Widget_Data *wd = elm_widget_data_get(video);
return emotion_object_position_get(sd->emotion);
return emotion_object_position_get(wd->emotion);
#else
(void)obj;
(void) video;
return 0.0;
#endif
}
EAPI void
elm_video_play_position_set(Evas_Object *obj,
double position)
elm_video_play_position_set(Evas_Object *video, double position)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_CHECK(obj);
ELM_VIDEO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(video, widtype);
Widget_Data *wd = elm_widget_data_get(video);
emotion_object_position_set(sd->emotion, position);
emotion_object_position_set(wd->emotion, position);
#else
(void)obj;
(void)position;
(void) video;
(void) position;
#endif
}
EAPI double
elm_video_play_length_get(const Evas_Object *obj)
elm_video_play_length_get(const Evas_Object *video)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_CHECK(obj) 0.0;
ELM_VIDEO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(video, widtype) 0.0;
Widget_Data *wd = elm_widget_data_get(video);
return emotion_object_play_length_get(sd->emotion);
return emotion_object_play_length_get(wd->emotion);
#else
(void)obj;
(void) video;
return 0.0;
#endif
}
EAPI const char *
elm_video_title_get(const Evas_Object *obj)
elm_video_title_get(const Evas_Object *video)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_CHECK(obj) NULL;
ELM_VIDEO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(video, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(video);
return emotion_object_title_get(sd->emotion);
return emotion_object_title_get(wd->emotion);
#else
(void)obj;
(void) video;
return NULL;
#endif
}
EAPI void
elm_video_remember_position_set(Evas_Object *obj,
Eina_Bool remember)
elm_video_remember_position_set(Evas_Object *video, Eina_Bool remember)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_CHECK(obj);
ELM_VIDEO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(video, widtype);
Widget_Data *wd = elm_widget_data_get(video);
sd->remember = remember;
wd->remember = remember;
#else
(void)obj;
(void)remember;
(void) video;
(void) remember;
#endif
}
EAPI Eina_Bool
elm_video_remember_position_get(const Evas_Object *obj)
elm_video_remember_position_get(const Evas_Object *video)
{
#ifdef HAVE_EMOTION
ELM_VIDEO_CHECK(obj) EINA_FALSE;
ELM_VIDEO_DATA_GET(obj, sd);
ELM_CHECK_WIDTYPE(video, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(video);
return sd->remember;
return wd->remember;
#else
(void)obj;
(void) video;
return EINA_FALSE;
#endif
}

View File

@ -20,19 +20,16 @@
* linked Elm_Video so it will use the video decoder, if available. It also
* activates the "remember" function on the linked Elm_Video object.
*
* Both widgets inherit from the @ref Layout one, so that all the
* functions acting on it also work for video objects.
* Signals that you can add callback for are :
*
* The player widget emits the following signals, besides the ones
* sent from @ref Layout:
* - @c "forward,clicked" - the user clicked the forward button.
* - @c "info,clicked" - the user clicked the info button.
* - @c "next,clicked" - the user clicked the next button.
* - @c "pause,clicked" - the user clicked the pause button.
* - @c "play,clicked" - the user clicked the play button.
* - @c "prev,clicked" - the user clicked the prev button.
* - @c "rewind,clicked" - the user clicked the rewind button.
* - @c "stop,clicked" - the user clicked the stop button.
* "forward,clicked" - the user clicked the forward button.
* "info,clicked" - the user clicked the info button.
* "next,clicked" - the user clicked the next button.
* "pause,clicked" - the user clicked the pause button.
* "play,clicked" - the user clicked the play button.
* "prev,clicked" - the user clicked the prev button.
* "rewind,clicked" - the user clicked the rewind button.
* "stop,clicked" - the user clicked the stop button.
*
* Default content parts of the player widget that you can use for are:
* @li "video" - A video of the player

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -188,297 +188,6 @@
#endif
#define ELM_INTERNAL_API_VERSION 7000
/**
* @defgroup Widget Widgets Extension Infrastructure
*
* This section is intended for people willing to create @b custom
* Elementary widgets or to contribute new (useful, unique) widgets
* upstream. If neither is your case, this text won't be of any use
* for you.
*
* Elementary widgets are built in a @b hierarchical fashion. The idea
* is to factorize as much code as possible between widgets with
* behavioral similarities, as long as to facilitate the creation of
* @b custom, new widgets, may the user need them.
*
* It all starts with a base class, which aggregates behaviour
* @b every Elementary widget is supposed to have:
* #Elm_Widget_Smart_Class. Every Elementary widget will be of that
* type, be it directly or by means of @b inheriting from it.
*
* #Elm_Widget_Smart_Class happens to be an @c Evas_Smart_Class. If
* you check out Evas' documentation on it, you'll see it's how one is
* supposed to create custom Evas objects, what Elementary widgets
* are.
*
* Once one instantiates an Elementary widget, since it inherits from
* #Elm_Widget_Smart_Class, the system will raise a class instance of
* that type for you. But that happens only @b once: the first time
* you ask for an Elementary widget (of a given type). All subsequent
* ones will only point to the very same class instance. Since it's
* the class which points to the functions implementing the behavior
* of objects of that type, all of the live instances of Elementary
* widgets (of that type) will share the same blob of code loaded in
* memory to execute their routines.
*
* Now go and take a look at #Elm_Widget_Smart_Class's fields. Because
* it inherits from Evas' base smart class, we got a field of that
* type as the first member, so that Evas can handle Elementary
* objects internally as if they were 'normal' Evas objects. Evas has
* the Evas-only behavior function pointers in there, so it's all it
* needs.
*
* Then, comes a version field, so that whenever we got to update or
* change the fields on our base smart class, there'll be a runtime
* check of the version expected by Elementary and the one provided by
* any code linking with it. A mismatch will show the developer of
* that code he/she needs to recompile and link its code to a newer
* version of Elementary.
*
* The next fields are the class functions itself. We call them
* 'virtual' because, as in object-oriented languages, one is supposed
* here to override them on inheriting classes. On most of
* inheritances you'll probably want to call the parent's version of
* the class function too: you must analise each case to tell.
*
* Take a look at #Elm_Widget_Smart_Data. That's private data bound to
* each Elementary object @b instance. It aggregates data needed for
* all widgets, since it's meant for the #Elm_Widget_Smart_Class-typed
* ones.
*
* When inheriting from that base type, instance data for this new
* class has to have, as the first member, a field of type
* #Elm_Widget_Smart_Data. This has to be respected recursively -- if
* a third class is to be created inheriting from the one that is a
* direct 'child' of #Elm_Widget_Smart_Class, then the private data on
* this third class has to have, as its first field, a variable of the
* type of the private data of the second class (its parent), direct
* child of #Elm_Widget_Smart_Class.
*
* [image here later, explaining process]
*
* It is from the base private data, #Elm_Widget_Smart_Data, that we
* reach an object's class functions, by the given object
* instance. This is the reason of the first field of that struct: a
* pointer set to point to its class when the object is instantiated.
*
* @section elm-migration Elementary's Migration to a hierarchical schema
*
* What's been stated before is a work in progress. Elementary 1.0 is
* @b not hierarchical in this way, but the idea is to get at this
* shape, now. This section is here to explain the process of
* migration, and it will be taken off once it's completed.
*
* We want to migrate widgets to the new schema progressively, one by
* one. In order for this to happen without hurting anyone during the
* process, it was made a @b compatibility class for Elementary
* widgets, to take place of the old, unique smart class for
* them. This is the role of #Elm_Widget_Compat_Smart_Class.
*
* All functions we had as 'hooks' before will be migrated to class
* functions. As you can see, all calls to @b instance hooks on the
* common code for widgets were replaced to <b> class function calls
* </b>, now. It just happens that, for
* #Elm_Widget_Compat_Smart_Class-typed widgets, i.e., the ones not
* migrated to the new schema yet, class calls are proxyed back to
* their instance 'hook' calls, that live on
* #Elm_Widget_Compat_Smart_Data structs. Those structs are
* #Elm_Widget_Smart_Data augmented with what is needed to reach the
* original widget's data field set, so that things go on @b unnoticed
* for the widgets awaiting translation to the new hierarchy.
*
* The following figure illustrates the old an new widget schemas,
* with highlights on their differences.
*
* @image html elm-widget-hierarchy.png
* @image rtf elm-widget-hierarchy.png
* @image latex elm-widget-hierarchy.eps
*/
/**
* @addtogroup Widget
* @{
*/
/**
* @def ELM_WIDGET_CLASS
*
* Use this macro to cast whichever subclass of
* #Elm_Widget_Smart_Class into it, so to acess its fields.
*
* @ingroup Widget
*/
#define ELM_WIDGET_CLASS(x) ((Elm_Widget_Smart_Class *) x)
/**
* @def ELM_WIDGET_DATA
*
* Use this macro to cast whichever subdata of
* #Elm_Widget_Smart_Data into it, so to acess its fields.
*
* @ingroup Widget
*/
#define ELM_WIDGET_DATA(x) ((Elm_Widget_Smart_Data *) x)
/**
* @def ELM_WIDGET_SMART_CLASS_VERSION
*
* Current version for Elementary widget @b base smart class, a value
* which goes to _Elm_Widget_Smart_Class::version.
*
* @ingroup Wiget
*/
#define ELM_WIDGET_SMART_CLASS_VERSION 1
/**
* @def ELM_WIDGET_SMART_CLASS_INIT
*
* Initializer for a whole #Elm_Widget_Smart_Class structure, with
* @c NULL values on its specific fields.
*
* @param smart_class_init initializer to use for the "base" field
* (#Evas_Smart_Class).
*
* @see EVAS_SMART_CLASS_INIT_NULL
* @see EVAS_SMART_CLASS_INIT_VERSION
* @see EVAS_SMART_CLASS_INIT_NAME_VERSION
* @see ELM_WIDGET_SMART_CLASS_INIT_NULL
* @see ELM_WIDGET_SMART_CLASS_INIT_NAME_VERSION
*
* @ingroup Widget
*/
#define ELM_WIDGET_SMART_CLASS_INIT(smart_class_init) \
{smart_class_init, ELM_WIDGET_SMART_CLASS_VERSION, NULL, NULL, NULL, NULL, \
NULL, NULL, NULL, NULL}
/**
* @def ELM_WIDGET_SMART_CLASS_INIT_NULL
*
* Initializer to zero out a whole #Elm_Widget_Smart_Class structure.
*
* @see ELM_WIDGET_SMART_CLASS_INIT_NAME_VERSION
* @see ELM_WIDGET_SMART_CLASS_INIT
*
* @ingroup Widget
*/
#define ELM_WIDGET_SMART_CLASS_INIT_NULL \
ELM_WIDGET_SMART_CLASS_INIT(EVAS_SMART_CLASS_INIT_NULL)
/**
* @def ELM_WIDGET_SMART_CLASS_INIT_NAME_VERSION
*
* Initializer to zero out a whole #Elm_Widget_Smart_Class structure and
* set its name and version.
*
* This is similar to #ELM_WIDGET_SMART_CLASS_INIT_NULL, but it will
* also set the version field of #Elm_Widget_Smart_Class (base field)
* to the latest #ELM_WIDGET_SMART_CLASS_VERSION and name it to the
* specific value.
*
* It will keep a reference to the name field as a <c>"const char *"</c>,
* i.e., the name must be available while the structure is
* used (hint: static or global variable!) and must not be modified.
*
* @see ELM_WIDGET_SMART_CLASS_INIT_NULL
* @see ELM_WIDGET_SMART_CLASS_INIT
*
* @ingroup Widget
*/
#define ELM_WIDGET_SMART_CLASS_INIT_NAME_VERSION(name) \
ELM_WIDGET_SMART_CLASS_INIT(EVAS_SMART_CLASS_INIT_NAME_VERSION(name))
/**
* Base widget smart class. It has the 'virtual' functions for all
* general, common actions on Elementary widgets.
*/
typedef struct _Elm_Widget_Smart_Class
{
Evas_Smart_Class base; /**< Base smart class struct, needed for all smart objects */
int version; /**< Version of this smart class definition */
Eina_Bool (*on_focus)(Evas_Object *obj); /**< 'Virtual' function handling receipt of focus on the widget */
Eina_Bool (*disable)(Evas_Object *obj); /**< 'Virtual' function on the widget being disabled */
Eina_Bool (*theme)(Evas_Object *obj); /**< 'Virtual' function on the widget being re-themed */
Eina_Bool (*translate)(Evas_Object *obj); /**< 'Virtual' function handling language changes on Elementary */
Eina_Bool (*event)(Evas_Object *obj,
Evas_Object *source,
Evas_Callback_Type type,
void *event_info); /**< 'Virtual' function handling input events on the widget */
Eina_Bool (*focus_next)(const Evas_Object *obj,
Elm_Focus_Direction dir,
Evas_Object **next); /**< 'Virtual' function handling passing focus to sub-objects */
Eina_Bool (*sub_object_add)(Evas_Object *obj,
Evas_Object *sobj); /**< 'Virtual' function handling sub objects being added */
Eina_Bool (*sub_object_del)(Evas_Object *obj,
Evas_Object *sobj); /**< 'Virtual' function handling sub objects being removed */
} Elm_Widget_Smart_Class;
/**
* Base widget smart data. This is data bound to an Elementary object
* @b instance, so its particular to that specific object and not
* shared between all objects in its class. It is here, though, that
* we got a pointer to the object's class, the first field -- @c
* 'api'.
*/
typedef struct _Elm_Widget_Smart_Data
{
const Elm_Widget_Smart_Class *api; /**< This is the pointer to the object's class, from where we can reach/call its class functions */
Evas_Object *obj;
Evas_Object *parent_obj;
Evas_Object *parent2;
Evas_Coord x, y, w, h;
Eina_List *subobjs;
Evas_Object *resize_obj;
Evas_Object *hover_obj;
Eina_List *tooltips, *cursors;
Evas_Coord rx, ry, rw, rh;
int scroll_hold;
int scroll_freeze;
double scale;
Elm_Theme *theme;
const char *style;
const char *access_info;
unsigned int focus_order;
Eina_Bool focus_order_on_calc;
int child_drag_x_locked;
int child_drag_y_locked;
Eina_List *translate_strings;
Eina_List *focus_chain;
Eina_List *event_cb;
/* subject to later analysis: to be changed by something different */
void *on_show_region_data;
void (*on_show_region)(void *data,
Evas_Object *obj);
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 top_win_focused : 1;
Eina_Bool tree_unfocusable : 1;
Eina_Bool highlight_ignore : 1;
Eina_Bool highlight_in_theme : 1;
Eina_Bool disabled : 1;
Eina_Bool is_mirrored : 1;
Eina_Bool mirrored_auto_mode : 1; /* This is
* TRUE by
* default */
Eina_Bool still_in : 1;
} Elm_Widget_Smart_Data;
/**
* @}
*/
typedef struct _Elm_Tooltip Elm_Tooltip;
typedef struct _Elm_Cursor Elm_Cursor;
@ -617,8 +326,9 @@ EAPI void elm_widget_content_unset_hook_set(Evas_Object *obj, Elm_Wi
EAPI void elm_widget_on_focus_region_hook_set(Evas_Object *obj, void (*func)(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h));
EAPI void elm_widget_data_set(Evas_Object *obj, void *data);
EAPI void *elm_widget_data_get(const Evas_Object *obj);
EAPI Eina_Bool elm_widget_sub_object_add(Evas_Object *obj, Evas_Object *sobj);
EAPI Eina_Bool elm_widget_sub_object_del(Evas_Object *obj, Evas_Object *sobj);
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 const Eina_List *elm_widget_sub_object_list_get(const Evas_Object *obj);
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_signal_emit(Evas_Object *obj, const char *emission, const char *source);
@ -657,7 +367,6 @@ EAPI Evas_Object *elm_widget_parent_get(const Evas_Object *obj);
EAPI Evas_Object *elm_widget_parent2_get(const Evas_Object *obj);
EAPI void elm_widget_parent2_set(Evas_Object *obj, Evas_Object *parent);
EAPI void elm_widget_focus_steal(Evas_Object *obj);
EAPI const Elm_Widget_Smart_Class *elm_widget_smart_class_get(void);
/**
* @internal

View File

@ -1,143 +0,0 @@
#ifndef ELM_WIDGET_BUTTON_H
#define ELM_WIDGET_BUTTON_H
#include "elm_widget_layout.h"
/**
* @addtogroup Widget
* @{
*
* @section elm-button-class The Elementary Button Class
*
* Elementary, besides having the @ref Button widget, exposes its
* foundation -- the Elementary Button Class -- in order to create
* other widgets which are, basically, a button with some more logic
* on top.
*/
/**
* @def ELM_BUTTON_CLASS
*
* Use this macro to cast whichever subclass of
* #Elm_Button_Smart_Class into it, so to acess its fields.
*
* @ingroup Button
*/
#define ELM_BUTTON_CLASS(x) ((Elm_Button_Smart_Class *) x)
/**
* @def ELM_BUTTON_DATA
*
* Use this macro to cast whichever subdata of
* #Elm_Button_Smart_Data into it, so to acess its fields.
*
* @ingroup Button
*/
#define ELM_BUTTON_DATA(x) ((Elm_Button_Smart_Data *) x)
/**
* @def ELM_BUTTON_SMART_CLASS_VERSION
*
* Current version for Elementary button @b base smart class, a value
* which goes to _Elm_Button_Smart_Class::version.
*
* @ingroup Widget
*/
#define ELM_BUTTON_SMART_CLASS_VERSION 1
/**
* @def ELM_BUTTON_SMART_CLASS_INIT
*
* Initializer for a whole #Elm_Button_Smart_Class structure, with
* @c NULL values on its specific fields.
*
* @param smart_class_init initializer to use for the "base" field
* (#Evas_Smart_Class).
*
* @see EVAS_SMART_CLASS_INIT_NULL
* @see EVAS_SMART_CLASS_INIT_NAME_VERSION
* @see ELM_BUTTON_SMART_CLASS_INIT_NULL
* @see ELM_BUTTON_SMART_CLASS_INIT_NAME_VERSION
*
* @ingroup Widget
*/
#define ELM_BUTTON_SMART_CLASS_INIT(smart_class_init) \
{smart_class_init, ELM_BUTTON_SMART_CLASS_VERSION, EINA_TRUE}
/**
* @def ELM_BUTTON_SMART_CLASS_INIT_NULL
*
* Initializer to zero out a whole #Elm_Button_Smart_Class structure.
*
* @see ELM_BUTTON_SMART_CLASS_INIT_NAME_VERSION
* @see ELM_BUTTON_SMART_CLASS_INIT
*
* @ingroup Widget
*/
#define ELM_BUTTON_SMART_CLASS_INIT_NULL \
ELM_BUTTON_SMART_CLASS_INIT(EVAS_SMART_CLASS_INIT_NULL)
/**
* @def ELM_BUTTON_SMART_CLASS_INIT_NAME_VERSION
*
* Initializer to zero out a whole #Elm_Button_Smart_Class structure and
* set its name and version.
*
* This is similar to #ELM_BUTTON_SMART_CLASS_INIT_NULL, but it will
* also set the version field of #Elm_Button_Smart_Class (base field)
* to the latest #ELM_BUTTON_SMART_CLASS_VERSION and name it to the
* specific value.
*
* It will keep a reference to the name field as a <c>"const char *"</c>,
* i.e., the name must be available while the structure is
* used (hint: static or global variable!) and must not be modified.
*
* @see ELM_BUTTON_SMART_CLASS_INIT_NULL
* @see ELM_BUTTON_SMART_CLASS_INIT
*
* @ingroup Widget
*/
#define ELM_BUTTON_SMART_CLASS_INIT_NAME_VERSION(name) \
ELM_BUTTON_SMART_CLASS_INIT(ELM_LAYOUT_SMART_CLASS_INIT_NAME_VERSION(name))
/**
* Elementary button base smart class. This inherits directly from
* #Elm_Layout_Smart_Class and is meant to build widgets extending the
* behavior of a button.
*
* All of the functions listed on @ref Button namespace will work for
* objects deriving from #Elm_Button_Smart_Class.
*/
typedef struct _Elm_Button_Smart_Class
{
Elm_Layout_Smart_Class base; /**< Layout widget class struct, since we're inheriting from it */
int version; /**< Version of this smart class definition */
Eina_Bool admits_autorepeat : 1; /**< Whether the button objects of this class admit auto-repetition of click events, when one holds the click on them. This is true by default. */
} Elm_Button_Smart_Class;
/**
* Base widget smart data extended with button widget data.
*/
typedef struct _Elm_Button_Smart_Data
{
Elm_Layout_Smart_Data base; /**< Base widget smart data as first member obligatory, as we're inheriting from it */
/* auto-repeat stuff */
double ar_threshold; /**< Time to wait until first auto-repeated click is generated */
double ar_interval; /**< Time frame for subsequent auto-repeated clicks, after the first automatic one is triggerred */
Ecore_Timer *timer; /**< Internal timer object for auto-repeat behavior */
Eina_Bool autorepeat : 1; /**< Whether auto-repetition of clicks is enabled or not (bound to _Elm_Button_Smart_Class::admits_autorepeat) */
Eina_Bool repeating : 1; /**< Whether auto-repetition is going on */
} Elm_Button_Smart_Data;
/**
* @}
*/
EAPI const Elm_Button_Smart_Class *elm_button_smart_class_get(void);
#endif

View File

@ -1,134 +0,0 @@
#ifndef ELM_WIDGET_CONTAINER_H
#define ELM_WIDGET_CONTAINER_H
/**
* @addtogroup Widget
* @{
*
* @section elm-container-class The Elementary Container Class
*
* This class defines a common interface for objects acting like
* containers, i.e. objects parenting others and displaying their
* childs "inside" of them somehow.
*
* The container must define "parts" (or spots) into which child
* objects will be placed, inside of it. This is a way of handling
* more the one content object, by naming content locations
* properly. This is the role of the @c name argument of the virtual
* functions in the class.
*
* The following object functions are meant to be used with all
* container objects and derived ones:
*
* - elm_object_part_content_set()
* - elm_object_part_content_get()
* - elm_object_part_content_unset()
*/
/**
* @def ELM_CONTAINER_CLASS
*
* Use this macro to cast whichever subclass of
* #Elm_Container_Smart_Class into it, so to acess its fields.
*
* @ingroup Container
*/
#define ELM_CONTAINER_CLASS(x) ((Elm_Container_Smart_Class *) x)
/**
* @def ELM_CONTAINER_SMART_CLASS_VERSION
*
* Current version for Elementary container @b base smart class, a value
* which goes to _Elm_Container_Smart_Class::version.
*
* @ingroup Widget
*/
#define ELM_CONTAINER_SMART_CLASS_VERSION 1
/**
* @def ELM_CONTAINER_SMART_CLASS_INIT
*
* Initializer for a whole #Elm_Container_Smart_Class structure, with
* @c NULL values on its specific fields.
*
* @param smart_class_init initializer to use for the "base" field
* (#Evas_Smart_Class).
*
* @see EVAS_SMART_CLASS_INIT_NULL
* @see EVAS_SMART_CLASS_INIT_NAME_VERSION
* @see ELM_CONTAINER_SMART_CLASS_INIT_NULL
* @see ELM_CONTAINER_SMART_CLASS_INIT_NAME_VERSION
*
* @ingroup Widget
*/
#define ELM_CONTAINER_SMART_CLASS_INIT(smart_class_init) \
{smart_class_init, ELM_CONTAINER_SMART_CLASS_VERSION, NULL, NULL, NULL}
/**
* @def ELM_CONTAINER_SMART_CLASS_INIT_NULL
*
* Initializer to zero out a whole #Elm_Container_Smart_Class structure.
*
* @see ELM_CONTAINER_SMART_CLASS_INIT_NAME_VERSION
* @see ELM_CONTAINER_SMART_CLASS_INIT
*
* @ingroup Widget
*/
#define ELM_CONTAINER_SMART_CLASS_INIT_NULL \
ELM_CONTAINER_SMART_CLASS_INIT(EVAS_SMART_CLASS_INIT_NULL)
/**
* @def ELM_CONTAINER_SMART_CLASS_INIT_NAME_VERSION
*
* Initializer to zero out a whole #Elm_Container_Smart_Class structure and
* set its name and version.
*
* This is similar to #ELM_CONTAINER_SMART_CLASS_INIT_NULL, but it will
* also set the version field of #Elm_Container_Smart_Class (base field)
* to the latest #ELM_CONTAINER_SMART_CLASS_VERSION and name it to the
* specific value.
*
* It will keep a reference to the name field as a <c>"const char *"</c>,
* i.e., the name must be available while the structure is
* used (hint: static or global variable!) and must not be modified.
*
* @see ELM_CONTAINER_SMART_CLASS_INIT_NULL
* @see ELM_CONTAINER_SMART_CLASS_INIT
*
* @ingroup Widget
*/
#define ELM_CONTAINER_SMART_CLASS_INIT_NAME_VERSION(name) \
ELM_CONTAINER_SMART_CLASS_INIT(ELM_WIDGET_SMART_CLASS_INIT_NAME_VERSION(name))
/**
* Elementary container base smart class. This inherits directly from
* #Elm_Widget_Smart_Class and is meant to build widgets relying on an
* Edje container as a building block of its visuals.
*
* For instance, the elm_container @b widget itself is just a realization
* of this smart class (see the code for elm_container_add()). All of the
* functions listed on @ref Container namespace will work for objects
* deriving from #Elm_Container_Smart_Class.
*/
typedef struct _Elm_Container_Smart_Class
{
Elm_Widget_Smart_Class base; /**< Base Elementary widget class struct, since we're inheriting from it */
int version; /**< Version of this smart class definition */
Eina_Bool (*content_set)(Evas_Object *obj,
const char *part,
Evas_Object *content); /* 'Virtual' function on setting content on the object, at the given @a part part */
Evas_Object *(*content_get)(const Evas_Object * obj,
const char *part); /* 'Virtual' function on retrieving content from the object, at the given @a part part */
Evas_Object *(*content_unset)(Evas_Object * obj,
const char *part); /* 'Virtual' function on unsetting content from the object, at the given @a part part. Meant to return the content's pointer. */
} Elm_Container_Smart_Class;
/**
* @}
*/
EAPI const Elm_Container_Smart_Class *elm_container_smart_class_get(void);
#endif

View File

@ -1,257 +0,0 @@
#ifndef ELM_WIDGET_LAYOUT_H
#define ELM_WIDGET_LAYOUT_H
#include "elm_widget_container.h"
/**
* @addtogroup Widget
* @{
*
* @section elm-layout-class The Elementary Layout Class
*
* Elementary, besides having the @ref Layout widget, exposes its
* foundation -- the Elementary Layout Class -- in order to create
* other widgets which are, basically, a certain layout with some more
* logic on top.
*
* The idea is make the creation of that widgets as easy as possible,
* factorizing code on this common base. For example, a button is a
* layout (that looks like push button) that happens to react on
* clicks and keyboard events in a special manner, calling its user
* back on those events. That's no surprise, then, that the @ref
* Button implementation relies on #Elm_Layout_Smart_Class, if you go
* to check it.
*
* The Layout class inherits from
* #Elm_Container_Smart_Class. Container parts, here, map directly to
* Edje parts from the layout's Edje group. Besides that, there's a whole
* infrastructure around Edje files:
* - intefacing by signals,
* - setting/retrieving text part values,
* - dealing with table and box parts directly,
* - etc.
*
* Take a look at #Elm_Layout_Smart_Class's 'virtual' functions to
* understand the whole interface. Finally, layout objects will do
* <b>part aliasing</b> for you, if you set it up properly. For that,
* take a look at #Elm_Layout_Part_Alias_Description, where it's
* explained in detail.
*/
/**
* @def ELM_LAYOUT_CLASS
*
* Use this macro to cast whichever subclass of
* #Elm_Layout_Smart_Class into it, so to acess its fields.
*
* @ingroup Widget
*/
#define ELM_LAYOUT_CLASS(x) ((Elm_Layout_Smart_Class *) x)
/**
* @def ELM_LAYOUT_DATA
*
* Use this macro to cast whichever subdata of
* #Elm_Layout_Smart_Data into it, so to acess its fields.
*
* @ingroup Widget
*/
#define ELM_LAYOUT_DATA(x) ((Elm_Layout_Smart_Data *) x)
/**
* @def ELM_LAYOUT_SMART_CLASS_VERSION
*
* Current version for Elementary layout @b base smart class, a value
* which goes to _Elm_Layout_Smart_Class::version.
*
* @ingroup Widget
*/
#define ELM_LAYOUT_SMART_CLASS_VERSION 1
/**
* @def ELM_LAYOUT_SMART_CLASS_INIT
*
* Initializer for a whole #Elm_Layout_Smart_Class structure, with
* @c NULL values on its specific fields.
*
* @param smart_class_init initializer to use for the "base" field
* (#Evas_Smart_Class).
*
* @see EVAS_SMART_CLASS_INIT_NULL
* @see EVAS_SMART_CLASS_INIT_NAME_VERSION
* @see ELM_LAYOUT_SMART_CLASS_INIT_NULL
* @see ELM_LAYOUT_SMART_CLASS_INIT_NAME_VERSION
*
* @ingroup Widget
*/
#define ELM_LAYOUT_SMART_CLASS_INIT(smart_class_init) \
{smart_class_init, ELM_LAYOUT_SMART_CLASS_VERSION, NULL, NULL, NULL, NULL, \
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
NULL}
/**
* @def ELM_LAYOUT_SMART_CLASS_INIT_NULL
*
* Initializer to zero out a whole #Elm_Layout_Smart_Class structure.
*
* @see ELM_LAYOUT_SMART_CLASS_INIT_NAME_VERSION
* @see ELM_LAYOUT_SMART_CLASS_INIT
*
* @ingroup Widget
*/
#define ELM_LAYOUT_SMART_CLASS_INIT_NULL \
ELM_LAYOUT_SMART_CLASS_INIT(EVAS_SMART_CLASS_INIT_NULL)
/**
* @def ELM_LAYOUT_SMART_CLASS_INIT_NAME_VERSION
*
* Initializer to zero out a whole #Elm_Layout_Smart_Class structure and
* set its name and version.
*
* This is similar to #ELM_LAYOUT_SMART_CLASS_INIT_NULL, but it will
* also set the version field of #Elm_Layout_Smart_Class (base field)
* to the latest #ELM_LAYOUT_SMART_CLASS_VERSION and name it to the
* specific value.
*
* It will keep a reference to the name field as a <c>"const char *"</c>,
* i.e., the name must be available while the structure is
* used (hint: static or global variable!) and must not be modified.
*
* @see ELM_LAYOUT_SMART_CLASS_INIT_NULL
* @see ELM_LAYOUT_SMART_CLASS_INIT
*
* @ingroup Widget
*/
#define ELM_LAYOUT_SMART_CLASS_INIT_NAME_VERSION(name) \
ELM_LAYOUT_SMART_CLASS_INIT \
(ELM_CONTAINER_SMART_CLASS_INIT_NAME_VERSION(name))
/**
* @typedef Elm_Layout_Part_Alias_Description
*
* A layout part aliasing (proxying) description, used to get part
* names aliasing independently of a widgets theme.
*
* @ingroup Widget
*/
typedef struct _Elm_Layout_Part_Alias_Description Elm_Layout_Part_Alias_Description;
/**
* @struct _Elm_Layout_Part_Alias_Description
*
* Elementary Layout-based widgets may declare part proxies, i.e., aliases
* for real theme part names to expose to the API calls:
* - elm_layout_text_set()
* - elm_layout_text_get()
* - elm_layout_content_set()
* - elm_layout_content_get()
* - elm_layout_content_unset()
* and their equivalents. This list must be set on the
* @c "_smart_set_user()" function of inheriting widgets, so that part
* aliasing is handled automatically for them.
*
* @ingroup Widget
*/
struct _Elm_Layout_Part_Alias_Description
{
const char *alias; /**< Alternate name for a given (real) part. Calls receiving this string as a part name will be translated to the string at _Elm_Layout_Part_Proxies_Description::real_part */
const char *real_part; /**< Target part name for the alias set on @ref _Elm_Layout_Part_Proxies_Description::real_part. An example of usage would be @c "default" on that field, with @c "elm.content.swallow" on this one */
};
/**
* Elementary layout base smart class. This inherits directly from
* #Elm_Container_Smart_Class and is meant to build widgets relying on
* an Edje layout as a building block of its visuals.
*
* For instance, the elm_layout @b widget itself is just a realization
* of this smart class (see the code for elm_layout_add()). All of the
* functions listed on @ref Layout namespace will work for objects
* deriving from #Elm_Layout_Smart_Class.
*/
typedef struct _Elm_Layout_Smart_Class
{
Elm_Container_Smart_Class base; /**< Elementary container widget class struct, since we're inheriting from it */
int version; /**< Version of this smart class definition */
void (*sizing_eval)(Evas_Object *obj); /* 'Virtual' function on evalutating the object's final geometry, accounting for its sub-objects */
void (*signal)(Evas_Object *obj,
const char *emission,
const char *source); /* 'Virtual' function on emitting an (Edje) signal to the object, acting on its internal layout */
void (*callback_add)(Evas_Object *obj,
const char *emission,
const char *source,
Edje_Signal_Cb func,
void *data); /* 'Virtual' function on adding an (Edje) signal callback to the object, proxyed from its internal layout */
void * (*callback_del)(Evas_Object * obj,
const char *emission,
const char *source,
Edje_Signal_Cb func); /* 'Virtual' function on deleting an (Edje) signal callback on the object, proxyed from its internal layout */
Eina_Bool (*text_set)(Evas_Object *obj,
const char *part,
const char *text); /* 'Virtual' function on setting text on an (Edje) part of the object, from its internal layout */
const char *(*text_get)(const Evas_Object * obj,
const char *part); /* 'Virtual' function on fetching text from an (Edje) part of the object, on its internal layout */
Eina_Bool (*box_append)(Evas_Object *obj,
const char *part,
Evas_Object *child); /* 'Virtual' function on appending an object to an (Edje) box part of the object, from its internal layout */
Eina_Bool (*box_prepend)(Evas_Object *obj,
const char *part,
Evas_Object *child); /* 'Virtual' function on prepending an object to an (Edje) box part of the object, from its internal layout */
Eina_Bool (*box_insert_before)(Evas_Object *obj,
const char *part,
Evas_Object *child,
const Evas_Object *reference); /* 'Virtual' function on inserting an object to an (Edje) box part of the object, from its internal layout. The new child's position in the box is be prior to the one of a relative child already in the box */
Eina_Bool (*box_insert_at)(Evas_Object *obj,
const char *part,
Evas_Object *child,
unsigned int pos); /* 'Virtual' function on inserting an object to an (Edje) box part of the object, from its internal layout. The new child's position number is passed explicitly */
Evas_Object *(*box_remove)(Evas_Object * obj,
const char *part,
Evas_Object * child); /* 'Virtual' function on removing an object from an (Edje) box part of the object, on its internal layout */
Eina_Bool (*box_remove_all)(Evas_Object *obj,
const char *part,
Eina_Bool clear); /* 'Virtual' function on removing @b all objects from an (Edje) box part of the object, on its internal layout */
Eina_Bool (*table_pack)(Evas_Object *obj,
const char *part,
Evas_Object *child,
unsigned short col,
unsigned short row,
unsigned short colspan,
unsigned short rowspan); /* 'Virtual' function on inserting an object to an (Edje) table part of the object, from its internal layout */
Evas_Object *(*table_unpack)(Evas_Object * obj,
const char *part,
Evas_Object * child); /* 'Virtual' function on removing an object from an (Edje) table part of the object, on its internal layout */
Eina_Bool (*table_clear)(Evas_Object *obj,
const char *part,
Eina_Bool clear); /* 'Virtual' function on removing @b all objects from an (Edje) table part of the object, on its internal layout */
const Elm_Layout_Part_Alias_Description *content_aliases; /**< List of (@c 'SWALLOW') part aliases, <b>@c NULL terminated</b>. If @c NULL is passed as part name, it will be translated to the 1st _Elm_Layout_Part_Proxies_Description::real_part field in the list. */
const Elm_Layout_Part_Alias_Description *text_aliases; /**< List of (@c 'TEXT' or 'TEXTBLOCK') part aliases, <b>@c NULL terminated</b>. If @c NULL is passed as part name, it will be translated to the 1st _Elm_Layout_Part_Proxies_Description::real_part field in the list. */
} Elm_Layout_Smart_Class;
/**
* Base widget smart data extended with layout widget data.
*/
typedef struct _Elm_Layout_Smart_Data
{
Elm_Widget_Smart_Data base; /**< Base widget smart data as first member obligatory */
Eina_List *subs; /**< List of Elm_Layout_Sub_Object_Data structs, to hold the actual sub objects */
Eina_List *edje_signals;
Eina_List *parts_cursors;
const char *klass, *group;
Eina_Bool needs_size_calc : 1;
} Elm_Layout_Smart_Data;
/**
* @}
*/
EAPI const Elm_Layout_Smart_Class *elm_layout_smart_class_get(void);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1277,10 +1277,6 @@ EAPI Ecore_X_Window elm_win_xwindow_get(const Evas_Object *obj);
* possible, but it's sized vertically the most it needs to fit its\
* contents.
*
* This widget inherits from the @ref Layout one, so that all the
* functions acting on it also work for inner windown objects. It also
* emits the signals inherited from @ref Layout.
*
* Some examples of Inwin can be found in the following:
* @li @ref inwin_example_01
*