efl_ui_spin: Add new spin and spin_button widgets

Summary:
https://phab.enlightenment.org/T5900

Creating base class(efl_ui_spin) to support various shape of spinner.

Added button interaction widget efl_ui_spin_button inherited from efl_ui_spin.

Test Plan: Add tests in elementary_test.

Reviewers: Jaehyun_Cho, woohyun, jpeg, singh.amitesh

Subscribers: jenkins, id213sin, cedric, jpeg

Differential Revision: https://phab.enlightenment.org/D5424
This commit is contained in:
Woochan Lee 2017-11-20 19:12:49 +09:00 committed by Jaehyun Cho
parent 31ce5250cb
commit eefcb49419
31 changed files with 1886 additions and 234 deletions

View File

@ -146,6 +146,8 @@ elementary/themes/edc/elm/separator.edc \
elementary/themes/edc/elm/slider.edc \
elementary/themes/edc/elm/slideshow.edc \
elementary/themes/edc/elm/spinner.edc \
elementary/themes/edc/elm/spin.edc \
elementary/themes/edc/elm/spin_button.edc \
elementary/themes/edc/elm/textpath.edc \
elementary/themes/edc/elm/thumb.edc \
elementary/themes/edc/elm/toolbar.edc \

View File

@ -67,6 +67,8 @@ collections {
#include "edc/elm/border.edc"
// XXX: min size calc problems - too wide! ... err ok on my 32bit box... eh?
#include "edc/elm/spinner.edc"
#include "edc/elm/spin.edc"
#include "edc/elm/spin_button.edc"
#include "edc/elm/menu.edc"
#include "edc/elm/clock.edc"
#include "edc/elm/gengrid.edc"

View File

@ -1472,6 +1472,7 @@ group { name: "elm/button/base/hoversel_horizontal_entry/default";
/******************* SPINNER BUTTONS STYLES **********************/
group { name: "elm/button/base/spinner/increase/default";
alias: "elm/button/base/spinner/increase/colorselector/default";
alias: "elm/button/base/spin_button/increase/default";
alias: "elm/button/base/calendar/increase/default";
alias: "elm/button/base/calendar/increase/double_spinners";
images.image: "sym_right_light_normal.png" COMP;
@ -1626,6 +1627,7 @@ group { name: "elm/button/base/hoversel_horizontal_entry/default";
group { name: "elm/button/base/spinner/decrease/default";
alias: "elm/button/base/spinner/decrease/colorselector/default";
inherit: "elm/button/base/spinner/increase/default";
alias: "elm/button/base/spin_button/decrease/default";
alias: "elm/button/base/calendar/decrease/default";
alias: "elm/button/base/calendar/decrease/double_spinners";
images.image: "sym_left_light_normal.png" COMP;
@ -1654,6 +1656,8 @@ group { name: "elm/button/base/hoversel_horizontal_entry/default";
group { name: "elm/button/base/spinner/default";
alias: "elm/button/base/spinner/colorselector/default";
alias: "elm/button/base/spinner/vertical";
alias: "elm/button/base/spin_button/default";
alias: "elm/button/base/spin_button/vertical";
parts {
part { name: "bg";
type: SPACER;
@ -1730,6 +1734,7 @@ group { name: "elm/button/base/hoversel_horizontal_entry/default";
}
group { name: "elm/button/base/spinner/increase/vertical";
inherit: "elm/button/base/spinner/increase/default";
alias: "elm/button/base/spin_button/increase/vertical";
images.image: "sym_up_light_normal.png" COMP;
images.image: "sym_up_glow_normal.png" COMP;
images.image: "sym_up_dark_normal.png" COMP;
@ -1755,6 +1760,7 @@ group { name: "elm/button/base/hoversel_horizontal_entry/default";
group { name: "elm/button/base/spinner/decrease/vertical";
inherit: "elm/button/base/spinner/decrease/default";
alias: "elm/button/base/spin_button/decrease/vertical";
images.image: "sym_down_light_normal.png" COMP;
images.image: "sym_down_glow_normal.png" COMP;
images.image: "sym_down_dark_normal.png" COMP;

View File

@ -854,6 +854,8 @@ group { name: "elm/entry/base-single/default";
group { name: "elm/entry/base-single/spinner/default";
alias: "elm/entry/base-single/spinner/vertical";
alias: "elm/entry/base-single/spin_button/default";
alias: "elm/entry/base-single/spin_button/vertical";
inherit: "elm/entry/base-single/default";
styles {
style { name: "entry_single_spinner_style";

View File

@ -0,0 +1,27 @@
group { name: "elm/spin/base/default";
parts {
part { name: "bg";
type: RECT;
scale: 1;
description { state: "default" 0.0;
color: 0 0 0 0;
}
}
part { name: "elm.text";
type: TEXT;
mouse_events: 0;
scale: 1;
description { state: "default" 0.0;
color: FN_COL_DEFAULT;
text {
font: FNBD;
size: 10;
min: 1 1;
ellipsis: -1;
align: 0.5 0.5;
}
rel.to: "bg";
}
}
}
}

View File

@ -0,0 +1,218 @@
group { name: "elm/spin_button/base/default";
images.image: "vert_bar_inset.png" COMP;
parts {
part { name: "clip"; type: RECT;
description { state: "default" 0.0;
rel1.to: "elm.swallow.text_button";
rel2.to: "elm.swallow.text_button";
}
}
part { name: "bg";
type: RECT;
scale: 1;
description { state: "default" 0.0;
color_class: "spinner_bg";
}
}
part { name: "inset"; mouse_events: 0;
description { state: "default" 0.0;
rel1.offset: 0 1;
rel2.offset: -1 -2;
image.normal: "vert_bar_inset.png";
image.border: 1 1 8 6;
image.middle: 0;
fill.smooth: 0;
}
}
part { name: "access";
type: RECT;
repeat_events: 1;
description { state: "default" 0.0;
fixed: 1 1;
color: 0 0 0 0;
rel1.to: "inset";
rel2.to: "inset";
visible: 0;
}
description { state: "active" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
part { name: "elm.swallow.entry";
type: SWALLOW;
clip_to: "clip";
description { state: "default" 0.0;
fixed: 1 1;
rel1.to: "elm.swallow.text_button";
rel2.to: "elm.swallow.text_button";
visible: 0;
}
description { state: "active" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
part { name: "elm.swallow.dec_button";
type: SWALLOW;
scale: 1;
description { state: "default" 0.0;
fixed: 1 0;
rel1.to: "inset";
rel1.offset: 1 1;
rel2.to: "inset";
rel2.offset: 1 -2;
rel2.relative: 0.0 1.0;
align: 0.0 0.5;
min: 15 15;
aspect: 1.0 1.0; aspect_preference: VERTICAL;
}
}
part { name: "elm.swallow.inc_button";
type: SWALLOW;
scale: 1;
description { state: "default" 0.0;
fixed: 1 0;
rel1.to: "inset";
rel1.offset: 1 1;
rel1.relative: 1.0 0.0;
rel2.to: "inset";
rel2.offset: 1 -2;
align: 1.0 0.5;
min: 15 15;
aspect: 1.0 1.0; aspect_preference: VERTICAL;
}
}
part { name: "elm.swallow.text_button";
type: SWALLOW;
scale: 1;
description { state: "default" 0.0;
visible: 1;
rel1.to_y: "inset";
rel1.to_x: "elm.swallow.dec_button";
rel1.relative: 1.0 0.0;
rel1.offset: 1 1;
rel2.to_y: "inset";
rel2.to_x: "elm.swallow.inc_button";
rel2.relative: 0.0 1.0;
rel2.offset: -2 -2;
}
description { state: "inactive" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
part { name: "disabler";
type: RECT;
repeat_events: 0;
mouse_events: 0;
description { state: "default" 0.0;
color: 0 0 0 0;
visible: 0;
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
}
programs {
program { name: "entry_active";
signal: "elm,state,entry,active";
source: "elm";
action: STATE_SET "active" 0.0;
target: "elm.swallow.entry";
}
program { name: "entry_inactive";
signal: "elm,state,entry,inactive";
source: "elm";
action: STATE_SET "default" 0.0;
target: "elm.swallow.entry";
}
program { name: "text_button_active";
signal: "elm,state,button,active";
source: "elm";
action: STATE_SET "default" 0.0;
target: "elm.swallow.text_button";
}
program { name: "text_button_inactive";
signal: "elm,state,button,inactive";
source: "elm";
action: STATE_SET "inactive" 0.0;
target: "elm.swallow.text_button";
}
program { name: "access_activate";
signal: "elm,state,access,active";
source: "elm";
action: STATE_SET "active" 0.0;
target: "access";
}
program { name: "access_inactivate";
signal: "elm,state,access,inactive";
source: "elm";
action: STATE_SET "default" 0.0;
target: "access";
}
program { name: "disable";
signal: "elm,state,disabled";
source: "elm";
action: STATE_SET "disabled" 0.0;
target: "disabler";
}
program { name: "enable";
signal: "elm,state,enabled";
source: "elm";
action: STATE_SET "default" 0.0;
target: "disabler";
}
}
}
group { name: "elm/spin_button/base/vertical";
inherit: "elm/spin_button/base/default";
parts {
part { name: "elm.swallow.inc_button";
type: SWALLOW;
scale: 1;
description { state: "default" 0.0;
rel1.to: "inset";
rel1.offset: 1 1;
rel1.relative: 1.0 0.0;
rel2.to: "inset";
rel2.offset: 1 -2;
align: 1.0 0.5;
}
}
part { name: "elm.swallow.text_button";
type: SWALLOW;
scale: 1;
description { state: "default" 0.0;
visible: 1;
rel1.to_y: "inset";
rel1.to_x: "elm.swallow.dec_button";
rel1.relative: 1.0 0.0;
rel1.offset: 1 1;
rel2.to_y: "inset";
rel2.to_x: "elm.swallow.inc_button";
rel2.relative: 0.0 1.0;
rel2.offset: -2 -2;
}
description { state: "active" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
part { name: "elm.swallow.dec_button";
type: SWALLOW;
scale: 1;
description { state: "default" 0.0;
rel1.to: "inset";
rel1.offset: 1 1;
rel2.to: "inset";
rel2.offset: 1 -2;
rel2.relative: 0.0 1.0;
align: 0.0 0.5;
}
}
}
}

View File

@ -57,7 +57,6 @@ efl_eolian_files = \
lib/efl/interfaces/efl_ui_base.eo \
lib/efl/interfaces/efl_ui_direction.eo \
lib/efl/interfaces/efl_ui_drag.eo \
lib/efl/interfaces/efl_ui_spin.eo \
lib/efl/interfaces/efl_ui_range.eo \
lib/efl/interfaces/efl_ui_view.eo \
lib/efl/interfaces/efl_ui_model_connect.eo \

View File

@ -20,6 +20,8 @@ elm_public_eolian_files = \
lib/elementary/efl_ui_radio.eo \
lib/elementary/efl_ui_slider.eo \
lib/elementary/efl_ui_slider_interval.eo \
lib/elementary/efl_ui_spin.eo \
lib/elementary/efl_ui_spin_button.eo \
lib/elementary/efl_ui_video.eo \
lib/elementary/efl_ui_win.eo \
lib/elementary/efl_ui_win_inlined.eo \
@ -311,6 +313,8 @@ includesunstable_HEADERS = \
lib/elementary/efl_ui_slider_private.h \
lib/elementary/elm_widget_slideshow.h \
lib/elementary/elm_widget_spinner.h \
lib/elementary/efl_ui_spin_private.h \
lib/elementary/efl_ui_spin_button_private.h \
lib/elementary/elm_widget_table.h \
lib/elementary/elm_widget_thumb.h \
lib/elementary/elm_widget_toolbar.h \
@ -656,6 +660,8 @@ lib_elementary_libelementary_la_SOURCES = \
lib/elementary/elm_separator.c \
lib/elementary/efl_ui_slider.c \
lib/elementary/efl_ui_slider_interval.c \
lib/elementary/efl_ui_spin.c \
lib/elementary/efl_ui_spin_button.c \
lib/elementary/elm_slideshow.c \
lib/elementary/elm_spinner.c \
lib/elementary/elm_store.c \
@ -877,6 +883,8 @@ bin/elementary/test_segment_control.c \
bin/elementary/test_separator.c \
bin/elementary/test_slider.c \
bin/elementary/test_ui_slider_interval.c \
bin/elementary/test_ui_spin.c \
bin/elementary/test_ui_spin_button.c \
bin/elementary/test_slideshow.c \
bin/elementary/test_spinner.c \
bin/elementary/test_store.c \

View File

@ -128,6 +128,8 @@ test_slider.c \
test_ui_slider_interval.c \
test_slideshow.c \
test_spinner.c \
test_ui_spinner.c \
test_ui_buttonspin.c \
test_store.c \
test_sys_notify.c \
test_systray.c \

View File

@ -176,6 +176,8 @@ void test_scroller3(void *data, Evas_Object *obj, void *event_info);
void test_scroller4(void *data, Evas_Object *obj, void *event_info);
void test_scroller5(void *data, Evas_Object *obj, void *event_info);
void test_spinner(void *data, Evas_Object *obj, void *event_info);
void test_ui_spin(void *data, Evas_Object *obj, void *event_info);
void test_ui_spin_button(void *data, Evas_Object *obj, void *event_info);
void test_index(void *data, Evas_Object *obj, void *event_info);
void test_index2(void *data, Evas_Object *obj, void *event_info);
void test_index3(void *data, Evas_Object *obj, void *event_info);
@ -1016,6 +1018,8 @@ add_tests:
//------------------------------//
ADD_TEST(NULL, "Range Values", "Spinner", test_spinner);
ADD_TEST(NULL, "Range Values", "Ui.Spin", test_ui_spin);
ADD_TEST(NULL, "Range Values", "Ui.Spin.Button", test_ui_spin_button);
ADD_TEST(NULL, "Range Values", "Slider", test_slider);
ADD_TEST(NULL, "Range Values", "Progressbar", test_progressbar);
ADD_TEST(NULL, "Range Values", "Progressbar 2", test_progressbar2);

View File

@ -186,10 +186,10 @@ test_flipselector(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *ev
fpd = elm_flipselector_add(bx);
evas_object_size_hint_weight_set(fpd, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
efl_ui_spin_step_set(fpd, 1.5);
efl_ui_spin_min_max_set(fpd, 2.3, 10.1);
efl_ui_spin_value_set(fpd, 5.3);
printf("Current value is %f\n", efl_ui_spin_value_get(fpd));
efl_ui_range_step_set(fpd, 1.5);
efl_ui_range_min_max_set(fpd, 2.3, 10.1);
efl_ui_range_value_set(fpd, 5.3);
printf("Current value is %f\n", efl_ui_range_value_get(fpd));
elm_box_pack_end(bx, fpd);
evas_object_show(fpd);

View File

@ -0,0 +1,71 @@
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#include <Elementary.h>
static void
_spin_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev)
{
printf("Value changed %d\n", (int)efl_ui_range_value_get(ev->object));
}
static void
_spin_min_reached_cb(void *data EINA_UNUSED, const Efl_Event *ev)
{
printf("Min reached %d\n", (int)efl_ui_range_value_get(ev->object));
}
static void
_spin_max_reached_cb(void *data EINA_UNUSED, const Efl_Event *ev)
{
printf("Max reached %d\n", (int)efl_ui_range_value_get(ev->object));
}
static void
_inc_clicked(void *data, const Efl_Event *ev EINA_UNUSED)
{
int val = (int)efl_ui_range_value_get(data);
efl_ui_range_value_set(data, ++val);
}
static void
_dec_clicked(void *data, const Efl_Event *ev EINA_UNUSED)
{
int val = (int)efl_ui_range_value_get(data);
efl_ui_range_value_set(data, --val);
}
void
test_ui_spin(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Eo *win, *bx, *sp;
win = efl_add(EFL_UI_WIN_CLASS, NULL,
efl_ui_win_type_set(efl_added, EFL_UI_WIN_BASIC),
efl_text_set(efl_added, "Efl.Ui.Spin"),
efl_ui_win_autodel_set(efl_added, EINA_TRUE));
bx = efl_add(EFL_UI_BOX_CLASS, win,
efl_content_set(win, efl_added),
efl_ui_direction_set(efl_added, EFL_UI_DIR_DOWN));
sp = efl_add(EFL_UI_SPIN_CLASS, bx,
efl_ui_range_min_max_set(efl_added, 0, 10),
efl_ui_range_value_set(efl_added, 6),
efl_ui_range_step_set(efl_added, 2),
efl_ui_format_string_set(efl_added, "test %d"),
efl_event_callback_add(efl_added, EFL_UI_SPIN_EVENT_CHANGED,_spin_changed_cb, NULL),
efl_event_callback_add(efl_added, EFL_UI_SPIN_EVENT_MIN_REACHED,_spin_min_reached_cb, NULL),
efl_event_callback_add(efl_added, EFL_UI_SPIN_EVENT_MAX_REACHED,_spin_max_reached_cb, NULL),
efl_pack(bx, efl_added));
efl_add(EFL_UI_BUTTON_CLASS, bx,
efl_text_set(efl_added, "Increse Spinner value"),
efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _inc_clicked, sp),
efl_pack(bx, efl_added));
efl_add(EFL_UI_BUTTON_CLASS, bx,
efl_text_set(efl_added, "Decrease Spinner value"),
efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _dec_clicked, sp),
efl_pack(bx, efl_added));
efl_gfx_size_set(win, EINA_SIZE2D(100, 80));
}

View File

@ -0,0 +1,43 @@
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#include <Elementary.h>
static void
_spin_delay_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev)
{
printf("Value delay changed %d\n", (int)efl_ui_range_value_get(ev->object));
}
void
test_ui_spin_button(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Eo *win, *bx;
win = efl_add(EFL_UI_WIN_CLASS, NULL,
efl_ui_win_type_set(efl_added, EFL_UI_WIN_BASIC),
efl_text_set(efl_added, "Efl.Ui.Spin_Button"),
efl_ui_win_autodel_set(efl_added, EINA_TRUE));
bx = efl_add(EFL_UI_BOX_CLASS, win,
efl_content_set(win, efl_added),
efl_ui_direction_set(efl_added, EFL_UI_DIR_DOWN));
efl_add(EFL_UI_SPIN_BUTTON_CLASS, bx,
efl_ui_range_min_max_set(efl_added, 0, 10),
efl_ui_range_value_set(efl_added, 6),
efl_ui_range_step_set(efl_added, 2),
efl_ui_spin_button_loop_set(efl_added, EINA_TRUE),
efl_ui_spin_button_editable_set(efl_added, EINA_TRUE),
efl_event_callback_add(efl_added, EFL_UI_SPIN_BUTTON_EVENT_DELAY_CHANGED,_spin_delay_changed_cb, NULL),
efl_pack(bx, efl_added));
efl_add(EFL_UI_SPIN_BUTTON_CLASS, bx,
efl_ui_range_min_max_set(efl_added, -100.0, 100.0),
efl_ui_range_value_set(efl_added, 0),
efl_ui_format_string_set(efl_added, "test float %0.2f"),
efl_ui_spin_button_editable_set(efl_added, EINA_FALSE),
efl_pack(bx, efl_added));
efl_gfx_size_set(win, EINA_SIZE2D(180, 100));
}

View File

@ -54,7 +54,6 @@ set(PUBLIC_EO_FILES
interfaces/efl_ui_item.eo
interfaces/efl_ui_menu.eo
interfaces/efl_ui_range.eo
interfaces/efl_ui_spin.eo
interfaces/efl_ui_autorepeat.eo
interfaces/efl_vpath.eo
interfaces/efl_vpath_core.eo

View File

@ -90,7 +90,6 @@ typedef Efl_Gfx_Path_Command_Type Efl_Gfx_Path_Command;
#include "interfaces/efl_ui_base.eo.h"
#include "interfaces/efl_ui_direction.eo.h"
#include "interfaces/efl_ui_drag.eo.h"
#include "interfaces/efl_ui_spin.eo.h"
#include "interfaces/efl_ui_range.eo.h"
#include "interfaces/efl_ui_item.eo.h"
#include "interfaces/efl_ui_menu.eo.h"

View File

@ -58,7 +58,6 @@
#include "interfaces/efl_ui_base.eo.c"
#include "interfaces/efl_ui_direction.eo.c"
#include "interfaces/efl_ui_drag.eo.c"
#include "interfaces/efl_ui_spin.eo.c"
#include "interfaces/efl_ui_range.eo.c"
#include "interfaces/efl_ui_menu.eo.c"
#include "interfaces/efl_ui_autorepeat.eo.c"

View File

@ -28,7 +28,7 @@ interface Efl.Ui.Range
If it is bigger then $max, will be updated to $max. Actual value
can be get with @Efl.Ui.Range.range_value.get
By default, min is equal to 0.0, and max is equal to 1.0.
The minimum and maximum values may be different for each class.
Warning: maximum must be greater than minimum, otherwise behavior
is undefined.
@ -46,5 +46,21 @@ interface Efl.Ui.Range
max: double; [[The maximum value.]]
}
}
@property range_step {
[[Control the step used to increment or decrement values for given widget.
This value will be incremented or decremented to the displayed value.
By default step value is equal to 1.
Warning: The step value should be bigger than 0.]]
set {
}
get {
}
values {
step: double; [[The step value.]]
}
}
}
}

View File

@ -1,84 +0,0 @@
interface Efl.Ui.Spin()
{
[[Efl UI spinner interface]]
methods {
@property min_max {
[[Control the minimum and maximum values for the spinner.
Define the allowed range of values to be selected by the user.
If actual value is less than $min, it will be updated to $min. If it
is bigger then $max, will be updated to $max.
By default, min is equal to 0, and max is equal to 100.
Warning: Maximum must be greater than minimum.]]
set {
}
get {
}
values {
min: double; [[The minimum value.]]
max: double; [[The maximum value.]]
}
}
@property step {
[[Control the step used to increment or decrement the spinner value.
This value will be incremented or decremented to the displayed value.
It will be incremented while the user keep right or top arrow pressed,
and will be decremented while the user keep left or bottom arrow pressed.
The interval to increment / decrement can be set with @.interval.set.
By default step value is equal to 1.]]
set {
}
get {
}
values {
step: double; [[The step value.]]
}
}
@property value {
[[Control the value the spinner displays.
Value will be presented on the label following format specified with
elm_spinner_format_set().
Warning The value must to be between min and max values. This values
are set by elm_spinner_min_max_set().]]
set {
}
get {
}
values {
val: double; [[The value to be displayed.]]
}
}
@property interval {
[[Control the interval on time updates for an user mouse button hold on spinner widgets' arrows.
This interval value is decreased while the user holds the
mouse pointer either incrementing or decrementing spinner's value.
This helps the user to get to a given value distant from the
current one easier/faster, as it will start to change quicker and
quicker on mouse button holds.
The calculation for the next change interval value, starting from
the one set with this call, is the previous interval divided by
$1.05, so it decreases a little bit.
The default starting interval value for automatic changes is
$0.85 seconds.]]
set {
}
get {
}
values {
interval: double; [[The (first) interval value in seconds.]]
}
}
}
}

View File

@ -304,6 +304,8 @@ EAPI extern Elm_Version *elm_version;
# include <efl_ui_text_editable.eo.h>
# include <efl_ui_text_async.eo.h>
# include <efl_ui_clock.eo.h>
# include <efl_ui_spin.eo.h>
# include <efl_ui_spin_button.eo.h>
# include <efl_ui_image_factory.eo.h>
#endif

View File

@ -0,0 +1,311 @@
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#define EFL_ACCESS_PROTECTED
#define EFL_ACCESS_VALUE_PROTECTED
#define EFL_ACCESS_WIDGET_ACTION_PROTECTED
#include <Elementary.h>
#include "elm_priv.h"
#include "efl_ui_spin_private.h"
#define MY_CLASS EFL_UI_SPIN_CLASS
#define MY_CLASS_NAME "Efl.Ui.Spin"
static Eina_Bool
_is_valid_digit(char x)
{
return ((x >= '0' && x <= '9') || (x == '.')) ? EINA_TRUE : EINA_FALSE;
}
static Efl_Ui_Spin_Format_Type
_is_label_format_integer(const char *fmt)
{
const char *itr = NULL;
const char *start = NULL;
Eina_Bool found = EINA_FALSE;
Efl_Ui_Spin_Format_Type ret_type = SPIN_FORMAT_INVALID;
start = strchr(fmt, '%');
if (!start) return SPIN_FORMAT_INVALID;
while (start)
{
if (found && start[1] != '%')
{
return SPIN_FORMAT_INVALID;
}
if (start[1] != '%' && !found)
{
found = EINA_TRUE;
for (itr = start + 1; *itr != '\0'; itr++)
{
if ((*itr == 'd') || (*itr == 'u') || (*itr == 'i') ||
(*itr == 'o') || (*itr == 'x') || (*itr == 'X'))
{
ret_type = SPIN_FORMAT_INT;
break;
}
else if ((*itr == 'f') || (*itr == 'F'))
{
ret_type = SPIN_FORMAT_FLOAT;
break;
}
else if (_is_valid_digit(*itr))
{
continue;
}
else
{
return SPIN_FORMAT_INVALID;
}
}
}
start = strchr(start + 2, '%');
}
return ret_type;
}
static void
_label_write(Evas_Object *obj)
{
Efl_Ui_Spin_Data *sd = efl_data_scope_get(obj, MY_CLASS);
if (sd->format_cb)
{
const char *buf;
Eina_Value val;
if (sd->format_type == SPIN_FORMAT_INT)
{
eina_value_setup(&val, EINA_VALUE_TYPE_INT);
eina_value_set(&val, (int)sd->val);
}
else
{
eina_value_setup(&val, EINA_VALUE_TYPE_DOUBLE);
eina_value_set(&val, sd->val);
}
eina_strbuf_reset(sd->format_strbuf);
sd->format_cb(sd->format_cb_data, sd->format_strbuf, val);
buf = eina_strbuf_string_get(sd->format_strbuf);
eina_value_flush(&val);
elm_layout_text_set(obj, "elm.text", buf);
sd->templates = buf;
}
else
{
char buf[1024];
snprintf(buf, sizeof(buf), "%.0f", sd->val);
elm_layout_text_set(obj, "elm.text", buf);
}
}
static int
_decimal_points_get(const char *label)
{
char result[16] = "0";
const char *start = strchr(label, '%');
while (start)
{
if (start[1] != '%')
{
start = strchr(start, '.');
if (start)
start++;
break;
}
else
start = strchr(start + 2, '%');
}
if (start)
{
const char *p = strchr(start, 'f');
if ((p) && ((p - start) < 15))
sscanf(start, "%[^f]", result);
}
return atoi(result);
}
EOLIAN static void
_efl_ui_spin_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Spin_Data *_pd EINA_UNUSED)
{
Evas_Coord minw = -1, minh = -1;
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
edje_object_size_min_restricted_calc
(wd->resize_obj, &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);
}
EOLIAN static Efl_Ui_Theme_Apply
_efl_ui_spin_elm_widget_theme_apply(Eo *obj, Efl_Ui_Spin_Data *sd EINA_UNUSED)
{
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EFL_UI_THEME_APPLY_FAILED);
if (!elm_layout_theme_set(obj, "spin", "base", elm_widget_style_get(obj)))
CRI("Failed to set layout!");
elm_layout_sizing_eval(obj);
return EFL_UI_THEME_APPLY_SUCCESS;
}
EOLIAN static Eo *
_efl_ui_spin_efl_object_constructor(Eo *obj, Efl_Ui_Spin_Data *sd)
{
obj = efl_constructor(efl_super(obj, MY_CLASS));
elm_widget_sub_object_parent_add(obj);
sd->val_max = 100.0;
sd->step = 1.0;
if (!elm_layout_theme_set(obj, "spin", "base",
elm_widget_style_get(obj)))
CRI("Failed to set layout!");
_label_write(obj);
elm_widget_can_focus_set(obj, EINA_TRUE);
elm_layout_sizing_eval(obj);
return obj;
}
EOLIAN static Eo *
_efl_ui_spin_efl_object_finalize(Eo *obj, Efl_Ui_Spin_Data *sd EINA_UNUSED)
{
obj = efl_finalize(efl_super(obj, MY_CLASS));
return obj;
}
EOLIAN static void
_efl_ui_spin_efl_object_destructor(Eo *obj, Efl_Ui_Spin_Data *sd EINA_UNUSED)
{
efl_ui_format_cb_set(obj, NULL, NULL, NULL);
efl_destructor(efl_super(obj, MY_CLASS));
}
EOLIAN static void
_efl_ui_spin_efl_ui_format_format_cb_set(Eo *obj, Efl_Ui_Spin_Data *sd, void *func_data, Efl_Ui_Format_Func_Cb func, Eina_Free_Cb func_free_cb)
{
if (sd->format_cb_data == func_data && sd->format_cb == func)
return;
if (sd->format_cb_data && sd->format_free_cb)
sd->format_free_cb(sd->format_cb_data);
sd->format_cb = func;
sd->format_cb_data = func_data;
sd->format_free_cb = func_free_cb;
if (!sd->format_strbuf) sd->format_strbuf = eina_strbuf_new();
const char *format = efl_ui_format_string_get(obj);
if (format)
{
sd->format_type = _is_label_format_integer(format);
if (sd->format_type == SPIN_FORMAT_INVALID)
{
ERR("format:\"%s\" is invalid, cannot be set", format);
return;
}
else if (sd->format_type == SPIN_FORMAT_FLOAT)
sd->decimal_points = _decimal_points_get(format);
}
_label_write(obj);
elm_layout_sizing_eval(obj);
}
EOLIAN static void
_efl_ui_spin_efl_ui_range_range_min_max_set(Eo *obj, Efl_Ui_Spin_Data *sd, double min, double max)
{
if (max < min)
{
ERR("Wrong params. min(%lf) is bigger than max(%lf). It will swaped.", min, max);
double t = min;
min = max;
max = t;
}
if ((EINA_DBL_EQ(sd->val_min, min)) && (EINA_DBL_EQ(sd->val_max, max))) return;
sd->val_min = min;
sd->val_max = max;
if (sd->val < sd->val_min) sd->val = sd->val_min;
if (sd->val > sd->val_max) sd->val = sd->val_max;
_label_write(obj);
}
EOLIAN static void
_efl_ui_spin_efl_ui_range_range_min_max_get(Eo *obj EINA_UNUSED, Efl_Ui_Spin_Data *sd, double *min, double *max)
{
if (min) *min = sd->val_min;
if (max) *max = sd->val_max;
}
EOLIAN static void
_efl_ui_spin_efl_ui_range_range_step_set(Eo *obj EINA_UNUSED, Efl_Ui_Spin_Data *sd, double step)
{
if (step <= 0)
{
ERR("Wrong param. The step(%lf) should be bigger than 0.0", step);
return;
}
sd->step = step;
}
EOLIAN static double
_efl_ui_spin_efl_ui_range_range_step_get(Eo *obj EINA_UNUSED, Efl_Ui_Spin_Data *sd)
{
return sd->step;
}
EOLIAN static void
_efl_ui_spin_efl_ui_range_range_value_set(Eo *obj, Efl_Ui_Spin_Data *sd, double val)
{
if (val < sd->val_min)
val = sd->val_min;
else if (val > sd->val_max)
val = sd->val_max;
if (EINA_DBL_EQ(val, sd->val)) return;
sd->val = val;
if (EINA_DBL_EQ(sd->val, sd->val_min))
efl_event_callback_call(obj, EFL_UI_SPIN_EVENT_MIN_REACHED, NULL);
else if (EINA_DBL_EQ(sd->val, sd->val_max))
efl_event_callback_call(obj, EFL_UI_SPIN_EVENT_MAX_REACHED, NULL);
efl_event_callback_call(obj, EFL_UI_SPIN_EVENT_CHANGED, NULL);
_label_write(obj);
}
EOLIAN static double
_efl_ui_spin_efl_ui_range_range_value_get(Eo *obj EINA_UNUSED, Efl_Ui_Spin_Data *sd)
{
return sd->val;
}
#define EFL_UI_SPIN_EXTRA_OPS \
ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_spin), \
#include "efl_ui_spin.eo.c"

View File

@ -0,0 +1,26 @@
class Efl.Ui.Spin (Efl.Ui.Layout, Efl.Ui.Range, Efl.Ui.Format,
Efl.Access.Value, Efl.Access.Widget.Action)
{
[[A Spin.
This is a widget which allows the user to increase or decrease numeric values
using user interactions. It's base type of widget to picking a value and showing value.
@since 1.21
]]
implements {
Efl.Object.constructor;
Efl.Object.finalize;
Efl.Object.destructor;
Elm.Widget.theme_apply;
Efl.Ui.Range.range_min_max { get; set; }
Efl.Ui.Range.range_step { get; set; }
Efl.Ui.Range.range_value { get; set; }
Efl.Ui.Format.format_cb { set; }
}
events {
changed; [[Called when spin changed]]
min,reached; [[Called when spin value reached min]]
max,reached; [[Called when spin value reached max]]
}
}

View File

@ -0,0 +1,922 @@
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#define EFL_ACCESS_PROTECTED
#define EFL_ACCESS_VALUE_PROTECTED
#define EFL_ACCESS_WIDGET_ACTION_PROTECTED
#define EFL_UI_FOCUS_COMPOSITION_PROTECTED
#include <Elementary.h>
#include "elm_priv.h"
#include "efl_ui_spin_button_private.h"
#include "efl_ui_spin_private.h"
#include "elm_entry.eo.h"
#define MY_CLASS EFL_UI_SPIN_BUTTON_CLASS
#define MY_CLASS_NAME "Efl.Ui.Spin_Button"
#define EFL_UI_SPIN_BUTTON_DELAY_CHANGE_TIME 0.2
static void
_inc_dec_button_clicked_cb(void *data, const Efl_Event *event);
static void
_inc_dec_button_pressed_cb(void *data, const Efl_Event *event);
static void
_inc_dec_button_unpressed_cb(void *data, const Efl_Event *event);
static void
_inc_dec_button_mouse_move_cb(void *data, const Efl_Event *event);
static void
_entry_activated_cb(void *data, const Efl_Event *event);
static void
_entry_focus_changed_cb(void *data, const Efl_Event *event);
static void
_access_increment_decrement_info_say(Evas_Object *obj, Eina_Bool is_incremented);
EFL_CALLBACKS_ARRAY_DEFINE(_inc_dec_button_cb,
{ EFL_UI_EVENT_CLICKED, _inc_dec_button_clicked_cb},
{ EFL_UI_EVENT_PRESSED, _inc_dec_button_pressed_cb},
{ EFL_UI_EVENT_UNPRESSED, _inc_dec_button_unpressed_cb},
{ EFL_EVENT_POINTER_MOVE, _inc_dec_button_mouse_move_cb }
);
static void
_entry_show(Evas_Object *obj)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
char buf[32], fmt[32] = "%0.f";
/* try to construct just the format from given label
* completely ignoring pre/post words
*/
if (pd->templates)
{
const char *start = strchr(pd->templates, '%');
while (start)
{
/* handle %% */
if (start[1] != '%')
break;
else
start = strchr(start + 2, '%');
}
if (start)
{
const char *itr, *end = NULL;
for (itr = start + 1; *itr != '\0'; itr++)
{
if ((*itr == 'd') || (*itr == 'u') || (*itr == 'i') || (*itr == 'o') ||
(*itr == 'x') || (*itr == 'X') || (*itr == 'f') || (*itr == 'F'))
{
end = itr + 1;
break;
}
}
if ((end) && ((size_t)(end - start + 1) < sizeof(fmt)))
{
memcpy(fmt, start, end - start);
fmt[end - start] = '\0';
}
}
}
if (pd->format_type == SPIN_FORMAT_INT)
snprintf(buf, sizeof(buf), fmt, (int)pd->val);
else
snprintf(buf, sizeof(buf), fmt, pd->val);
elm_object_text_set(sd->ent, buf);
}
static void
_label_write(Evas_Object *obj)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
if (pd->templates)
elm_layout_text_set(sd->text_button, "elm.text", pd->templates);
else
{
char buf[1024];
snprintf(buf, sizeof(buf), "%.0f", pd->val);
elm_layout_text_set(sd->text_button, "elm.text", buf);
}
}
static Eina_Bool
_delay_change_timer_cb(void *data)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
sd->delay_change_timer = NULL;
efl_event_callback_call(data, EFL_UI_SPIN_BUTTON_EVENT_DELAY_CHANGED, NULL);
return ECORE_CALLBACK_CANCEL;
}
static Eina_Bool
_value_set(Evas_Object *obj,
double new_val)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
if (sd->loop)
{
if (new_val < pd->val_min)
new_val = pd->val_max;
else if (new_val > pd->val_max)
new_val = pd->val_min;
}
efl_ui_range_value_set(obj, new_val);
ecore_timer_del(sd->delay_change_timer);
sd->delay_change_timer = ecore_timer_add(EFL_UI_SPIN_BUTTON_DELAY_CHANGE_TIME,
_delay_change_timer_cb, obj);
return EINA_TRUE;
}
static void
_entry_hide(Evas_Object *obj)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
elm_layout_signal_emit(obj, "elm,state,button,active", "elm");
evas_object_show(sd->text_button);
elm_layout_signal_emit(obj, "elm,state,entry,inactive", "elm");
evas_object_hide(sd->ent);
if (sd->entry_visible && !evas_focus_state_get(evas_object_evas_get(obj)))
sd->entry_reactivate = EINA_TRUE;
sd->entry_visible = EINA_FALSE;
}
static void
_entry_value_apply(Evas_Object *obj)
{
const char *str;
double val;
char *end;
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
if (!sd->entry_visible) return;
efl_event_callback_del(sd->ent, EFL_UI_FOCUS_OBJECT_EVENT_FOCUS_CHANGED,
_entry_focus_changed_cb, obj);
_entry_hide(obj);
str = elm_object_text_get(sd->ent);
if (!str) return;
val = strtod(str, &end);
if (((*end != '\0') && (!isspace(*end))) || (fabs(val - pd->val) < DBL_EPSILON)) return;
efl_ui_range_value_set(obj, val);
efl_event_callback_call(obj, EFL_UI_SPIN_EVENT_CHANGED, NULL);
ecore_timer_del(sd->delay_change_timer);
sd->delay_change_timer = ecore_timer_add(EFL_UI_SPIN_BUTTON_DELAY_CHANGE_TIME,
_delay_change_timer_cb, obj);
}
static void
_invalid_input_validity_filter(void *data EINA_UNUSED, Evas_Object *obj, char **text)
{
char *insert = NULL;
const char *str = NULL;
int cursor_pos = 0;
int read_idx = 0, read_char, cmp_char;
EINA_SAFETY_ON_NULL_RETURN(obj);
EINA_SAFETY_ON_NULL_RETURN(text);
insert = *text;
str = elm_object_text_get(obj);
evas_string_char_next_get(*text, 0, &read_char);
cursor_pos = elm_entry_cursor_pos_get(obj);
if (read_char)
{
if (read_char == '-')
{
if (cursor_pos != 0)
{
goto invalid_input;
}
}
if (read_char == '.')
{
read_idx = evas_string_char_next_get(str, 0, &cmp_char);
while (cmp_char)
{
if (read_char == cmp_char)
{
goto invalid_input;
}
read_idx = evas_string_char_next_get(str, read_idx, &cmp_char);
}
}
read_idx = evas_string_char_next_get(str, 0, &cmp_char);
if ((cmp_char == '-') && (cursor_pos == 0))
{
goto invalid_input;
}
}
return;
invalid_input:
*insert = 0;
}
static void
_entry_accept_filter_add(Evas_Object *obj)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
static Elm_Entry_Filter_Accept_Set digits_filter_data;
if (!sd->ent) return;
elm_entry_markup_filter_remove(sd->ent, elm_entry_filter_accept_set, &digits_filter_data);
if (pd->decimal_points > 0)
digits_filter_data.accepted = "-.0123456789";
else
digits_filter_data.accepted = "-0123456789";
elm_entry_markup_filter_prepend(sd->ent, elm_entry_filter_accept_set, &digits_filter_data);
}
static char *
_text_insert(const char *text, const char *input, int pos)
{
char *result = NULL;
int text_len, input_len;
text_len = evas_string_char_len_get(text);
input_len = evas_string_char_len_get(input);
result = (char *)calloc(text_len + input_len + 1, sizeof(char));
if (!result) return NULL;
strncpy(result, text, pos);
strcpy(result + pos, input);
strcpy(result + pos + input_len, text + pos);
return result;
}
static void
_min_max_validity_filter(void *data, Evas_Object *obj, char **text)
{
const char *str, *point;
char *insert, *new_str = NULL;
double val;
int max_len, len;
EINA_SAFETY_ON_NULL_RETURN(data);
EINA_SAFETY_ON_NULL_RETURN(obj);
EINA_SAFETY_ON_NULL_RETURN(text);
Efl_Ui_Spin_Data *pd = efl_data_scope_get(data, EFL_UI_SPIN_CLASS);
str = elm_object_text_get(obj);
if (!str) return;
insert = *text;
new_str = _text_insert(str, insert, elm_entry_cursor_pos_get(obj));
if (!new_str) return;
max_len = log10(fabs(pd->val_max)) + 1;
new_str = _text_insert(str, insert, elm_entry_cursor_pos_get(obj));
if (pd->format_type == SPIN_FORMAT_INT)
{
len = strlen(new_str);
if (len < max_len) goto end;
}
else if (pd->format_type == SPIN_FORMAT_FLOAT)
{
point = strchr(new_str, '.');
if (point)
{
if ((int) strlen(point + 1) > pd->decimal_points)
{
*insert = 0;
goto end;
}
}
}
val = strtod(new_str, NULL);
if ((val < pd->val_min) || (val > pd->val_max))
*insert = 0;
end:
free(new_str);
}
static void
_entry_show_cb(void *data,
Evas *e EINA_UNUSED,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
_entry_show(data);
elm_object_focus_set(obj, EINA_TRUE);
elm_entry_select_all(obj);
sd->entry_visible = EINA_TRUE;
elm_layout_signal_emit(data, "elm,state,button,inactive", "elm");
evas_object_hide(sd->text_button);
}
static void
_toggle_entry(Evas_Object *obj)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
if (elm_widget_disabled_get(obj)) return;
if (!sd->editable) return;
if (sd->entry_visible) _entry_value_apply(obj);
else
{
if (!sd->ent)
{
sd->ent = elm_entry_add(obj);
Eina_Strbuf *buf = eina_strbuf_new();
eina_strbuf_append_printf(buf, "spinner/%s", elm_widget_style_get(obj));
elm_widget_style_set(sd->ent, eina_strbuf_string_get(buf));
eina_strbuf_free(buf);
evas_object_event_callback_add
(sd->ent, EVAS_CALLBACK_SHOW, _entry_show_cb, obj);
elm_entry_single_line_set(sd->ent, EINA_TRUE);
elm_layout_content_set(obj, "elm.swallow.entry", sd->ent);
_entry_accept_filter_add(obj);
elm_entry_markup_filter_append(sd->ent, _invalid_input_validity_filter, NULL);
if (_elm_config->spinner_min_max_filter_enable)
elm_entry_markup_filter_append(sd->ent, _min_max_validity_filter, obj);
efl_event_callback_add(sd->ent, ELM_ENTRY_EVENT_ACTIVATED,
_entry_activated_cb, obj);
}
efl_event_callback_add(sd->ent, EFL_UI_FOCUS_OBJECT_EVENT_FOCUS_CHANGED,
_entry_focus_changed_cb, obj);
sd->entry_visible = EINA_TRUE;
elm_layout_signal_emit(obj, "elm,state,entry,active", "elm");
evas_object_show(sd->ent);
{
Eina_List *items = NULL;
items = eina_list_append(items, sd->dec_button);
items = eina_list_append(items, sd->text_button);
items = eina_list_append(items, sd->ent);
items = eina_list_append(items, sd->inc_button);
efl_ui_focus_composition_elements_set(obj, items);
}
efl_ui_focus_manager_focus_set(efl_ui_focus_user_manager_get(obj), sd->ent);
}
}
static void
_entry_toggle_cb(void *data EINA_UNUSED,
Evas_Object *obj,
const char *emission EINA_UNUSED,
const char *source EINA_UNUSED)
{
_toggle_entry(obj);
}
static Eina_Bool
_spin_value(void *data)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
Efl_Ui_Spin_Data *pd = efl_data_scope_get(data, EFL_UI_SPIN_CLASS);
if (_value_set(data, pd->val + (sd->inc_val ? pd->step : -pd->step)))
_label_write(data);
return ECORE_CALLBACK_RENEW;
}
static void
_spin_stop(Evas_Object *obj)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
ELM_SAFE_FREE(sd->spin_timer, ecore_timer_del);
elm_widget_scroll_freeze_pop(obj);
}
static Eina_Bool
_inc_dec_button_press_start(void *data)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
sd->interval = sd->first_interval;
sd->longpress_timer = NULL;
ecore_timer_del(sd->spin_timer);
sd->spin_timer = ecore_timer_add(sd->interval, _spin_value, data);
_spin_value(data);
elm_widget_scroll_freeze_push(data);
return ECORE_CALLBACK_CANCEL;
}
static void
_inc_dec_button_clicked_cb(void *data, const Efl_Event *event)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
_spin_stop(data);
sd->inc_val = sd->inc_button == event->object ? EINA_TRUE : EINA_FALSE;
_spin_value(data);
if (_elm_config->access_mode)
_access_increment_decrement_info_say(data, EINA_TRUE);
}
static void
_inc_dec_button_pressed_cb(void *data, const Efl_Event *event)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
sd->inc_val = sd->inc_button == event->object ? EINA_TRUE : EINA_FALSE;
if (sd->longpress_timer) ecore_timer_del(sd->longpress_timer);
sd->longpress_timer = ecore_timer_add
(_elm_config->longpress_timeout,
_inc_dec_button_press_start, data);
if (sd->entry_visible) _entry_value_apply(data);
}
static void
_inc_dec_button_unpressed_cb(void *data, const Efl_Event *event EINA_UNUSED)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
if (sd->longpress_timer)
{
ecore_timer_del(sd->longpress_timer);
sd->longpress_timer = NULL;
}
_spin_stop(data);
}
static void
_inc_dec_button_mouse_move_cb(void *data, const Efl_Event *event)
{
Efl_Input_Pointer *ev = event->info;
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
if (efl_input_processed_get(ev) && sd->longpress_timer)
{
ecore_timer_del(sd->longpress_timer);
sd->longpress_timer = NULL;
}
}
static void
_text_button_focus_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
{
_toggle_entry(data);
}
static void
_entry_activated_cb(void *data, const Efl_Event *event EINA_UNUSED)
{
_toggle_entry(data);
}
static void
_entry_focus_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
{
_toggle_entry(data);
}
static void
_text_button_clicked_cb(void *data, const Efl_Event *event EINA_UNUSED)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
if (sd->entry_visible) return;
_toggle_entry(data);
}
static Eina_Bool
_key_action_toggle(Evas_Object *obj, const char *params EINA_UNUSED)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
if (sd->spin_timer) _spin_stop(obj);
else if (sd->entry_visible) _entry_toggle_cb(NULL, obj, NULL, NULL);
return EINA_FALSE;
}
EOLIAN static Eina_Bool
_efl_ui_spin_button_elm_widget_widget_event(Eo *obj, Efl_Ui_Spin_Button_Data *sd EINA_UNUSED, const Efl_Event *eo_event, Evas_Object *src EINA_UNUSED)
{
Eo *ev = eo_event->info;
if (efl_input_processed_get(ev)) return EINA_FALSE;
if (eo_event->desc == EFL_EVENT_KEY_DOWN)
{
if (sd->spin_timer) _spin_stop(obj);
else return EINA_FALSE;
}
else if (eo_event->desc == EFL_EVENT_KEY_UP)
{
if (sd->spin_timer) _spin_stop(obj);
else return EINA_FALSE;
}
else if (eo_event->desc == EFL_EVENT_POINTER_WHEEL)
{
sd->interval = sd->first_interval;
if (efl_input_pointer_wheel_delta_get(ev) < 0)
sd->inc_val = EINA_TRUE;
else
sd->inc_val = EINA_FALSE;
_spin_value(obj);
}
else return EINA_FALSE;
efl_input_processed_set(ev, EINA_TRUE);
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_efl_ui_spin_button_elm_widget_on_focus_update(Eo *obj, Efl_Ui_Spin_Button_Data *sd, Elm_Object_Item *item EINA_UNUSED)
{
Eina_Bool int_ret = EINA_FALSE;
int_ret = efl_ui_widget_on_focus_update(efl_super(obj, MY_CLASS), NULL);
if (!int_ret) return EINA_FALSE;
if (!elm_widget_focus_get(obj))
{
ELM_SAFE_FREE(sd->delay_change_timer, ecore_timer_del);
ELM_SAFE_FREE(sd->spin_timer, ecore_timer_del);
}
else
{
if (sd->entry_reactivate)
{
_toggle_entry(obj);
sd->entry_reactivate = EINA_FALSE;
}
}
return EINA_TRUE;
}
EOLIAN static void
_efl_ui_spin_button_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Spin_Button_Data *_pd EINA_UNUSED)
{
Evas_Coord minw = -1, minh = -1;
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
edje_object_size_min_restricted_calc
(wd->resize_obj, &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 char *
_access_info_cb(void *data, Evas_Object *obj EINA_UNUSED)
{
const char *txt = NULL;
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
if (sd->entry_visible)
txt = elm_object_text_get(sd->ent);
else
txt = elm_object_text_get(sd->text_button);
if (txt) return strdup(txt);
return NULL;
}
static char *
_access_state_cb(void *data, Evas_Object *obj EINA_UNUSED)
{
if (elm_widget_disabled_get(data))
return strdup(E_("State: Disabled"));
return NULL;
}
static void
_access_activate_spin_button_cb(void *data,
Evas_Object *part_obj EINA_UNUSED,
Elm_Object_Item *item EINA_UNUSED)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
if (elm_widget_disabled_get(data)) return;
if (!sd->entry_visible)
_toggle_entry(data);
}
static void
_access_increment_decrement_info_say(Evas_Object *obj,
Eina_Bool is_incremented)
{
Eina_Strbuf *buf;
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
buf = eina_strbuf_new();
if (is_incremented)
{
elm_object_signal_emit
(sd->inc_button, "elm,action,anim,activate", "elm");
eina_strbuf_append(buf, E_("incremented"));
}
else
{
elm_object_signal_emit
(sd->dec_button, "elm,action,anim,activate", "elm");
eina_strbuf_append(buf, E_("decremented"));
}
eina_strbuf_append_printf
(buf, "%s", elm_object_text_get(sd->text_button));
_elm_access_say(eina_strbuf_string_get(buf));
eina_strbuf_free(buf);
}
static void
_access_spinner_register(Evas_Object *obj, Eina_Bool is_access)
{
Evas_Object *ao;
Elm_Access_Info *ai;
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
if (!is_access)
{
/* unregister access */
_elm_access_edje_object_part_object_unregister
(obj, elm_layout_edje_get(obj), "access");
elm_layout_signal_emit(obj, "elm,state,access,inactive", "elm");
return;
}
elm_layout_signal_emit(obj, "elm,state,access,active", "elm");
ao = _elm_access_edje_object_part_object_register
(obj, elm_layout_edje_get(obj), "access");
ai = _elm_access_info_get(ao);
_elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("spinner"));
_elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, obj);
_elm_access_activate_callback_set(ai, _access_activate_spin_button_cb, obj);
/*Do not register spinner buttons if widget is disabled*/
if (!elm_widget_disabled_get(obj))
{
ai = _elm_access_info_get(sd->inc_button);
_elm_access_text_set(ai, ELM_ACCESS_TYPE,
E_("spinner increment button"));
ai = _elm_access_info_get(sd->dec_button);
_elm_access_text_set(ai, ELM_ACCESS_TYPE,
E_("spinner decrement button"));
ai = _elm_access_info_get(sd->text_button);
_elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("spinner text"));
_elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, obj);
}
}
EOLIAN static Efl_Ui_Theme_Apply
_efl_ui_spin_button_elm_widget_theme_apply(Eo *obj, Efl_Ui_Spin_Button_Data *sd EINA_UNUSED)
{
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EFL_UI_THEME_APPLY_FAILED);
if (!elm_layout_theme_set(obj, "spin_button", "base", elm_widget_style_get(obj)))
CRI("Failed to set layout!");
if (sd->ent)
{
Eina_Strbuf *buf = eina_strbuf_new();
eina_strbuf_append_printf(buf, "spin_button/%s", elm_widget_style_get(obj));
elm_widget_style_set(sd->ent, eina_strbuf_string_get(buf));
eina_strbuf_free(buf);
}
if (sd->inc_button)
{
Eina_Strbuf *buf = eina_strbuf_new();
eina_strbuf_append_printf(buf, "spin_button/increase/%s", elm_widget_style_get(obj));
elm_widget_style_set(sd->inc_button, eina_strbuf_string_get(buf));
eina_strbuf_free(buf);
}
if (sd->text_button)
{
Eina_Strbuf *buf = eina_strbuf_new();
eina_strbuf_append_printf(buf, "spin_button/%s", elm_widget_style_get(obj));
elm_widget_style_set(sd->text_button, eina_strbuf_string_get(buf));
eina_strbuf_free(buf);
}
if (sd->dec_button)
{
Eina_Strbuf *buf = eina_strbuf_new();
eina_strbuf_append_printf(buf, "spin_button/decrease/%s", elm_widget_style_get(obj));
elm_widget_style_set(sd->dec_button, eina_strbuf_string_get(buf));
eina_strbuf_free(buf);
}
if (_elm_config->access_mode)
_access_spinner_register(obj, EINA_TRUE);
elm_layout_sizing_eval(obj);
return EFL_UI_THEME_APPLY_SUCCESS;
}
EOLIAN static Eo *
_efl_ui_spin_button_efl_object_finalize(Eo *obj, Efl_Ui_Spin_Button_Data *sd)
{
obj = efl_finalize(efl_super(obj, MY_CLASS));
elm_widget_sub_object_parent_add(obj);
sd->first_interval = 0.85;
if (!elm_layout_theme_set(obj, "spin_button", "base",
elm_widget_style_get(obj)))
CRI("Failed to set layout!");
sd->inc_button = elm_button_add(obj);
elm_object_style_set(sd->inc_button, "spinner/increase/default");
efl_event_callback_array_add(sd->inc_button, _inc_dec_button_cb(), obj);
elm_layout_content_set(obj, "elm.swallow.inc_button", sd->inc_button);
elm_widget_sub_object_add(obj, sd->inc_button);
sd->text_button = elm_button_add(obj);
elm_object_style_set(sd->text_button, "spinner/default");
efl_event_callback_add(sd->text_button, EFL_UI_EVENT_CLICKED,
_text_button_clicked_cb, obj);
efl_event_callback_add(sd->text_button,
EFL_UI_FOCUS_OBJECT_EVENT_FOCUS_CHANGED,
_text_button_focus_changed_cb, obj);
elm_layout_content_set(obj, "elm.swallow.text_button", sd->text_button);
elm_widget_sub_object_add(obj, sd->text_button);
sd->dec_button = elm_button_add(obj);
elm_object_style_set(sd->dec_button, "spinner/decrease/default");
efl_event_callback_array_add(sd->dec_button, _inc_dec_button_cb(), obj);
elm_layout_content_set(obj, "elm.swallow.dec_button", sd->dec_button);
elm_widget_sub_object_add(obj, sd->dec_button);
{
Eina_List *items = NULL;
items = eina_list_append(items, sd->dec_button);
items = eina_list_append(items, sd->text_button);
items = eina_list_append(items, sd->inc_button);
efl_ui_focus_composition_elements_set(obj, items);
}
elm_layout_signal_callback_add
(obj, "elm,action,entry,toggle", "*", _entry_toggle_cb, NULL);
_label_write(obj);
elm_widget_can_focus_set(obj, EINA_TRUE);
elm_layout_sizing_eval(obj);
efl_access_role_set(obj, EFL_ACCESS_ROLE_SPIN_BUTTON);
return obj;
}
EOLIAN static void
_efl_ui_spin_button_efl_ui_range_range_value_set(Eo *obj, Efl_Ui_Spin_Button_Data *sd EINA_UNUSED, double val)
{
efl_ui_range_value_set(efl_super(obj, MY_CLASS), val);
_label_write(obj);
}
EOLIAN static void
_efl_ui_spin_button_editable_set(Eo *obj EINA_UNUSED, Efl_Ui_Spin_Button_Data *sd, Eina_Bool editable)
{
sd->editable = editable;
}
EOLIAN static Eina_Bool
_efl_ui_spin_button_editable_get(Eo *obj EINA_UNUSED, Efl_Ui_Spin_Button_Data *sd)
{
return sd->editable;
}
EOLIAN static void
_efl_ui_spin_button_loop_set(Eo *obj EINA_UNUSED, Efl_Ui_Spin_Button_Data *sd, Eina_Bool loop)
{
sd->loop = loop;
}
EOLIAN static Eina_Bool
_efl_ui_spin_button_loop_get(Eo *obj EINA_UNUSED, Efl_Ui_Spin_Button_Data *sd)
{
return sd->loop;
}
EOLIAN static const Efl_Access_Action_Data *
_efl_ui_spin_button_efl_access_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Efl_Ui_Spin_Button_Data *sd EINA_UNUSED)
{
static Efl_Access_Action_Data atspi_actions[] = {
{ "toggle", "toggle", NULL, _key_action_toggle},
{ NULL, NULL, NULL, NULL }
};
return &atspi_actions[0];
}
// A11Y Accessibility
EOLIAN static void
_efl_ui_spin_button_efl_access_value_value_and_text_get(Eo *obj EINA_UNUSED, Efl_Ui_Spin_Button_Data *sd EINA_UNUSED, double *value, const char **text)
{
Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
if (value) *value = pd->val;
if (text) *text = NULL;
}
EOLIAN static Eina_Bool
_efl_ui_spin_button_efl_access_value_value_and_text_set(Eo *obj, Efl_Ui_Spin_Button_Data *sd EINA_UNUSED, double value, const char *text EINA_UNUSED)
{
Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
if (pd->val_min > value) return EINA_FALSE;
if (pd->val_max < value) return EINA_FALSE;
pd->val = value;
efl_ui_range_value_set(efl_super(obj, MY_CLASS), value);
return EINA_TRUE;
}
EOLIAN static void
_efl_ui_spin_button_efl_access_value_range_get(Eo *obj EINA_UNUSED, Efl_Ui_Spin_Button_Data *sd EINA_UNUSED, double *lower, double *upper, const char **descr)
{
Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
if (lower) *lower = pd->val_min;
if (upper) *upper = pd->val_max;
if (descr) *descr = NULL;
}
EOLIAN static double
_efl_ui_spin_button_efl_access_value_increment_get(Eo *obj EINA_UNUSED, Efl_Ui_Spin_Button_Data *sd EINA_UNUSED)
{
Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
return pd->step;
}
EOLIAN static const char*
_efl_ui_spin_button_efl_access_name_get(Eo *obj, Efl_Ui_Spin_Button_Data *sd EINA_UNUSED)
{
const char *name;
name = efl_access_name_get(efl_super(obj, EFL_UI_SPIN_BUTTON_CLASS));
if (name) return name;
const char *ret = elm_layout_text_get(obj, "elm.text");
return ret;
}
// A11Y Accessibility - END
#define EFL_UI_SPIN_BUTTON_EXTRA_OPS \
ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_spin_button), \
#include "efl_ui_spin_button.eo.c"

View File

@ -0,0 +1,80 @@
class Efl.Ui.Spin_Button (Efl.Ui.Spin, Efl.Ui.Focus.Composition,
Efl.Access.Value, Efl.Access.Widget.Action)
{
[[A Button Spin.
This is a widget which allows the user to increase or decrease
numeric values using arrow buttons, or edit values directly, clicking
over it and typing the new value.
@since 1.21
]]
methods {
@property loop {
[[Control whether the spin should loop when it reaches its minimum or maximum value.
Disabled by default. If disabled, when the user tries to increment the
value,
but displayed value plus step value is bigger than maximum value,
the new value will be the maximum value.
The same happens when the user tries to decrement it,
but the value less step is less than minimum value. In this case,
the new displayed value will be the minimum value.
When loop is enabled, when the user tries to increment the value,
but displayed value plus step value is bigger than maximum value,
the new value will be the minimum value. When the the user tries to
decrement it, but the value less step is less than minimum value,
the new displayed value will be the maximum value.
E.g.:
$min = 10
$max = 50
$step = 20
$displayed = 20
When the user decrement value (using left or bottom arrow), it will
displays $50.]]
set {
}
get {
}
values {
loop: bool(false); [[$true to enable loop or $false to disable it.]]
}
}
@property editable {
[[Control whether the spin can be directly edited by the user or not.
Spin objects can have edition disabled, in which state they will
be changed only by arrows.
Useful for contexts
where you don't want your users to interact with it writing the value.
Specially
when using special values, the user can see real value instead
of special label on edition.]]
set {
}
get {
}
values {
editable: bool(false); [[$true to allow users to edit it or $false to don't allow users to edit it directly.]]
}
}
}
implements {
Efl.Object.finalize;
Elm.Widget.theme_apply;
Elm.Widget.widget_event;
Elm.Widget.on_focus_update;
Efl.Ui.Range.range_value { set; }
Efl.Access.name { get; }
Efl.Access.Value.value_and_text { get; set; }
Efl.Access.Value.range { get; }
Efl.Access.Value.increment { get; }
Efl.Access.Widget.Action.elm_actions { get; }
}
events {
delay,changed; [[Called when spin delay changed]]
}
}

View File

@ -0,0 +1,20 @@
#ifndef EFL_UI_SPIN_BUTTON_PRIVATE_H
#define EFL_UI_SPIN_BUTTON_PRIVATE_H
typedef struct _Efl_Ui_Spin_Button_Data Efl_Ui_Spin_Button_Data;
struct _Efl_Ui_Spin_Button_Data
{
double interval, first_interval;
Evas_Object *ent, *inc_button, *dec_button, *text_button;
Ecore_Timer *delay_change_timer; /**< a timer for a delay,changed smart callback */
Ecore_Timer *spin_timer; /**< a timer for a repeated spinner value change on mouse down */
Ecore_Timer *longpress_timer; /**< a timer to detect long press. After lonpress timeout,
start continuous change of values until mouse up */
Eina_Bool entry_visible : 1;
Eina_Bool entry_reactivate : 1;
Eina_Bool editable : 1;
Eina_Bool inc_val : 1;
Eina_Bool loop : 1;
};
#endif

View File

@ -0,0 +1,29 @@
#ifndef EFL_UI_SPIN_PRIVATE_H
#define EFL_UI_SPIN_PRIVATE_H
#include "Elementary.h"
typedef enum _Efl_Ui_Spin_Format_Type
{
SPIN_FORMAT_FLOAT,
SPIN_FORMAT_INT,
SPIN_FORMAT_INVALID
} Efl_Ui_Spin_Format_Type;
typedef struct _Efl_Ui_Spin_Data Efl_Ui_Spin_Data;
struct _Efl_Ui_Spin_Data
{
const char *templates;
double val, val_min, val_max;
double step; /**< step for the value change. 1 by default. */
int decimal_points;
Ecore_Timer *spin_timer; /**< a timer for a repeated spin value change on mouse down */
Efl_Ui_Spin_Format_Type format_type;
Efl_Ui_Format_Func_Cb format_cb;
Eina_Free_Cb format_free_cb;
void *format_cb_data;
Eina_Strbuf *format_strbuf;
};
#endif

View File

@ -470,7 +470,7 @@ _items_add(Evas_Object *obj)
}
EOLIAN static void
_elm_flipselector_efl_ui_spin_min_max_set(Eo *obj, Elm_Flipselector_Data *sd, double min, double max)
_elm_flipselector_efl_ui_range_range_min_max_set(Eo *obj, Elm_Flipselector_Data *sd, double min, double max)
{
if (min > max) return;
if ((sd->val_min == min) && (sd->val_max == max)) return;
@ -482,14 +482,14 @@ _elm_flipselector_efl_ui_spin_min_max_set(Eo *obj, Elm_Flipselector_Data *sd, do
}
EOLIAN static void
_elm_flipselector_efl_ui_spin_min_max_get(Eo *obj EINA_UNUSED, Elm_Flipselector_Data *sd, double *min, double *max)
_elm_flipselector_efl_ui_range_range_min_max_get(Eo *obj EINA_UNUSED, Elm_Flipselector_Data *sd, double *min, double *max)
{
if (min) *min = sd->val_min;
if (max) *max = sd->val_max;
}
EOLIAN static void
_elm_flipselector_efl_ui_spin_step_set(Eo *obj EINA_UNUSED, Elm_Flipselector_Data *sd, double step)
_elm_flipselector_efl_ui_range_range_step_set(Eo *obj EINA_UNUSED, Elm_Flipselector_Data *sd, double step)
{
if (sd->step == step) return;
@ -498,13 +498,13 @@ _elm_flipselector_efl_ui_spin_step_set(Eo *obj EINA_UNUSED, Elm_Flipselector_Dat
}
EOLIAN static double
_elm_flipselector_efl_ui_spin_step_get(Eo *obj EINA_UNUSED, Elm_Flipselector_Data *sd)
_elm_flipselector_efl_ui_range_range_step_get(Eo *obj EINA_UNUSED, Elm_Flipselector_Data *sd)
{
return sd->step;
}
EOLIAN static double
_elm_flipselector_efl_ui_spin_value_get(Eo *obj EINA_UNUSED, Elm_Flipselector_Data *sd)
_elm_flipselector_efl_ui_range_range_value_get(Eo *obj EINA_UNUSED, Elm_Flipselector_Data *sd)
{
if (sd->val_min == 0 && sd->val_max == 0)
{
@ -516,7 +516,7 @@ _elm_flipselector_efl_ui_spin_value_get(Eo *obj EINA_UNUSED, Elm_Flipselector_Da
}
EOLIAN static void
_elm_flipselector_efl_ui_spin_value_set(Eo *obj EINA_UNUSED, Elm_Flipselector_Data *sd, double val)
_elm_flipselector_efl_ui_range_range_value_set(Eo *obj EINA_UNUSED, Elm_Flipselector_Data *sd, double val)
{
Eina_List *l;
Elm_Object_Item *it;
@ -657,18 +657,6 @@ elm_flipselector_add(Evas_Object *parent)
return elm_legacy_add(MY_CLASS, parent);
}
EAPI void
elm_flipselector_first_interval_set(Evas_Object *obj, double interval)
{
efl_ui_spin_interval_set(obj, interval);
}
EAPI double
elm_flipselector_first_interval_get(const Evas_Object *obj)
{
return efl_ui_spin_interval_get(obj);
}
EOLIAN static Eo *
_elm_flipselector_efl_object_constructor(Eo *obj, Elm_Flipselector_Data *sd)
{
@ -869,14 +857,14 @@ _elm_flipselector_item_next_get(const Eo *eo_item,
return NULL;
}
EOLIAN static void
_elm_flipselector_efl_ui_spin_interval_set(Eo *obj EINA_UNUSED, Elm_Flipselector_Data *sd, double interval)
EOLIAN void
_elm_flipselector_first_interval_set(Eo *obj EINA_UNUSED, Elm_Flipselector_Data *sd, double interval)
{
sd->first_interval = interval;
}
EOLIAN static double
_elm_flipselector_efl_ui_spin_interval_get(Eo *obj EINA_UNUSED, Elm_Flipselector_Data *sd)
EOLIAN double
_elm_flipselector_first_interval_get(Eo *obj EINA_UNUSED, Elm_Flipselector_Data *sd)
{
return sd->first_interval;
}

View File

@ -1,4 +1,4 @@
class Elm.Flipselector (Efl.Ui.Layout, Efl.Ui.Spin,
class Elm.Flipselector (Efl.Ui.Layout, Efl.Ui.Range,
Efl.Access.Widget.Action,
Efl.Ui.Selectable)
{
@ -60,6 +60,40 @@ class Elm.Flipselector (Efl.Ui.Layout, Efl.Ui.Spin,
}
}
@property first_interval {
set {
[[Set the interval on time updates for a user mouse button hold
on a flip selector widget.
This interval value is decreased while the user holds the
mouse pointer either flipping up or flipping down a given flip
selector.
This helps the user to get to a given item distant from the
current one easier/faster, as it will start to flip quicker and
quicker on mouse button holds.
The calculation for the next flip interval value, starting from
the one set with this call, is the previous interval divided by
1.05, so it decreases a little bit.
The default starting interval value for automatic flips is
0.85 seconds.
See also @.first_interval.get.
]]
}
get {
[[Get the interval on time updates for an user mouse button hold
on a flip selector widget.
See also @.first_interval.set for more details.
]]
}
values {
interval: double; [[The (first) interval value in seconds.]]
}
}
item_prepend {
[[Prepend a (text) item to a flip selector widget
@ -129,10 +163,9 @@ class Elm.Flipselector (Efl.Ui.Layout, Efl.Ui.Spin,
Efl.Object.constructor;
Elm.Widget.theme_apply;
Elm.Widget.widget_event;
Efl.Ui.Spin.min_max { get; set; }
Efl.Ui.Spin.step { get; set; }
Efl.Ui.Spin.value { get; set; }
Efl.Ui.Spin.interval { get; set; }
Efl.Ui.Range.range_min_max { get; set; }
Efl.Ui.Range.range_step { get; set; }
Efl.Ui.Range.range_value { get; set; }
Efl.Access.Widget.Action.elm_actions { get; }
}
events {

View File

@ -11,42 +11,5 @@
*/
EAPI Evas_Object *elm_flipselector_add(Evas_Object *parent);
/**
* @brief Set the interval on time updates for a user mouse button hold on a
* flip selector widget.
*
* This interval value is decreased while the user holds the mouse pointer
* either flipping up or flipping down a given flip selector.
*
* This helps the user to get to a given item distant from the current one
* easier/faster, as it will start to flip quicker and quicker on mouse button
* holds.
*
* The calculation for the next flip interval value, starting from the one set
* with this call, is the previous interval divided by 1.05, so it decreases a
* little bit.
*
* The default starting interval value for automatic flips is 0.85 seconds.
*
* See also @ref elm_obj_flipselector_first_interval_get.
*
* @param[in] interval The (first) interval value in seconds.
*
* @ingroup Elm_Flipselector
*/
EAPI void elm_flipselector_first_interval_set(Evas_Object *obj, double interval);
/**
* @brief Get the interval on time updates for an user mouse button hold on a
* flip selector widget.
*
* See also @ref elm_obj_flipselector_first_interval_set for more details.
*
* @return The (first) interval value in seconds.
*
* @ingroup Elm_Flipselector
*/
EAPI double elm_flipselector_first_interval_get(const Evas_Object *obj);
#include "elm_flipselector_item.eo.legacy.h"
#include "elm_flipselector.eo.legacy.h"

View File

@ -1359,49 +1359,37 @@ elm_spinner_add(Evas_Object *parent)
EAPI void
elm_spinner_min_max_set(Evas_Object *obj, double min, double max)
{
efl_ui_spin_min_max_set(obj, min, max);
efl_ui_range_min_max_set(obj, min, max);
}
EAPI void
elm_spinner_min_max_get(const Evas_Object *obj, double *min, double *max)
{
efl_ui_spin_min_max_get(obj, min, max);
efl_ui_range_min_max_get(obj, min, max);
}
EAPI void
elm_spinner_step_set(Evas_Object *obj, double step)
{
efl_ui_spin_step_set(obj, step);
efl_ui_range_step_set(obj, step);
}
EAPI double
elm_spinner_step_get(const Evas_Object *obj)
{
return efl_ui_spin_step_get(obj);
}
EAPI void
elm_spinner_interval_set(Evas_Object *obj, double interval)
{
efl_ui_spin_interval_set(obj, interval);
}
EAPI double
elm_spinner_interval_get(const Evas_Object *obj)
{
return efl_ui_spin_interval_get(obj);
return efl_ui_range_step_get(obj);
}
EAPI void
elm_spinner_value_set(Evas_Object *obj, double val)
{
efl_ui_spin_value_set(obj, val);
efl_ui_range_value_set(obj, val);
}
EAPI double
elm_spinner_value_get(const Evas_Object *obj)
{
return efl_ui_spin_value_get(obj);
return efl_ui_range_value_get(obj);
}
EOLIAN static Eo *
@ -1447,7 +1435,7 @@ _elm_spinner_label_format_get(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd)
}
EOLIAN static void
_elm_spinner_efl_ui_spin_min_max_set(Eo *obj, Elm_Spinner_Data *sd, double min, double max)
_elm_spinner_efl_ui_range_range_min_max_set(Eo *obj, Elm_Spinner_Data *sd, double min, double max)
{
if ((sd->val_min == min) && (sd->val_max == max)) return;
@ -1462,26 +1450,26 @@ _elm_spinner_efl_ui_spin_min_max_set(Eo *obj, Elm_Spinner_Data *sd, double min,
}
EOLIAN static void
_elm_spinner_efl_ui_spin_min_max_get(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd, double *min, double *max)
_elm_spinner_efl_ui_range_range_min_max_get(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd, double *min, double *max)
{
if (min) *min = sd->val_min;
if (max) *max = sd->val_max;
}
EOLIAN static void
_elm_spinner_efl_ui_spin_step_set(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd, double step)
_elm_spinner_efl_ui_range_range_step_set(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd, double step)
{
sd->step = step;
}
EOLIAN static double
_elm_spinner_efl_ui_spin_step_get(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd)
_elm_spinner_efl_ui_range_range_step_get(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd)
{
return sd->step;
}
EOLIAN static void
_elm_spinner_efl_ui_spin_value_set(Eo *obj, Elm_Spinner_Data *sd, double val)
_elm_spinner_efl_ui_range_range_value_set(Eo *obj, Elm_Spinner_Data *sd, double val)
{
if (sd->val == val) return;
@ -1504,7 +1492,7 @@ _elm_spinner_efl_ui_spin_value_set(Eo *obj, Elm_Spinner_Data *sd, double val)
}
EOLIAN static double
_elm_spinner_efl_ui_spin_value_get(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd)
_elm_spinner_efl_ui_range_range_value_get(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd)
{
return sd->val;
}
@ -1601,13 +1589,13 @@ _elm_spinner_editable_get(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd)
}
EOLIAN static void
_elm_spinner_efl_ui_spin_interval_set(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd, double interval)
_elm_spinner_interval_set(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd, double interval)
{
sd->first_interval = interval;
}
EOLIAN static double
_elm_spinner_efl_ui_spin_interval_get(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd)
_elm_spinner_interval_get(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd)
{
return sd->first_interval;
}

View File

@ -1,4 +1,4 @@
class Elm.Spinner (Efl.Ui.Layout, Efl.Ui.Spin, Efl.Ui.Focus.Composition,
class Elm.Spinner (Efl.Ui.Layout, Efl.Ui.Range, Efl.Ui.Focus.Composition,
Efl.Access.Value, Efl.Access.Widget.Action)
{
[[Elementary spinner class]]
@ -39,6 +39,30 @@ class Elm.Spinner (Efl.Ui.Layout, Efl.Ui.Spin, Efl.Ui.Focus.Composition,
wrap: bool; [[$true to enable wrap or $false to disable it.]]
}
}
@property interval {
[[Control the interval on time updates for an user mouse button hold on spinner widgets' arrows.
This interval value is decreased while the user holds the
mouse pointer either incrementing or decrementing spinner's value.
This helps the user to get to a given value distant from the
current one easier/faster, as it will start to change quicker and
quicker on mouse button holds.
The calculation for the next change interval value, starting from
the one set with this call, is the previous interval divided by
$1.05, so it decreases a little bit.
The default starting interval value for automatic changes is
$0.85 seconds.]]
set {
}
get {
}
values {
interval: double; [[The (first) interval value in seconds.]]
}
}
@property round {
[[Control the round value for rounding
@ -150,10 +174,9 @@ class Elm.Spinner (Efl.Ui.Layout, Efl.Ui.Spin, Efl.Ui.Focus.Composition,
Elm.Widget.on_access_update;
Elm.Widget.on_focus_update;
Elm.Widget.widget_event;
Efl.Ui.Spin.min_max { get; set; }
Efl.Ui.Spin.step { get; set; }
Efl.Ui.Spin.value { get; set; }
Efl.Ui.Spin.interval { get; set; }
Efl.Ui.Range.range_min_max { get; set; }
Efl.Ui.Range.range_step { get; set; }
Efl.Ui.Range.range_value { get; set; }
Efl.Access.name { get; }
Efl.Access.Value.value_and_text { get; set; }
Efl.Access.Value.range { get; }

View File

@ -118,52 +118,6 @@ EAPI void elm_spinner_step_set(Evas_Object *obj, double step);
*/
EAPI double elm_spinner_step_get(const Evas_Object *obj);
/**
* @brief Control the interval on time updates for an user mouse button hold on
* spinner widgets' arrows.
*
* This interval value is decreased while the user holds the mouse pointer
* either incrementing or decrementing spinner's value.
*
* This helps the user to get to a given value distant from the current one
* easier/faster, as it will start to change quicker and quicker on mouse
* button holds.
*
* The calculation for the next change interval value, starting from the one
* set with this call, is the previous interval divided by $1.05, so it
* decreases a little bit.
*
* The default starting interval value for automatic changes is $0.85 seconds.
*
* @param[in] interval The (first) interval value in seconds.
*
* @ingroup Elm_Spinner
*/
EAPI void elm_spinner_interval_set(Evas_Object *obj, double interval);
/**
* @brief Control the interval on time updates for an user mouse button hold on
* spinner widgets' arrows.
*
* This interval value is decreased while the user holds the mouse pointer
* either incrementing or decrementing spinner's value.
*
* This helps the user to get to a given value distant from the current one
* easier/faster, as it will start to change quicker and quicker on mouse
* button holds.
*
* The calculation for the next change interval value, starting from the one
* set with this call, is the previous interval divided by $1.05, so it
* decreases a little bit.
*
* The default starting interval value for automatic changes is $0.85 seconds.
*
* @return The (first) interval value in seconds.
*
* @ingroup Elm_Spinner
*/
EAPI double elm_spinner_interval_get(const Evas_Object *obj);
/**
* @brief Control the value the spinner displays.
*