woohyun pushed a commit to branch master.

http://git.enlightenment.org/core/elementary.git/commit/?id=55352b09346ca541c98bdfe16832430ab5ec25c6

commit 55352b09346ca541c98bdfe16832430ab5ec25c6
Author: Youngbok Shin <youngb.s...@samsung.com>
Date:   Tue Dec 22 18:48:16 2015 +0900

    calendar: Apply elm_button widgets instead of manually implemented spinner 
buttons.
    
    Summary:
    The spinner buttons in elm_calendar widget can be replaced by elm_buttons.
    Then, using elm_button widgets makes it much easier to maintain.
    And the buttons has to be focusable with "tab" key just like elm_spinner 
widget.
    The lagacy callbacks for signals from edje is not removed for backward 
compatibility.
    @feature
    
    Test Plan: elementary_test -> calendar, calendar2, calendar3
    
    Reviewers: seoz, Hermet, kimcinoo, cedric, woohyun
    
    Reviewed By: woohyun
    
    Subscribers: CHAN
    
    Differential Revision: https://phab.enlightenment.org/D3198
---
 data/themes/edc/elm/button.edc   |   4 +
 data/themes/edc/elm/calendar.edc | 134 +++---------
 src/lib/elm_calendar.c           | 426 ++++++++++++++++++++++++++++++++++++---
 src/lib/elm_widget_calendar.h    |  10 +-
 4 files changed, 429 insertions(+), 145 deletions(-)

diff --git a/data/themes/edc/elm/button.edc b/data/themes/edc/elm/button.edc
index 92b026b..0088b6d 100644
--- a/data/themes/edc/elm/button.edc
+++ b/data/themes/edc/elm/button.edc
@@ -1337,6 +1337,8 @@ 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/calendar/increase/default";
+      alias: "elm/button/base/calendar/increase/double_spinners";
       images.image: "sym_right_light_normal.png" COMP;
       images.image: "sym_right_glow_normal.png" COMP;
       images.image: "sym_right_dark_normal.png" COMP;
@@ -1489,6 +1491,8 @@ 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/calendar/decrease/default";
+      alias: "elm/button/base/calendar/decrease/double_spinners";
       images.image: "sym_left_light_normal.png" COMP;
       images.image: "sym_left_glow_normal.png" COMP;
       images.image: "sym_left_dark_normal.png" COMP;
diff --git a/data/themes/edc/elm/calendar.edc b/data/themes/edc/elm/calendar.edc
index 35a0367..b706a82 100644
--- a/data/themes/edc/elm/calendar.edc
+++ b/data/themes/edc/elm/calendar.edc
@@ -12,8 +12,8 @@
          base: "font="FN" font_size=10 color=#151515 style=shadow_bottom 
shadow_color=#ffffffc0 align=center";\
       }\
 
-#define CAL_SPIN(_sufix, _signal_sufix, _text, _relative)\
-      part { name: "left_bt"#_sufix; type: RECT;\
+#define CAL_SPIN(_sufix, _text, _relative)\
+      part { name: "left_bt"#_sufix; type: SPACER;\
          scale: 1;\
          description { state: "default" 0.0;\
             fixed: 1 1;\
@@ -26,30 +26,6 @@
             align: 0.0 0.5;\
             min: 15 15;\
             max: 15 15;\
-            color: 0 0 0 0;\
-         }\
-      }\
-      part { name: "left_bt"#_sufix"_over"; repeat_events: 1;\
-         scale: 1;\
-         description { state: "default" 0.0;\
-            min: 15 15;\
-            max: 15 15;\
-            align: 0.5 0.5;\
-            rel1.to: "left_bt"#_sufix;\
-            rel2.to: "left_bt"#_sufix;\
-            image.normal: "sym_left_light_normal.png";\
-         }\
-         description { state: "rtl" 0.0;\
-            inherit: "default" 0.0;\
-            image.normal: "sym_right_light_normal.png";\
-         }\
-         description { state: "clicked" 0.0;\
-            inherit: "default" 0.0;\
-            image.normal: "sym_left_glow_normal.png";\
-         }\
-         description { state: "clicked_rtl" 0.0;\
-            inherit: "default" 0.0;\
-            image.normal: "sym_right_glow_normal.png";\
          }\
       }\
       part { name: "right_bt"#_sufix; type: RECT;\
@@ -68,26 +44,32 @@
             color: 0 0 0 0;\
          }\
       }\
-      part { name: "right_bt"#_sufix"_over"; repeat_events: 1;\
+      part { name: "elm,calendar,button"#_sufix",left";\
+         type: SWALLOW;\
          scale: 1;\
          description { state: "default" 0.0;\
-            min: 15 15;\
-            max: 15 15;\
-            rel1.to: "right_bt"#_sufix;\
-            rel2.to: "right_bt"#_sufix;\
-            image.normal: "sym_right_light_normal.png";\
+            fixed: 1 1;\
+            rel1.to: "left_bt"#_sufix;\
+            rel2.to: "left_bt"#_sufix;\
          }\
          description { state: "rtl" 0.0;\
             inherit: "default" 0.0;\
-            image.normal: "sym_left_light_normal.png";\
+            rel1.to: "right_bt"#_sufix;\
+            rel2.to: "right_bt"#_sufix;\
          }\
-         description { state: "clicked" 0.0;\
-            inherit: "default" 0.0;\
-            image.normal: "sym_right_glow_normal.png";\
+      }\
+      part { name: "elm,calendar,button"#_sufix",right";\
+         type: SWALLOW;\
+         scale: 1;\
+         description { state: "default" 0.0;\
+            fixed: 1 1;\
+            rel1.to: "right_bt"#_sufix;\
+            rel2.to: "right_bt"#_sufix;\
          }\
-         description { state: "clicked_rtl" 0.0;\
+         description { state: "rtl" 0.0;\
             inherit: "default" 0.0;\
-            image.normal: "sym_left_glow_normal.png";\
+            rel1.to: "left_bt"#_sufix;\
+            rel2.to: "left_bt"#_sufix;\
          }\
       }\
       part { name: #_text; type: TEXT; mouse_events: 0;\
@@ -106,76 +88,6 @@
                min: 0 1;\
             }\
          }\
-      }\
-      programs {\
-         program {\
-            signal: "mouse,down,1"; source: "left_bt"#_sufix;\
-            action: SIGNAL_EMIT "elm,action,decrement,start"#_signal_sufix 
"elm";\
-         }\
-         program {\
-            signal: "mouse,up,1"; source: "left_bt"#_sufix;\
-            action: SIGNAL_EMIT "elm,action,stop"#_signal_sufix "elm"; \
-         }\
-         program { name:   "left_bt"#_sufix"_click";\
-            signal: "mouse,down,1"; source: "left_bt"#_sufix;\
-            script {\
-               if (get_int(rtl) == 1)\
-                 set_state(PART:"left_bt"#_sufix"_over", "clicked_rtl", 0.0);\
-               else\
-                 set_state(PART:"left_bt"#_sufix"_over", "clicked", 0.0);\
-            }\
-         }\
-         program { name:   "left_bt"#_sufix"_unclick";\
-            signal: "mouse,up,1"; source: "left_bt"#_sufix;\
-            script {\
-               if (get_int(rtl) == 1)\
-                 set_state(PART:"left_bt"#_sufix"_over", "rtl", 0.0);\
-               else\
-                 set_state(PART:"left_bt"#_sufix"_over", "default", 0.0);\
-            }\
-         }\
-         program {\
-            signal: "mouse,down,1"; source: "right_bt"#_sufix;\
-            action: SIGNAL_EMIT "elm,action,increment,start"#_signal_sufix 
"elm";\
-         }\
-         program {\
-            signal: "mouse,up,1"; source: "right_bt"#_sufix;\
-            action: SIGNAL_EMIT "elm,action,stop"#_signal_sufix "elm";     \
-         }\
-         program { name:   "right_bt"#_sufix"_click";\
-            signal: "mouse,down,1"; source: "right_bt"#_sufix;\
-            script {\
-               if (get_int(rtl) == 1)\
-                 set_state(PART:"right_bt"#_sufix"_over", "clicked_rtl", 0.0);\
-               else\
-                 set_state(PART:"right_bt"#_sufix"_over", "clicked", 0.0);\
-            }\
-         }\
-         program { name:   "right_bt"#_sufix"_unclick";\
-            signal: "mouse,up,1"; source: "right_bt"#_sufix;\
-            script {\
-               if (get_int(rtl) == 1)\
-                 set_state(PART:"right_bt"#_sufix"_over", "rtl", 0.0);\
-               else\
-                 set_state(PART:"right_bt"#_sufix"_over", "default", 0.0);\
-            }\
-         }\
-         program { name:   "rtl"#_sufix;\
-            signal: "edje,state,rtl"; source: "edje";\
-            script {\
-               set_int(rtl, 1);\
-               set_state(PART:"left_bt"#_sufix"_over", "rtl", 0.0);\
-               set_state(PART:"right_bt"#_sufix"_over", "rtl", 0.0);\
-            }\
-         }\
-         program { name:   "ltr"#_sufix;\
-            signal: "edje,state,ltr"; source: "edje";\
-            script {\
-               set_int(rtl, 0);\
-               set_state(PART:"left_bt"#_sufix"_over", "default", 0.0);\
-               set_state(PART:"right_bt"#_sufix"_over", "default", 0.0);\
-            }\
-         }\
       }
 
 #define CH(_pos) \
@@ -512,7 +424,7 @@ group { name: "elm/calendar/base/default";
          }
       }
 
-      CAL_SPIN(,,month_text, spinner-base1)
+      CAL_SPIN(,month_text, spinner-base1)
       CH(0)   CH(1)   CH(2)   CH(3)   CH(4)   CH(5)   CH(6)
       CIT(0)  CIT(1)  CIT(2)  CIT(3)  CIT(4)  CIT(5)  CIT(6)
       CIT(7)  CIT(8)  CIT(9)  CIT(10) CIT(11) CIT(12) CIT(13)
@@ -551,8 +463,8 @@ group { name: "elm/calendar/base/double_spinners";
             align: 0.0 0.0;
          }
       }
-      CAL_SPIN(,,month_text, spinner-base1)
-      CAL_SPIN(_year, year, year_text, spinner-base2)
+      CAL_SPIN(,month_text, spinner-base1)
+      CAL_SPIN(_year, year_text, spinner-base2)
    }
 }
 
diff --git a/src/lib/elm_calendar.c b/src/lib/elm_calendar.c
index c1aa2d6..65e13e7 100644
--- a/src/lib/elm_calendar.c
+++ b/src/lib/elm_calendar.c
@@ -14,6 +14,11 @@
 #define MY_CLASS_NAME "Elm_Calendar"
 #define MY_CLASS_NAME_LEGACY "elm_calendar"
 
+#define ELM_CALENDAR_BUTTON_LEFT "elm,calendar,button,left"
+#define ELM_CALENDAR_BUTTON_RIGHT "elm,calendar,button,right"
+#define ELM_CALENDAR_BUTTON_YEAR_LEFT "elm,calendar,button_year,left"
+#define ELM_CALENDAR_BUTTON_YEAR_RIGHT "elm,calendar,button_year,right"
+
 static const char SIG_CHANGED[] = "changed";
 static const char SIG_DISPLAY_CHANGED[] = "display,changed";
 
@@ -27,6 +32,96 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = {
    {NULL, NULL}
 };
 
+/* Originally, the button functionalities of month, year spinners were
+ * implemented by its own edc. There was a bunch of callback functions
+ * for handle the signals. The following functions are the old callback
+ * functions for handle the signals.
+ *    _button_month_dec_start
+ *    _button_year_inc_start
+ *    _button_year_dec_start
+ *    _button_month_stop
+ *    _button_year_stop
+ *
+ * But, it is replaced by elm_button widget objects. The following
+ * callback functions are also newly added for button objects.
+ * We still keep the old signal callback functions for backward compatibility. 
*/
+static void
+_button_widget_month_inc_start_click(void *data,
+                                     Evas_Object *obj EINA_UNUSED,
+                                     void *event_info EINA_UNUSED);
+static void
+_button_widget_month_inc_start(void *data,
+                              Evas_Object *obj EINA_UNUSED,
+                              void *event_info EINA_UNUSED);
+static void
+_button_widget_month_dec_start_click(void *data,
+                                    Evas_Object *obj EINA_UNUSED,
+                                    void *event_info EINA_UNUSED);
+static void
+_button_widget_month_dec_start(void *data,
+                              Evas_Object *obj EINA_UNUSED,
+                              void *event_info EINA_UNUSED);
+static void
+_button_widget_year_inc_start_click(void *data,
+                                    Evas_Object *obj EINA_UNUSED,
+                                    void *event_info EINA_UNUSED);
+static void
+_button_widget_year_inc_start(void *data,
+                              Evas_Object *obj EINA_UNUSED,
+                              void *event_info EINA_UNUSED);
+static void
+_button_widget_year_dec_start_click(void *data,
+                                    Evas_Object *obj EINA_UNUSED,
+                                    void *event_info EINA_UNUSED);
+static void
+_button_widget_year_dec_start(void *data,
+                              Evas_Object *obj EINA_UNUSED,
+                              void *event_info EINA_UNUSED);
+
+/* This two functions should be moved in Eina for next release. */
+static Eina_Tmpstr *
+_eina_tmpstr_strftime(const char *format, const struct tm *tm)
+{
+   const size_t flen = strlen(format);
+   size_t buflen = 16; // An arbitrary starting size
+   char *buf = NULL;
+
+   do {
+      char *tmp;
+      size_t len;
+
+      tmp = realloc(buf, buflen * sizeof(char));
+      if (!tmp) goto on_error;
+      buf = tmp;
+
+      len = strftime(buf, buflen, format, tm);
+      // Check if we have the expected result and return it.
+      if ((len > 0 && len < buflen) || (len == 0 && flen == 0))
+        {
+           Eina_Tmpstr *r;
+
+           r = eina_tmpstr_add_length(buf, len + 1);
+           free(buf);
+           return r;
+        }
+
+      /* Possibly buf overflowed - try again with a bigger buffer */
+      buflen <<= 1; // multiply buffer size by 2
+   } while (buflen < 128 * flen);
+
+ on_error:
+   free(buf);
+   return NULL;
+}
+
+static char *
+_eina_tmpstr_steal(Eina_Tmpstr *s)
+{
+   char *r = s ? strdup(s) : NULL;
+   eina_tmpstr_del(s);
+   return r;
+}
+
 static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
 
 static const Elm_Action key_actions[] = {
@@ -321,24 +416,28 @@ _access_calendar_spinner_register(Evas_Object *obj)
    Elm_Access_Info *ai;
    ELM_CALENDAR_DATA_GET(obj, sd);
 
-   sd->dec_btn_month_access = _elm_access_edje_object_part_object_register
-                            (obj, elm_layout_edje_get(obj), "left_bt");
-   ai = _elm_access_info_get(sd->dec_btn_month_access);
+   if (!sd->dec_btn_month)
+     sd->dec_btn_month = _elm_access_edje_object_part_object_register
+        (obj, elm_layout_edje_get(obj), "left_bt");
+   ai = _elm_access_info_get(sd->dec_btn_month);
    _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("calendar decrement month 
button"));
 
-   sd->dec_btn_year_access = _elm_access_edje_object_part_object_register
-                            (obj, elm_layout_edje_get(obj), "left_bt_year");
-   ai = _elm_access_info_get(sd->dec_btn_year_access);
+   if (!sd->dec_btn_year)
+     sd->dec_btn_year = _elm_access_edje_object_part_object_register
+        (obj, elm_layout_edje_get(obj), "left_bt_year");
+   ai = _elm_access_info_get(sd->dec_btn_year);
    _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("calendar decrement year 
button"));
 
-   sd->inc_btn_month_access = _elm_access_edje_object_part_object_register
-                            (obj, elm_layout_edje_get(obj), "right_bt");
-   ai = _elm_access_info_get(sd->inc_btn_month_access);
+   if (!sd->inc_btn_month)
+     sd->inc_btn_month = _elm_access_edje_object_part_object_register
+        (obj, elm_layout_edje_get(obj), "right_bt");
+   ai = _elm_access_info_get(sd->inc_btn_month);
    _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("calendar increment month 
button"));
 
-   sd->inc_btn_year_access = _elm_access_edje_object_part_object_register
-                            (obj, elm_layout_edje_get(obj), "right_bt_year");
-   ai = _elm_access_info_get(sd->inc_btn_year_access);
+   if (!sd->inc_btn_year)
+     sd->inc_btn_year = _elm_access_edje_object_part_object_register
+        (obj, elm_layout_edje_get(obj), "right_bt_year");
+   ai = _elm_access_info_get(sd->inc_btn_year);
    _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("calendar increment year 
button"));
 
    sd->month_access = _elm_access_edje_object_part_object_register
@@ -627,14 +726,140 @@ _set_headers(Evas_Object *obj)
    elm_layout_thaw(obj);
 }
 
+static void
+_spinner_buttons_add(Evas_Object *obj, Elm_Calendar_Data *sd)
+{
+   char left_buf[255] = { 0 };
+   char right_buf[255] = { 0 };
+
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+   snprintf(left_buf, sizeof(left_buf), "calendar/decrease/%s", 
elm_object_style_get(obj));
+   snprintf(right_buf, sizeof(right_buf), "calendar/increase/%s", 
elm_object_style_get(obj));
+
+   if (edje_object_part_exists(wd->resize_obj, ELM_CALENDAR_BUTTON_LEFT))
+     {
+        if (sd->dec_btn_month && eo_isa(sd->dec_btn_month, ELM_ACCESS_CLASS))
+          {
+             _elm_access_edje_object_part_object_unregister
+               (obj, elm_layout_edje_get(obj), "left_bt");
+             sd->dec_btn_month = NULL;
+          }
+
+        if (!sd->dec_btn_month)
+          {
+             sd->dec_btn_month = elm_button_add(obj);
+             elm_button_autorepeat_set(sd->dec_btn_month, EINA_TRUE);
+             elm_button_autorepeat_initial_timeout_set(sd->dec_btn_month, 0.5);
+             elm_button_autorepeat_gap_timeout_set(sd->dec_btn_month, 0.2);
+             evas_object_smart_callback_add(sd->dec_btn_month, "clicked", 
_button_widget_month_dec_start_click, obj);
+             evas_object_smart_callback_add(sd->dec_btn_month, "repeated", 
_button_widget_month_dec_start, obj);
+          }
+
+        elm_object_style_set(sd->dec_btn_month, left_buf);
+        elm_layout_content_set(obj, ELM_CALENDAR_BUTTON_LEFT, 
sd->dec_btn_month);
+     }
+   else if (sd->dec_btn_month && !eo_isa(sd->dec_btn_month, ELM_ACCESS_CLASS))
+     {
+        evas_object_del(sd->dec_btn_month);
+        sd->dec_btn_month = NULL;
+     }
+
+   if (edje_object_part_exists(wd->resize_obj, ELM_CALENDAR_BUTTON_RIGHT))
+     {
+        if (sd->inc_btn_month && eo_isa(sd->inc_btn_month, ELM_ACCESS_CLASS))
+          {
+             _elm_access_edje_object_part_object_unregister
+               (obj, elm_layout_edje_get(obj), "right_bt");
+             sd->inc_btn_month = NULL;
+          }
+
+        if (!sd->inc_btn_month)
+          {
+             sd->inc_btn_month = elm_button_add(obj);
+             elm_button_autorepeat_set(sd->inc_btn_month, EINA_TRUE);
+             elm_button_autorepeat_initial_timeout_set(sd->inc_btn_month, 0.5);
+             elm_button_autorepeat_gap_timeout_set(sd->inc_btn_month, 0.2);
+             evas_object_smart_callback_add(sd->inc_btn_month, "clicked", 
_button_widget_month_inc_start_click, obj);
+             evas_object_smart_callback_add(sd->inc_btn_month, "repeated", 
_button_widget_month_inc_start, obj);
+          }
+
+        elm_object_style_set(sd->inc_btn_month, right_buf);
+        elm_layout_content_set(obj, ELM_CALENDAR_BUTTON_RIGHT, 
sd->inc_btn_month);
+     }
+   else if (sd->inc_btn_month && !eo_isa(sd->inc_btn_month, ELM_ACCESS_CLASS))
+     {
+        evas_object_del(sd->inc_btn_month);
+        sd->inc_btn_month = NULL;
+     }
+
+   if (edje_object_part_exists(wd->resize_obj, ELM_CALENDAR_BUTTON_YEAR_LEFT))
+     {
+        if (sd->dec_btn_year && eo_isa(sd->dec_btn_year, ELM_ACCESS_CLASS))
+          {
+             _elm_access_edje_object_part_object_unregister
+               (obj, elm_layout_edje_get(obj), "left_bt_year");
+             sd->dec_btn_year = NULL;
+          }
+
+        if (!sd->dec_btn_year)
+          {
+             sd->dec_btn_year = elm_button_add(obj);
+             elm_button_autorepeat_set(sd->dec_btn_year, EINA_TRUE);
+             elm_button_autorepeat_initial_timeout_set(sd->dec_btn_year, 0.5);
+             elm_button_autorepeat_gap_timeout_set(sd->dec_btn_year, 0.2);
+             evas_object_smart_callback_add(sd->dec_btn_year, "clicked", 
_button_widget_year_dec_start_click, obj);
+             evas_object_smart_callback_add(sd->dec_btn_year, "repeated", 
_button_widget_year_dec_start, obj);
+         }
+
+        elm_object_style_set(sd->dec_btn_year, left_buf);
+        elm_layout_content_set(obj, ELM_CALENDAR_BUTTON_YEAR_LEFT, 
sd->dec_btn_year);
+     }
+   else if (sd->dec_btn_year && !eo_isa(sd->dec_btn_year, ELM_ACCESS_CLASS))
+     {
+        evas_object_del(sd->dec_btn_year);
+        sd->dec_btn_year = NULL;
+     }
+
+   if (edje_object_part_exists(wd->resize_obj, ELM_CALENDAR_BUTTON_YEAR_RIGHT))
+     {
+        if (sd->inc_btn_year && eo_isa(sd->inc_btn_year, ELM_ACCESS_CLASS))
+          {
+             _elm_access_edje_object_part_object_unregister
+               (obj, elm_layout_edje_get(obj), "right_bt_year");
+             sd->inc_btn_year = NULL;
+          }
+
+        if (!sd->inc_btn_year)
+          {
+             sd->inc_btn_year = elm_button_add(obj);
+             elm_button_autorepeat_set(sd->inc_btn_year, EINA_TRUE);
+             elm_button_autorepeat_initial_timeout_set(sd->inc_btn_year, 0.5);
+             elm_button_autorepeat_gap_timeout_set(sd->inc_btn_year, 0.2);
+             evas_object_smart_callback_add(sd->inc_btn_year, "clicked", 
_button_widget_year_inc_start_click, obj);
+             evas_object_smart_callback_add(sd->inc_btn_year, "repeated", 
_button_widget_year_inc_start, obj);
+          }
+
+        elm_object_style_set(sd->inc_btn_year, right_buf);
+        elm_layout_content_set(obj, ELM_CALENDAR_BUTTON_YEAR_RIGHT, 
sd->inc_btn_year);
+     }
+   else if (sd->inc_btn_year && !eo_isa(sd->inc_btn_year, ELM_ACCESS_CLASS))
+     {
+        evas_object_del(sd->inc_btn_year);
+        sd->inc_btn_year = NULL;
+     }
+}
+
 EOLIAN static Eina_Bool
-_elm_calendar_elm_widget_theme_apply(Eo *obj, Elm_Calendar_Data *_pd 
EINA_UNUSED)
+_elm_calendar_elm_widget_theme_apply(Eo *obj, Elm_Calendar_Data *sd)
 {
    Eina_Bool int_ret = EINA_FALSE;
 
    eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
    if (!int_ret) return EINA_FALSE;
 
+   _spinner_buttons_add(obj, sd);
+
    evas_object_smart_changed(obj);
    return EINA_TRUE;
 }
@@ -745,6 +970,7 @@ _spin_year_value(void *data)
    return ECORE_CALLBACK_RENEW;
 }
 
+/* Legacy callbacks for signals from edje */
 static void
 _button_month_inc_start(void *data,
                   Evas_Object *obj EINA_UNUSED,
@@ -761,6 +987,7 @@ _button_month_inc_start(void *data,
    _spin_month_value(data);
 }
 
+/* Legacy callbacks for signals from edje */
 static void
 _button_month_dec_start(void *data,
                   Evas_Object *obj EINA_UNUSED,
@@ -777,6 +1004,7 @@ _button_month_dec_start(void *data,
    _spin_month_value(data);
 }
 
+/* Legacy callbacks for signals from edje */
 static void
 _button_month_stop(void *data,
                    Evas_Object *obj EINA_UNUSED,
@@ -789,6 +1017,7 @@ _button_month_stop(void *data,
    ELM_SAFE_FREE(sd->spin_month, ecore_timer_del);
 }
 
+/* Legacy callbacks for signals from edje */
 static void
 _button_year_inc_start(void *data,
                        Evas_Object *obj EINA_UNUSED,
@@ -805,6 +1034,7 @@ _button_year_inc_start(void *data,
    _spin_year_value(data);
 }
 
+/* Legacy callbacks for signals from edje */
 static void
 _button_year_dec_start(void *data,
                   Evas_Object *obj EINA_UNUSED,
@@ -821,6 +1051,7 @@ _button_year_dec_start(void *data,
    _spin_year_value(data);
 }
 
+/* Legacy callbacks for signals from edje */
 static void
 _button_year_stop(void *data,
                   Evas_Object *obj EINA_UNUSED,
@@ -833,6 +1064,126 @@ _button_year_stop(void *data,
    ELM_SAFE_FREE(sd->spin_year, ecore_timer_del);
 }
 
+static void
+_button_widget_month_inc_start_click(void *data,
+                                    Evas_Object *obj EINA_UNUSED,
+                                    void *event_info EINA_UNUSED)
+{
+   ELM_CALENDAR_DATA_GET(data, sd);
+   if (sd->month_repeated)
+     {
+        sd->month_repeated = EINA_FALSE;
+        return;
+     }
+
+   sd->interval = sd->first_interval;
+   sd->spin_speed = 1;
+   _spin_month_value(data);
+}
+
+static void
+_button_widget_month_inc_start(void *data,
+                              Evas_Object *obj EINA_UNUSED,
+                              void *event_info EINA_UNUSED)
+{
+   ELM_CALENDAR_DATA_GET(data, sd);
+
+   sd->interval = sd->first_interval;
+   sd->spin_speed = 1;
+   _spin_month_value(data);
+   sd->month_repeated = EINA_TRUE;
+}
+
+static void
+_button_widget_month_dec_start_click(void *data,
+                                    Evas_Object *obj EINA_UNUSED,
+                                    void *event_info EINA_UNUSED)
+{
+   ELM_CALENDAR_DATA_GET(data, sd);
+   if (sd->month_repeated)
+     {
+        sd->month_repeated = EINA_FALSE;
+        return;
+     }
+
+   sd->interval = sd->first_interval;
+   sd->spin_speed = -1;
+   _spin_month_value(data);
+}
+
+static void
+_button_widget_month_dec_start(void *data,
+                              Evas_Object *obj EINA_UNUSED,
+                              void *event_info EINA_UNUSED)
+{
+   ELM_CALENDAR_DATA_GET(data, sd);
+
+   sd->interval = sd->first_interval;
+   sd->spin_speed = -1;
+   _spin_month_value(data);
+   sd->month_repeated = EINA_TRUE;
+}
+
+static void
+_button_widget_year_inc_start_click(void *data,
+                                    Evas_Object *obj EINA_UNUSED,
+                                    void *event_info EINA_UNUSED)
+{
+   ELM_CALENDAR_DATA_GET(data, sd);
+   if (sd->year_repeated)
+     {
+        sd->year_repeated = EINA_FALSE;
+        return;
+     }
+
+   sd->interval = sd->first_interval;
+   sd->spin_speed = 1;
+   _spin_year_value(data);
+}
+
+static void
+_button_widget_year_inc_start(void *data,
+                              Evas_Object *obj EINA_UNUSED,
+                              void *event_info EINA_UNUSED)
+{
+   ELM_CALENDAR_DATA_GET(data, sd);
+
+   sd->interval = sd->first_interval;
+   sd->spin_speed = 1;
+   _spin_year_value(data);
+   sd->year_repeated = EINA_TRUE;
+}
+
+static void
+_button_widget_year_dec_start_click(void *data,
+                                    Evas_Object *obj EINA_UNUSED,
+                                    void *event_info EINA_UNUSED)
+{
+   ELM_CALENDAR_DATA_GET(data, sd);
+   if (sd->year_repeated)
+     {
+        sd->year_repeated = EINA_FALSE;
+        return;
+     }
+
+   sd->interval = sd->first_interval;
+   sd->spin_speed = -1;
+   _spin_year_value(data);
+}
+
+static void
+_button_widget_year_dec_start(void *data,
+                              Evas_Object *obj EINA_UNUSED,
+                              void *event_info EINA_UNUSED)
+{
+   ELM_CALENDAR_DATA_GET(data, sd);
+
+   sd->interval = sd->first_interval;
+   sd->spin_speed = -1;
+   _spin_year_value(data);
+   sd->year_repeated = EINA_TRUE;
+}
+
 static int
 _get_item_day(Evas_Object *obj,
               int selected_it)
@@ -1076,6 +1427,8 @@ _elm_calendar_evas_object_smart_add(Eo *obj, 
Elm_Calendar_Data *priv)
                              elm_object_style_get(obj)))
      CRI("Failed to set layout!");
 
+   _spinner_buttons_add(obj, priv);
+
    evas_object_smart_changed(obj);
 
    // ACCESS
@@ -1112,7 +1465,7 @@ static Eina_Bool _elm_calendar_smart_focus_next_enable = 
EINA_FALSE;
 EOLIAN static Eina_Bool
 _elm_calendar_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, 
Elm_Calendar_Data *_pd EINA_UNUSED)
 {
-   return _elm_calendar_smart_focus_next_enable;
+   return EINA_TRUE;
 }
 
 EOLIAN static Eina_Bool
@@ -1130,12 +1483,12 @@ _elm_calendar_elm_widget_focus_next(Eo *obj, 
Elm_Calendar_Data *sd, Elm_Focus_Di
    Evas_Object *po;
 
    items = eina_list_append(items, sd->month_access);
-   items = eina_list_append(items, sd->dec_btn_month_access);
-   items = eina_list_append(items, sd->inc_btn_month_access);
+   items = eina_list_append(items, sd->dec_btn_month);
+   items = eina_list_append(items, sd->inc_btn_month);
 
    items = eina_list_append(items, sd->year_access);
-   items = eina_list_append(items, sd->dec_btn_year_access);
-   items = eina_list_append(items, sd->inc_btn_year_access);
+   items = eina_list_append(items, sd->dec_btn_year);
+   items = eina_list_append(items, sd->inc_btn_year);
 
    day = 0;
    maxdays = _maxdays_get(&sd->shown_time, 0);
@@ -1164,6 +1517,7 @@ _access_obj_process(Evas_Object *obj, Eina_Bool is_access)
    int maxdays, day, i;
 
    ELM_CALENDAR_DATA_GET(obj, sd);
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
 
    if (is_access)
      _access_calendar_register(obj);
@@ -1184,22 +1538,34 @@ _access_obj_process(Evas_Object *obj, Eina_Bool 
is_access)
                }
           }
 
-        if (sd->dec_btn_month_access)
-          _elm_access_edje_object_part_object_unregister
-            (obj, elm_layout_edje_get(obj), "left_bt");
-        if (sd->inc_btn_month_access)
-          _elm_access_edje_object_part_object_unregister
-            (obj, elm_layout_edje_get(obj), "right_bt");
+        if (sd->dec_btn_month && eo_isa(sd->dec_btn_month, ELM_ACCESS_CLASS))
+          {
+             _elm_access_edje_object_part_object_unregister
+               (obj, elm_layout_edje_get(obj), "left_bt");
+             sd->dec_btn_month = NULL;
+          }
+        if (sd->inc_btn_month && eo_isa(sd->inc_btn_month, ELM_ACCESS_CLASS))
+          {
+             _elm_access_edje_object_part_object_unregister
+               (obj, elm_layout_edje_get(obj), "right_bt");
+             sd->inc_btn_month = NULL;
+          }
         if (sd->month_access)
           _elm_access_edje_object_part_object_unregister
             (obj, elm_layout_edje_get(obj), "month_text");
 
-        if (sd->dec_btn_year_access)
-          _elm_access_edje_object_part_object_unregister
-            (obj, elm_layout_edje_get(obj), "left_bt_year");
-        if (sd->inc_btn_year_access)
-          _elm_access_edje_object_part_object_unregister
-            (obj, elm_layout_edje_get(obj), "right_bt_year");
+        if (sd->dec_btn_year && eo_isa(sd->dec_btn_year, ELM_ACCESS_CLASS))
+          {
+             _elm_access_edje_object_part_object_unregister
+               (obj, elm_layout_edje_get(obj), "left_bt_year");
+             sd->dec_btn_year = NULL;
+          }
+        if (sd->inc_btn_year && eo_isa(sd->inc_btn_year, ELM_ACCESS_CLASS))
+          {
+             _elm_access_edje_object_part_object_unregister
+               (obj, elm_layout_edje_get(obj), "right_bt_year");
+             sd->inc_btn_year = NULL;
+          }
         if (sd->year_access)
           _elm_access_edje_object_part_object_unregister
             (obj, elm_layout_edje_get(obj), "year_text");
diff --git a/src/lib/elm_widget_calendar.h b/src/lib/elm_widget_calendar.h
index e7d4d47..f5b54a7 100644
--- a/src/lib/elm_widget_calendar.h
+++ b/src/lib/elm_widget_calendar.h
@@ -44,11 +44,11 @@ struct _Elm_Calendar_Data
    const char              *weekdays[ELM_DAY_LAST];
    struct tm                current_time, selected_time, shown_time;
    Day_Color                day_color[42]; // EINA_DEPRECATED
-   Evas_Object             *inc_btn_month_access;
-   Evas_Object             *dec_btn_month_access;
+   Evas_Object             *inc_btn_month;
+   Evas_Object             *dec_btn_month;
    Evas_Object             *month_access;
-   Evas_Object             *inc_btn_year_access;
-   Evas_Object             *dec_btn_year_access;
+   Evas_Object             *inc_btn_year;
+   Evas_Object             *dec_btn_year;
    Evas_Object             *year_access;
 
    Elm_Calendar_Weekday     first_week_day;
@@ -59,6 +59,8 @@ struct _Elm_Calendar_Data
    Eina_Bool                double_spinners : 1;
    Eina_Bool                filling : 1;
    Eina_Bool                weekdays_set : 1;
+   Eina_Bool                month_repeated : 1;
+   Eina_Bool                year_repeated : 1;
 };
 
 struct _Elm_Calendar_Mark

-- 


Reply via email to