Elementary segment_control: Introduced new widget by Govindaraju and Prince.

Segment Control Widget is a horizontal control made of multiple segment items
together, each segment item is set to equal size, functioning similar to
discrete two state button. Only one segment item can be at selected state.


SVN revision: 58461
This commit is contained in:
Daniel Juyung Seo 2011-04-07 16:44:54 +00:00
parent 6983399bc9
commit 4204583f81
21 changed files with 1742 additions and 0 deletions

View File

@ -38,3 +38,5 @@ Tom Hacohen <tom@stosb.com>
Aharon Hillel <a.hillel@partner.samsung.com>
Jonathan Atton (Watchwolf) <jonathan.atton@gmail.com>
Shinwoo Kim <kimcinoo@gmail.com>
Govindaraju SM <govi.sm@samsung.com> <govism@gmail.com>
Prince Kumar Dubey <prince.dubey@samsung.com> <prince.dubey@gmail.com>

View File

@ -610,6 +610,139 @@ collections {
}
}
}
}
group { name: "segment_test";
parts{
part {
name: "bg";
type: RECT;
scale: 1; //allow scaling
description {
state: "default" 0.0;
visible: 0;
min: 480 400;
color: 0 0 0 0;
}
}
part { name: "top_padding";
type: RECT;
scale: 1; //allow scaling
description {
state: "default" 0.0;
visible: 0;
min : 250 30; //minimum size for gap filler
fixed: 0 1;
rel1 { relative: 0 0; }
rel2 { relative: 1 0; }
color: 0 0 0 0;
align: 0 0;
}
}
part { name: "segment1";
type: SWALLOW;
scale: 1;
description {
state: "default" 0.0;
fixed: 1 1;
rel1 { relative: 0.0 1.0; to_x: "bg"; to_y: "top_padding"; }
rel2 { relative: 1.0 0.25; to: "bg"; }
align: 0.5 0.0;
}
}
part { name: "segment1_bottom_padding";
type: RECT;
scale: 1;
description {
state: "default" 0.0;
visible: 0;
min : 250 10;
max : 250 10;
fixed: 1 1;
align: 0.5 0;
rel1 { relative: 0 1.0; to_y: "segment1"; }
rel2 { relative: 1 1.0; to_y: "segment1"; }
color: 0 255 0 0;
}
}
part { name: "segment2";
type: SWALLOW;
scale: 1;
description {
state: "default" 0.0;
fixed: 1 1;
rel1 { relative: 0.1 1.0; to_x: "bg"; to_y: "segment1_bottom_padding"; }
rel2 { relative: 0.9 160/400; to: "bg"; }
align: 0.5 0.0;
}
}
part { name: "segment2_bottom_padding";
type: RECT;
scale: 1;
description {
state: "default" 0.0;
visible: 0;
min : 250 10;
max : 250 10;
fixed: 1 1;
align: 0.5 0;
rel1 { relative: 0 1.0; to_y: "segment2"; }
rel2 { relative: 1 1.0; to_y: "segment2"; }
color: 0 255 0 0;
}
}
part { name: "segment3";
type: SWALLOW;
scale: 1;
description {
state: "default" 0.0;
fixed: 1 1;
rel1 { relative: 0.2 1.0; to_x: "bg"; to_y: "segment2_bottom_padding"; }
rel2 { relative: 0.8 0.6; to: "bg"; }
align: 0.5 0.0;
}
}
part { name: "segment3_bottom_padding";
type: RECT;
scale: 1;
description {
state: "default" 0.0;
visible: 0;
min : 250 10;
max : 250 10;
fixed: 1 1;
align: 0.5 0;
rel1 { relative: 0 1.0; to_y: "segment3"; }
rel2 { relative: 1 1.0; to_y: "segment3"; }
color: 0 255 0 0;
}
}
part { name: "segment4";
type: SWALLOW;
scale: 1;
description {
state: "default" 0.0;
fixed: 1 1;
rel1 { relative: 0.3 1.0; to_x: "bg"; to_y: "segment3_bottom_padding"; }
rel2 { relative: 0.7 340/400; to: "bg"; }
align: 0.5 0.0;
}
}
part { name: "btn1_bottom_padding";
type: RECT;
scale: 1;
description {
state: "default" 0.0;
visible: 0;
min : 250 100;
max : 250 100;
fixed: 1 1;
align: 0.5 0;
rel1 { relative: 0 1.0; to_y: "segment4"; }
rel2 { relative: 1 1.0; to_y: "segment4"; }
color: 0 255 0 0;
}
}
}
}
group { name: "bg_overlay";
images {

View File

@ -36048,6 +36048,637 @@ collections {
}
}
///////////////////////////////////////////////////////////////////////////////
group { name: "elm/segment_control/base/default";
#define SEGMENT_TYPE_SINGLE 1
#define SEGMENT_TYPE_LEFT 2
#define SEGMENT_TYPE_MIDDLE 3
#define SEGMENT_TYPE_RIGHT 4
#define SEGMENT_STATE_NORMAL 1
#define SEGMENT_STATE_PRESSED 2
#define SEGMENT_STATE_SELECTED 3
#define SEGMENT_STATUS_ENABLED 0
#define SEGMENT_STATUS_DISABLED 1
parts {
part { name: "bg";
type: RECT;
mouse_events: 0;
scale: 1;
description {
state: "default" 0.0;
color: 0 0 0 0;
min: 100 40;
}
}
}
}
group { name: "elm/segment_control/item/default";
data.item: "label.wrap.part" "label.bg";
styles {
style { name: "seg_text_style_normal";
base: "font=Sans font_size=16 style=shadow \
shadow_color=#2924224d \
align=center \
color=#ffffffff wrap=char text_class=label";
tag: "br" "\n";
tag: "hilight" "+ font=Sans:style=Bold";
tag: "tab" "\t";
}
style { name: "seg_text_style_selected";
base: "font=Sans:style=Bold font_size=16 style=shadow \
shadow_color=#aaaaaa4d \
align=center \
color=#111111ff wrap=char text_class=label";
tag: "br" "\n";
tag: "hilight" "+ font=Sans:style=Bold";
tag: "b" "+ font=Sans:style=Bold";
tag: "tab" "\t";
}
style { name: "seg_text_style_disabled";
base: "font=Sans:style=Medium font_size=16 style=shadow \
shadow_color=#2924224d \
align=center color=#2924224d \
wrap=char text_class=label";
tag: "br" "\n";
tag: "hilight" "+ font=Sans:style=Bold";
tag: "b" "+ font=Sans:style=Bold";
tag: "tab" "\t";
}
}
images {
image: "seg_single_pressed.png" COMP;
image: "seg_single_selected.png" COMP;
image: "seg_single_normal.png" COMP;
image: "seg_left_pressed.png" COMP;
image: "seg_left_selected.png" COMP;
image: "seg_left_normal.png" COMP;
image: "seg_middle_pressed.png" COMP;
image: "seg_middle_selected.png" COMP;
image: "seg_middle_normal.png" COMP;
image: "seg_right_pressed.png" COMP;
image: "seg_right_selected.png" COMP;
image: "seg_right_normal.png" COMP;
}
parts {
part { name: "segment";
mouse_events: 1;
scale: 1;
description { state: "default" 0.0;
min: 1 1;
visible: 0;
image {
normal: "seg_single_normal.png";
border: 7 7 7 7;
border_scale: 1;
middle: 1;
}
}
description { state: "default_single" 0.0;
inherit: "default" 0.0;
visible: 1;
image {
normal: "seg_single_normal.png";
border: 7 7 7 7;
}
}
description { state: "default_left" 0.0;
inherit: "default" 0.0;
visible: 1;
image {
normal: "seg_left_normal.png";
border: 6 1 7 7;
}
}
description { state: "default_right" 0.0;
inherit: "default" 0.0;
visible: 1;
image {
normal: "seg_right_normal.png";
border: 1 6 7 7;
}
}
description { state: "default_middle" 0.0;
inherit: "default" 0.0;
visible: 1;
image {
normal: "seg_middle_normal.png";
border: 2 2 2 2;
}
}
description { state: "pressed_single" 0.0;
inherit: "default" 0.0;
visible: 1;
image {
normal: "seg_single_pressed.png";
border: 7 7 7 7;
}
}
description { state: "pressed_left" 0.0;
inherit: "default" 0.0;
visible: 1;
image {
normal: "seg_left_pressed.png";
border: 6 1 7 7;
}
}
description { state: "pressed_right" 0.0;
inherit: "default" 0.0;
visible: 1;
image {
normal: "seg_right_pressed.png";
border: 1 6 7 7;
}
}
description { state: "pressed_middle" 0.0;
inherit: "default" 0.0;
visible: 1;
image {
normal: "seg_middle_pressed.png";
border: 1 1 2 2;
}
}
description { state: "selected_single" 0.0;
inherit: "default" 0.0;
visible: 1;
image {
normal: "seg_single_selected.png";
border: 7 7 7 7;
}
}
description { state: "selected_left" 0.0;
inherit: "default" 0.0;
visible: 1;
image {
normal: "seg_left_selected.png";
border: 6 3 7 7;
}
}
description { state: "selected_right" 0.0;
inherit: "default" 0.0;
visible: 1;
image {
normal: "seg_right_selected.png";
border: 3 6 7 7;
}
}
description { state: "selected_middle" 0.0;
inherit: "default" 0.0;
visible: 1;
image {
normal: "seg_middle_selected.png";
border: 3 3 3 3;
}
}
}
part { name: "padding_left";
type: RECT;
scale: 1;
mouse_events: 0;
description { state: "default" 0.0;
align: 0.0 0.0;
rel1.relative: 0.0 0.0;
rel2.relative: 0.0 1.0;
min: 2 2;
max: 2 2;
fixed: 1 0;
color: 0 0 0 0;
}
}
part { name: "padding_right";
type: RECT;
scale: 1;
mouse_events: 0;
description { state: "default" 0.0;
align: 1.0 0.0;
rel1.relative: 1.0 0.0;
rel2.relative: 1.0 1.0;
min: 2 2;
max: 2 2;
fixed: 1 0;
color: 0 0 0 0;
}
}
part { name: "padding_top";
type: RECT;
scale: 1;
mouse_events: 0;
description { state: "default" 0.0;
align: 0.0 0.0;
rel1.relative: 0.0 0.0;
rel2.relative: 1.0 0.0;
min: 2 2;
max: 2 2;
fixed: 0 1;
color: 0 0 0 0;
}
}
part { name: "padding_bottom";
type: RECT;
scale: 1;
mouse_events: 0;
description { state: "default" 0.0;
align: 1.0 1.0;
rel1.relative: 0.0 1.0;
rel2.relative: 1.0 1.0;
min: 2 2;
max: 2 2;
fixed: 0 1;
color: 0 0 0 0;
}
}
part { name: "icon.bg";
type: RECT;
scale: 1;
mouse_events: 0;
description { state: "default" 0.0;
visible: 1;
fixed: 1 0;
rel1 {
to_x: "padding_left";
to_y: "padding_top";
relative: 1.0 1.0;
}
rel2 {
to: "elm.swallow.icon";
relative: 1.0 1.0;
}
align: 0.0 0.5;
color: 0 0 0 0;
}
}
part { name: "padding_icon_text";
type: RECT;
scale: 1;
mouse_events: 0;
description { state: "default" 0.0; //when only icon or no icon is there
align: 0.0 0.0;
rel1 {
to: "icon.bg";
relative: 1.0 0.0;
}
rel2 {
to: "icon.bg";
relative: 1.0 1.0;
}
fixed: 1 0;
min: 0 0;
color: 0 0 0 0;
}
description { state: "icononly" 0.0;
inherit: "default" 0.0;
}
description { state: "visible" 0.0; //when icon is visible
inherit: "default" 0.0;
min: 2 0;
}
}
part { name: "elm.swallow.icon";
type: SWALLOW;
scale: 1;
description { state: "default" 0.0;
visible: 0;
align: 0.0 0.5;
rel1 {
to_x: "padding_left";
to_y: "padding_top";
relative: 1.0 1.0;
}
rel2 {
to_y: "padding_bottom";
relative: 0.0 0.0;
}
fixed: 1 0;
aspect: 1.0 1.0;
aspect_preference: BOTH;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
rel2 {
to_y: "padding_bottom";
relative: 0.3 0.0;
}
}
description { state: "icononly" 0.0;
inherit: "default" 0.0;
visible: 1;
rel2 {
to_x: "padding_right";
to_y: "padding_bottom";
relative: 0.0 0.0;
}
align: 0.5 0.5;
}
}
part { name: "elm.text";
type: TEXT;
mouse_events: 0;
scale: 1;
description {
state: "default" 0.0;
visible: 0;
fixed: 1 1;
min: 1 1;
rel1 {
to_x: "padding_icon_text";
relative: 1.0 1.0;
}
rel2 {
to_x: "padding_right";
relative: 0.0 0.0;
}
color: 224 224 224 255;
color3: 0 0 0 64;
text {
font: "Sans";
ellipsis: 0.0;
fit: 1 1;
size: 24;
size_range: 8 36;
min: 0 1;
}
}
description { state: "normal" 0.0;
inherit: "default" 0.0;
visible: 1;
}
description { state: "pressed" 0.0;
inherit: "default" 0.0;
visible: 1;
color: 0 0 0 255;
}
description { state: "selected" 0.0;
inherit: "default" 0.0;
visible: 1;
color: 50 50 50 255;
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
visible: 1;
color: 200 200 200 255;
}
}
part { name: "disabler";
repeat_events: 0;
scale: 1;
description { state: "default" 0.0;
visible: 0;
fixed: 1 1;
min: 1 1;
align: 0.0 0.5;
rel1 { relative: 0.0 0.0; to: "segment";}
rel2 { relative: 1.0 1.0; to: "segment";}
color: 255 255 255 150;
}
description { state: "disabled_single" 0.0;
inherit: "default" 0.0;
visible: 1;
image {
normal: "seg_single_normal.png";
border: 7 7 7 7;
}
}
description { state: "disabled_left" 0.0;
inherit: "default" 0.0;
visible: 1;
image {
normal: "seg_left_normal.png";
border: 6 1 7 7;
}
}
description { state: "disabled_right" 0.0;
inherit: "default" 0.0;
visible: 1;
image {
normal: "seg_right_normal.png";
border: 1 6 7 7;
}
}
description { state: "disabled_middle" 0.0;
inherit: "default" 0.0;
visible: 1;
image {
normal: "seg_middle_normal.png";
border: 2 2 2 2;
}
}
}
}
programs {
script {
public seg_type; // Single, Left, Middle, Right.
public seg_state; // Normal/Default, Pressed, Selected.
public seg_status;// Enabled/Default, Disabled
public update_state() {
new type, state, disabled;
type = get_int(seg_type);
state = get_int(seg_state);
disabled = get_int(seg_status);
if(state == SEGMENT_STATE_NORMAL)
{
if(type == SEGMENT_TYPE_SINGLE)
set_state(PART:"segment", "default_single", 0.0);
else if(type == SEGMENT_TYPE_LEFT)
set_state(PART:"segment", "default_left", 0.0);
else if(type == SEGMENT_TYPE_MIDDLE)
set_state(PART:"segment", "default_middle", 0.0);
else if(type == SEGMENT_TYPE_RIGHT)
set_state(PART:"segment", "default_right", 0.0);
set_state(PART:"elm.text", "normal", 0.0);
}
else if(state == SEGMENT_STATE_PRESSED)
{
if(type == SEGMENT_TYPE_SINGLE)
set_state(PART:"segment", "pressed_single", 0.0);
else if(type == SEGMENT_TYPE_LEFT)
set_state(PART:"segment", "pressed_left", 0.0);
else if(type == SEGMENT_TYPE_MIDDLE)
set_state(PART:"segment", "pressed_middle", 0.0);
else if(type == SEGMENT_TYPE_RIGHT)
set_state(PART:"segment", "pressed_right", 0.0);
set_state(PART:"elm.text", "pressed", 0.0);
}
else if(state == SEGMENT_STATE_SELECTED)
{
if(type == SEGMENT_TYPE_SINGLE)
set_state(PART:"segment", "selected_single", 0.0);
else if(type == SEGMENT_TYPE_LEFT)
set_state(PART:"segment", "selected_left", 0.0);
else if(type == SEGMENT_TYPE_MIDDLE)
set_state(PART:"segment", "selected_middle", 0.0);
else if(type == SEGMENT_TYPE_RIGHT)
set_state(PART:"segment", "selected_right", 0.0);
set_state(PART:"elm.text", "selected", 0.0);
}
if(disabled == SEGMENT_STATUS_DISABLED)
{
if(type == SEGMENT_TYPE_SINGLE)
set_state(PART:"disabler", "disabled_single", 0.0);
else if(type == SEGMENT_TYPE_LEFT)
set_state(PART:"disabler", "disabled_left", 0.0);
else if(type == SEGMENT_TYPE_MIDDLE)
set_state(PART:"disabler", "disabled_middle", 0.0);
else if(type == SEGMENT_TYPE_RIGHT)
set_state(PART:"disabler", "disabled_right", 0.0);
set_state(PART:"elm.text", "disabled", 0.0);
}
}
}
program {
name: "segment_type_s";
signal: "elm,type,segment,single";
source: "elm";
script {
set_int(seg_type, SEGMENT_TYPE_SINGLE);
update_state();
}
}
program {
name: "segment_type_l";
signal: "elm,type,segment,left";
source: "elm";
script {
set_int(seg_type, SEGMENT_TYPE_LEFT);
update_state();
}
}
program {
name: "segment_type_m";
signal: "elm,type,segment,middle";
source: "elm";
script {
set_int(seg_type, SEGMENT_TYPE_MIDDLE);
update_state();
}
}
program {
name: "segment_type_r";
signal: "elm,type,segment,right";
source: "elm";
script {
set_int(seg_type, SEGMENT_TYPE_RIGHT);
update_state();
}
}
program {
name: "normal_segment";
signal: "elm,state,segment,normal";
source: "elm";
script {
set_int(seg_state, SEGMENT_STATE_NORMAL);
update_state();
}
}
program {
name: "pressed_segment";
signal: "elm,state,segment,pressed";
source: "elm";
script {
set_int(seg_state, SEGMENT_STATE_PRESSED);
update_state();
}
}
program {
name: "selected_segment";
signal: "elm,state,segment,selected";
source: "elm";
script {
set_int(seg_state, SEGMENT_STATE_SELECTED);
update_state();
}
}
program { name: "disable_segment";
signal: "elm,state,disabled";
source: "elm";
script {
set_int(seg_status, SEGMENT_STATUS_DISABLED);
update_state();
}
}
program { name: "enable_segment";
signal: "elm,state,enabled";
source: "elm";
script {
set_int(seg_status, SEGMENT_STATUS_ENABLED);
update_state();
}
}
program { name: "text_show";
signal: "elm,state,text,visible";
source: "elm";
script {
new st[31];
new Float:vl;
get_state(PART:"elm.swallow.icon", st, 30, vl);
if (!strcmp(st, "icononly"))
{
set_state(PART:"elm.swallow.icon", "visible", 0.0);
set_state(PART:"padding_icon_text", "visible", 0.0);
}
get_state(PART:"elm.text", st, 30, vl);
if (!strcmp(st, "selected"))
set_state(PART:"elm.text", "selected", 0.0);
else
set_state(PART:"elm.text", "normal", 0.0);
}
}
program { name: "text_hide";
signal: "elm,state,text,hidden";
source: "elm";
script {
new st[31];
new Float:vl;
get_state(PART:"elm.swallow.icon", st, 30, vl);
if (!strcmp(st, "visible"))
{
set_state(PART:"elm.swallow.icon", "icononly", 0.0);
set_state(PART:"padding_icon_text", "icononly", 0.0);
}
set_state(PART:"elm.text", "default", 0.0);
}
}
program { name: "icon_show";
signal: "elm,state,icon,visible";
source: "elm";
script {
new st[31];
new Float:vl;
get_state(PART:"elm.text", st, 30, vl);
if ((!strcmp(st, "normal")) || (!strcmp(st, "selected")))
{
set_state(PART:"elm.swallow.icon", "visible", 0.0);
set_state(PART:"padding_icon_text", "visible", 0.0);
}
else
{
set_state(PART:"elm.swallow.icon", "icononly", 0.0);
set_state(PART:"padding_icon_text", "icononly", 0.0);
}
}
}
program { name: "icon_hide";
signal: "elm,state,icon,hidden";
source: "elm";
action: STATE_SET "default" 0.0;
target: "elm.swallow.icon";
}
}
#undef SEGMENT_TYPE_SINGLE
#undef SEGMENT_TYPE_LEFT
#undef SEGMENT_TYPE_MIDDLE
#undef SEGMENT_TYPE_RIGHT
#undef SEGMENT_STATE_NORMAL
#undef SEGMENT_STATE_PRESSED
#undef SEGMENT_STATE_SELECTED
#undef SEGMENT_STATUS_ENABLED
#undef SEGMENT_STATUS_DISABLED
}
/* a simple title layout, with a label and two icons */
group { name: "elm/layout/application/titlebar";
images {

Binary file not shown.

After

Width:  |  Height:  |  Size: 719 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 856 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 709 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 778 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -94,6 +94,7 @@ test_diskselector.c \
test_colorselector.c \
test_ctxpopup.c \
test_bubble.c \
test_segment_control.c \
test_store.c
elementary_test_LDADD = $(top_builddir)/src/lib/libelementary.la \

View File

@ -120,6 +120,7 @@ void test_diskselector(void *data, Evas_Object *obj, void *event_info);
void test_colorselector(void *data, Evas_Object *obj, void *event_info);
void test_ctxpopup(void *data, Evas_Object *obj, void *event_info);
void test_bubble(void *data, Evas_Object *obj, void *event_info);
void test_segment_control(void *data, Evas_Object *obj, void *event_info);
void test_store(void *data, Evas_Object *obj, void *event_info);
struct elm_test
@ -373,6 +374,7 @@ my_win_main(char *autorun)
ADD_TEST("Color Selector", test_colorselector);
ADD_TEST("Ctxpopup", test_ctxpopup);
ADD_TEST("Bubble", test_bubble);
ADD_TEST("Segment Control", test_segment_control);
ADD_TEST("Store", test_store);
#undef ADD_TEST

View File

@ -0,0 +1,105 @@
#include <Elementary.h>
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#ifndef ELM_LIB_QUICKLAUNCH
void
test_segment_control(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
Evas_Object *win, *bg, *ic, *ic1, *ic2, *ic3, *ic4, *ic5;
Elm_Segment_Item *it1, *it2, *it3, *it4, *it5;
Evas_Object * in_layout;
Evas_Object *segment1, *segment2, *segment3, *segment4;
char buf[PATH_MAX];
char buf1[PATH_MAX];
char buf2[PATH_MAX];
char buf3[PATH_MAX];
char buf4[PATH_MAX];
char buf5[PATH_MAX];
char buf6[PATH_MAX];
win = elm_win_add(NULL, "segmentcontrol", ELM_WIN_BASIC);
elm_win_title_set(win, "Segment Control");
elm_win_autodel_set(win, 1);
bg = elm_bg_add(win);
elm_win_resize_object_add(win, bg);
evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_show(bg);
in_layout = elm_layout_add( win );
elm_win_resize_object_add(win, in_layout);
snprintf(buf, sizeof(buf), "%s/objects/test.edj", PACKAGE_DATA_DIR);
elm_layout_file_set(in_layout, buf, "segment_test");
evas_object_size_hint_weight_set(in_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
ic = elm_icon_add(in_layout);
snprintf(buf1, sizeof(buf1), "%s/images/logo.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf1, NULL);
evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
ic1 = elm_icon_add(in_layout);
snprintf(buf2, sizeof(buf2), "%s/images/logo.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic1, buf2, NULL);
evas_object_size_hint_aspect_set(ic1, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
segment1 = elm_segment_control_add(win);
it1 = elm_segment_control_item_add(segment1, NULL, "Only Text");
it2 = elm_segment_control_item_add(segment1, ic, NULL);
elm_segment_control_item_selected_set(it2, EINA_TRUE);
it3 = elm_segment_control_item_add(segment1, ic1, "Text_Icon_test");
it4 = elm_segment_control_item_add(segment1, NULL, "Seg4");
it5 = elm_segment_control_item_add(segment1, NULL, "Seg5");
segment2 = elm_segment_control_add(win);
it1 = elm_segment_control_item_add(segment2, NULL, "SegmentItem");
it2 = elm_segment_control_item_add(segment2, NULL, "SegmentItem");
elm_segment_control_item_selected_set(it2, EINA_TRUE);
it3 = elm_segment_control_item_add(segment2, NULL, "SegmentControlItem");
it4 = elm_segment_control_item_add(segment2, NULL, "SegmentItem");
ic2 = elm_icon_add(in_layout);
snprintf(buf3, sizeof(buf3), "%s/images/logo.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic2, buf3, NULL);
evas_object_size_hint_aspect_set(ic2, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
ic3 = elm_icon_add(in_layout);
snprintf(buf4, sizeof(buf4), "%s/images/logo.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic3, buf4, NULL);
evas_object_size_hint_aspect_set(ic3, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
ic4 = elm_icon_add(in_layout);
snprintf(buf5, sizeof(buf5), "%s/images/logo.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic4, buf5, NULL);
evas_object_size_hint_aspect_set(ic4, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
segment3 = elm_segment_control_add(win);
it1 = elm_segment_control_item_add(segment3, ic2, NULL);
it2 = elm_segment_control_item_add(segment3, ic3, NULL);
elm_segment_control_item_selected_set(it2, EINA_TRUE);
it3 = elm_segment_control_item_add(segment3, ic4, NULL);
ic5 = elm_icon_add(in_layout);
snprintf(buf6, sizeof(buf6), "%s/images/logo.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic5, buf6, NULL);
evas_object_size_hint_aspect_set(ic5, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
segment4 = elm_segment_control_add(win);
it1 = elm_segment_control_item_add(segment4, NULL, "Disabled");
it2 = elm_segment_control_item_add(segment4, ic5, "Disabled");
elm_segment_control_item_selected_set(it2, EINA_TRUE);
it3 = elm_segment_control_item_add(segment4, NULL, "Disabled");
elm_object_disabled_set(segment4, EINA_TRUE);
elm_layout_content_set(in_layout, "segment1", segment1);
elm_layout_content_set(in_layout, "segment2", segment2);
elm_layout_content_set(in_layout, "segment3", segment3);
elm_layout_content_set(in_layout, "segment4", segment4);
evas_object_show(in_layout);
evas_object_show(win);
}
#endif

View File

@ -2780,6 +2780,24 @@ extern "C" {
EAPI const Elm_Store *elm_store_item_store_get(const Elm_Store_Item *sti) EINA_ARG_NONNULL(1);
EAPI const Elm_Genlist_Item *elm_store_item_genlist_item_get(const Elm_Store_Item *sti) EINA_ARG_NONNULL(1);
/* SegmentControl */
typedef struct _Elm_Segment_Item Elm_Segment_Item;
EAPI Evas_Object *elm_segment_control_add(Evas_Object *parent) EINA_ARG_NONNULL(1);
EAPI Elm_Segment_Item *elm_segment_control_item_add(Evas_Object *obj, Evas_Object *icon, const char *label) EINA_ARG_NONNULL(1);
EAPI Elm_Segment_Item *elm_segment_control_item_insert_at(Evas_Object *obj, Evas_Object *icon, const char *label, int index) EINA_ARG_NONNULL(1);
EAPI void elm_segment_control_item_del(Elm_Segment_Item *it) EINA_ARG_NONNULL(1);
EAPI void elm_segment_control_item_del_at(Evas_Object *obj, int index) EINA_ARG_NONNULL(1);
EAPI int elm_segment_control_item_count_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
EAPI Elm_Segment_Item *elm_segment_control_item_get(const Evas_Object *obj, int index) EINA_ARG_NONNULL(1);
EAPI const char *elm_segment_control_item_label_get(const Evas_Object *obj, int index) EINA_ARG_NONNULL(1);
EAPI void elm_segment_control_item_label_set(Elm_Segment_Item* it, const char* label) EINA_ARG_NONNULL(1);
EAPI Evas_Object *elm_segment_control_item_icon_get(const Evas_Object *obj, int index) EINA_ARG_NONNULL(1);
EAPI void elm_segment_control_item_icon_set(Elm_Segment_Item *it, Evas_Object *icon) EINA_ARG_NONNULL(1);
EAPI int elm_segment_control_item_index_get(const Elm_Segment_Item *it) EINA_ARG_NONNULL(1);
EAPI Evas_Object *elm_segment_control_item_object_get(const Elm_Segment_Item *it) EINA_ARG_NONNULL(1);
EAPI Elm_Segment_Item *elm_segment_control_item_selected_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
EAPI void elm_segment_control_item_selected_set(Elm_Segment_Item *it, Eina_Bool select) EINA_ARG_NONNULL(1);
#ifdef __cplusplus
}
#endif

View File

@ -94,6 +94,7 @@ elm_calendar.c \
elm_flipselector.c \
elm_diskselector.c \
elm_colorselector.c \
elm_segment_control.c \
\
elc_anchorblock.c \
elc_anchorview.c \

View File

@ -0,0 +1,849 @@
#include <Elementary.h>
#include "elm_priv.h"
/**
* @defgroup SegmentControl SegmentControl
*
* SegmentControl Widget is a horizontal control made of multiple segment items,
* each segment item functioning similar to discrete two state button. A segment
* control groups the the items together and provides compact single button with
* multiple equal size segments. Segment item size is determined by base widget
* size and the number of items added.
* 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.
*
* Signals that you can add callbacks for are:
*
* "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 index.
*/
typedef struct _Widget_Data Widget_Data;
struct _Widget_Data
{
Evas_Object *obj;
Evas_Object *base;
Eina_List *seg_items;
int item_count;
Elm_Segment_Item *selected_item;
int item_width;
};
struct _Elm_Segment_Item
{
Elm_Widget_Item base;
Evas_Object *icon;
const char *label;
int seg_index;
};
static const char *widtype = NULL;
static void _sizing_eval(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 _item_free(Elm_Segment_Item *it);
static void _segment_off(Elm_Segment_Item *it);
static void _segment_on(Elm_Segment_Item *it);
static void _position_items(Widget_Data *wd);
static void _on_move_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj
__UNUSED__, void *event_info __UNUSED__);
static void _mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj
__UNUSED__, void *event_info __UNUSED__);
static void _mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj
__UNUSED__, void *event_info __UNUSED__);
static void _swallow_item_objects(Elm_Segment_Item *it);
static void _update_list(Widget_Data *wd);
static Elm_Segment_Item * _item_find(const Evas_Object *obj, int index);
static Elm_Segment_Item* _item_new(Evas_Object *obj, Evas_Object *icon,
const char *label);
static void
_sizing_eval(Evas_Object *obj)
{
Widget_Data *wd;
Evas_Coord minw = -1, minh = -1;
Evas_Coord w, h;
wd = elm_widget_data_get(obj);
if (!wd) return;
elm_coords_finger_size_adjust(wd->item_count, &minw, 1, &minh);
edje_object_size_min_restricted_calc(wd->base, &minw, &minh, minw, minh);
elm_coords_finger_size_adjust(wd->item_count, &minw, 1, &minh);
evas_object_size_hint_min_get(obj, &w, &h);
if (w > minw) minw = w;
if (h > minh) minh = h;
evas_object_size_hint_min_set(obj, minw, minh);
}
static void
_del_hook(Evas_Object *obj)
{
Elm_Segment_Item *it;
Widget_Data *wd;
wd = elm_widget_data_get(obj);
if (!wd) return;
EINA_LIST_FREE(wd->seg_items, it) _item_free(it);
free(wd);
}
static void
_theme_hook(Evas_Object *obj)
{
Eina_List *l;
Eina_Bool rtl;
Elm_Segment_Item *it;
Widget_Data *wd;
wd = elm_widget_data_get(obj);
if (!wd) return;
_elm_widget_mirrored_reload(obj);
rtl = elm_widget_mirrored_get(obj);
edje_object_mirrored_set(wd->base, rtl);
_elm_theme_object_set(obj, wd->base, "segment_control", "base",
elm_widget_style_get(obj));
edje_object_scale_set(wd->base, elm_widget_scale_get(wd->base)
*_elm_config->scale);
EINA_LIST_FOREACH(wd->seg_items, l, it)
{
_elm_theme_object_set(obj, it->base.view, "segment_control",
"item", elm_widget_style_get(obj));
edje_object_scale_set(it->base.view, elm_widget_scale_get(it->base.view)
*_elm_config->scale);
edje_object_mirrored_set(it->base.view, rtl);
}
_update_list(wd);
}
static void
_disable_hook(Evas_Object *obj)
{
Widget_Data *wd;
wd = elm_widget_data_get(obj);
if (!wd) return;
_update_list(wd);
}
// TODO: Elm_widget elm_widget_focus_list_next_get supports only Elm_widget list,
// Not the Elm_Widget_item. Focus switching with in widget not supported until
// it is supported in elm_widget
#if 0
static void *
_elm_list_data_get(const Eina_List *list)
{
Elm_Segment_Item *it = eina_list_data_get(list);
if (it) return NULL;
edje_object_signal_emit(it->base.view, "elm,state,segment,selected", "elm");
return it->base.view;
}
static Eina_Bool
_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir,
Evas_Object **next)
{
static int count=0;
Widget_Data *;
const Eina_List *items;
void *(*list_data_get) (const Eina_List *list);
wd = elm_widget_data_get(obj);
if ((!wd)) return EINA_FALSE;
/* Focus chain */
/* TODO: Change this to use other chain */
if ((items = elm_widget_focus_custom_chain_get(obj)))
list_data_get = eina_list_data_get;
else
{
items = wd->seg_items;
list_data_get = _elm_list_data_get;
if (!items) return EINA_FALSE;
}
return elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next);
}
#endif
static void
_item_free(Elm_Segment_Item *it)
{
Widget_Data *wd;
if (!it) return;
wd = elm_widget_item_data_get(it);
if (!wd) return;
if (wd->selected_item == it) wd->selected_item = NULL;
if (wd->seg_items) wd->seg_items = eina_list_remove(wd->seg_items, it);
elm_widget_item_pre_notify_del(it);
if (it->icon) evas_object_del(it->icon);
if (it->label) eina_stringshare_del(it->label);
elm_widget_item_del(it);
}
static void
_segment_off(Elm_Segment_Item *it)
{
Widget_Data *wd;
if (!it) return;
wd = elm_widget_item_data_get(it);
if (!wd) return;
edje_object_signal_emit(it->base.view, "elm,state,segment,normal", "elm");
if (wd->selected_item == it) wd->selected_item = NULL;
}
static void
_segment_on(Elm_Segment_Item *it)
{
Widget_Data *wd;
if (!it) return;
wd = elm_widget_item_data_get(it);
if (!wd) return;
if (it == wd->selected_item) return;
if (wd->selected_item) _segment_off(wd->selected_item);
edje_object_signal_emit(it->base.view, "elm,state,segment,selected", "elm");
wd->selected_item = it;
evas_object_smart_callback_call(wd->obj, "changed", (void*) it->seg_index);
}
static void
_position_items(Widget_Data *wd)
{
Eina_List *l;
Elm_Segment_Item *it;
Eina_Bool rtl;
int bx, by, bw, bh, pos;
wd->item_count = eina_list_count(wd->seg_items);
if (wd->item_count <= 0) return;
evas_object_geometry_get(wd->base, &bx, &by, &bw, &bh);
wd->item_width = bw / wd->item_count;
rtl = elm_widget_mirrored_get(wd->obj);
if (rtl)
pos = bx + bw - wd->item_width;
else
pos = bx;
EINA_LIST_FOREACH(wd->seg_items, l, it)
{
evas_object_move(it->base.view, pos, by);
evas_object_resize(it->base.view, wd->item_width, bh);
if (rtl)
pos -= wd->item_width;
else
pos += wd->item_width;
}
_sizing_eval(wd->obj);
}
static void
_on_move_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
{
Widget_Data *wd;
wd = elm_widget_data_get(data);
if (!wd) return;
_position_items(wd);
}
static void
_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
void *event_info)
{
Widget_Data *wd;
Elm_Segment_Item *it;
Evas_Event_Mouse_Up *ev;
Evas_Coord x, y, w, h;
it = data;
if (!it) return;
wd = elm_widget_item_data_get(it);
if (!wd) return;
if (elm_widget_disabled_get(wd->obj)) return;
if (it == wd->selected_item) return;
ev = event_info;
evas_object_geometry_get(it->base.view, &x, &y, &w, &h);
if ((ev->output.x >= x) && (ev->output.x <= (x + w)) && (ev->output.y >= y)
&& (ev->output.y <= (y + h)))
_segment_on(it);
else
edje_object_signal_emit(it->base.view, "elm,state,segment,normal", "elm");
}
static void
_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
{
Widget_Data *wd;
Elm_Segment_Item *it;
it = data;
if (!it) return;
wd = elm_widget_item_data_get(it);
if (!wd) return;
if (elm_widget_disabled_get(wd->obj)) return;
if (it == wd->selected_item) return;
edje_object_signal_emit(it->base.view, "elm,state,segment,pressed", "elm");
}
static void
_swallow_item_objects(Elm_Segment_Item *it)
{
if (!it) return;
if (it->icon)
{
edje_object_part_swallow(it->base.view, "elm.swallow.icon", it->icon);
edje_object_signal_emit(it->base.view, "elm,state,icon,visible", "elm");
}
else
edje_object_signal_emit(it->base.view, "elm,state,icon,hidden", "elm");
if (it->label)
edje_object_signal_emit(it->base.view, "elm,state,text,visible", "elm");
else
edje_object_signal_emit(it->base.view, "elm,state,text,hidden", "elm");
edje_object_message_signal_process(it->base.view);
}
static void
_update_list(Widget_Data *wd)
{
Eina_List *l;
Elm_Segment_Item *it;
Eina_Bool rtl;
int index = 0;
_position_items(wd);
if (wd->item_count == 1)
{
it = eina_list_nth(wd->seg_items, 0);
it->seg_index = 0;
//Set the segment type
edje_object_signal_emit(it->base.view,
"elm,type,segment,single", "elm");
//Set the segment state
if (wd->selected_item == it)
edje_object_signal_emit(it->base.view,
"elm,state,segment,selected", "elm");
else
edje_object_signal_emit(it->base.view,
"elm,state,segment,normal", "elm");
if (elm_widget_disabled_get(wd->obj))
edje_object_signal_emit(it->base.view, "elm,state,disabled", "elm");
_swallow_item_objects(it);
return;
}
rtl = elm_widget_mirrored_get(wd->obj);
EINA_LIST_FOREACH(wd->seg_items, l, it)
{
it->seg_index = index;
//Set the segment type
if (index == 0)
{
if (rtl)
edje_object_signal_emit(it->base.view,
"elm,type,segment,right", "elm");
else
edje_object_signal_emit(it->base.view,
"elm,type,segment,left", "elm");
}
else if (index == (wd->item_count - 1))
{
if (rtl)
edje_object_signal_emit(it->base.view,
"elm,type,segment,left", "elm");
else
edje_object_signal_emit(it->base.view,
"elm,type,segment,right", "elm");
}
else
edje_object_signal_emit(it->base.view,
"elm,type,segment,middle", "elm");
//Set the segment state
if (wd->selected_item == it)
edje_object_signal_emit(it->base.view,
"elm,state,segment,selected", "elm");
else
edje_object_signal_emit(it->base.view,
"elm,state,segment,normal", "elm");
if (elm_widget_disabled_get(wd->obj))
edje_object_signal_emit(it->base.view, "elm,state,disabled", "elm");
_swallow_item_objects(it);
index++;
}
}
static Elm_Segment_Item *
_item_find(const Evas_Object *obj, int index)
{
Widget_Data *wd;
Elm_Segment_Item *it;
wd = elm_widget_data_get(obj);
if (!wd) return NULL;
it = eina_list_nth(wd->seg_items, index);
return it;
}
static Elm_Segment_Item*
_item_new(Evas_Object *obj, Evas_Object *icon, const char *label)
{
Elm_Segment_Item *it;
Widget_Data *wd;
wd = elm_widget_data_get(obj);
if (!wd) return NULL;
it = elm_widget_item_new(obj, Elm_Segment_Item);
if (!it) return NULL;
elm_widget_item_data_set(it, wd);
it->base.view = edje_object_add(evas_object_evas_get(obj));
edje_object_scale_set(it->base.view, elm_widget_scale_get(it->base.view)
*_elm_config->scale);
evas_object_smart_member_add(it->base.view, obj);
elm_widget_sub_object_add(obj, it->base.view);
_elm_theme_object_set(obj, it->base.view, "segment_control", "item",
elm_object_style_get(obj));
edje_object_mirrored_set(it->base.view,
elm_widget_mirrored_get(it->base.widget));
if (label)
eina_stringshare_replace(&it->label, label);
if (it->label)
edje_object_signal_emit(it->base.view, "elm,state,text,visible", "elm");
else
edje_object_signal_emit(it->base.view, "elm,state,text,hidden", "elm");
edje_object_message_signal_process(it->base.view);
edje_object_part_text_set(it->base.view, "elm.text", label);
it->icon = icon;
if (it->icon) elm_widget_sub_object_add(it->base.view, it->icon);
evas_object_event_callback_add(it->base.view, EVAS_CALLBACK_MOUSE_DOWN,
_mouse_down, it);
evas_object_event_callback_add(it->base.view, EVAS_CALLBACK_MOUSE_UP,
_mouse_up, it);
evas_object_show(it->base.view);
return it;
}
/**
* Create new SegmentControl.
* @param [in] parent The parent object
* @return The new object or NULL if it cannot be created
*
* @ingroup SegmentControl
*/
EAPI Evas_Object *
elm_segment_control_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, "segment_control");
elm_widget_type_set(obj, "segment_control");
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);
// TODO: Focus switch support to Elm_widget_Item not supported yet.
#if 0
elm_widget_focus_next_hook_set(obj, _focus_next_hook);
#endif
wd->obj = obj;
wd->base = edje_object_add(e);
edje_object_scale_set(wd->base, elm_widget_scale_get(wd->base)
*_elm_config->scale);
_elm_theme_object_set(obj, wd->base, "segment_control", "base", "default");
elm_widget_resize_object_set(obj, wd->base);
evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
_on_move_resize, obj);
evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
_on_move_resize, obj);
return obj;
}