Ring is the view that shows up on alarm or timer's timeout.
The style of the view depends on the type of the ring. If
ring view was called by alarm it shows the alarm info,
otherwise is called by timer and shows time counter. Ring
is created on app_control request with proper operation set
from the following:
http://tizen.org/appcontrol/operation/alarm
http://tizen.org/appcontrol/operation/timeout
Commit implements:
- ring view with alarm data content or counter,
- ring presenter due to MVP pattern,
- ring model which is created and used only if ring shows up
on timer's call.
- ring controller to create ring presenter, view and model
adjusted to the type of the requested call.
Change-Id: Ice190b3b47c3aa8deb69bf37dd6a7506e1f37bc1
#define PACKAGE "org.tizen.clock"
+#define APP_CONTROL_OPERATION_TIMEOUT "http://tizen.org/appcontrol/operation/timeout"
+#define APP_CONTROL_OPERATION_ALARM "http://tizen.org/appcontrol/operation/alarm"
+
#endif
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CLOCK_MODEL_RING_CONTROLLER_H_
+#define _CLOCK_MODEL_RING_CONTROLLER_H_
+
+#include "Presenter/RingPresenter.h"
+
+namespace controller {
+
+ class RingController {
+ public:
+ static RingController &GetInstance(void);
+
+ ~RingController(){};
+
+ void operator=(RingController const&) = delete;
+ RingController(RingController const&) = delete;
+
+ void HandleAlarm(int alarmID);
+ void HandleTimeout(void);
+
+ void ShutDown(void);
+
+ private:
+ presenter::RingPresenter *presenter_;
+ model::Ring *model_;
+ view::RingView *view_;
+
+ RingController(){};
+ };
+
+} //namespace model
+
+#endif //_CLOCK_MODEL_RING_CONTROLLER_H_
#include <vector>
#include <functional>
-
namespace model {
class AlarmProvider : public utils::ISerializable {
public:
return true;
}
- Duration GetTime()
+ Duration GetTime() const
{
return GetTimeSinceEpoch() - start_time_ + pause_time_;
}
- Duration GetTimeSinceEpoch()
+ Duration GetTimeSinceEpoch() const
{
return duration_cast<Duration>(system_clock::now().time_since_epoch());
}
- Duration GetStartTime()
+ Duration GetStartTime() const
{
return start_time_;
}
+ unsigned GetHour() const
+ {
+ return (unsigned)(duration_cast<hours>(GetTime()).count() % 99);
+ }
+
+ unsigned GetMinute() const
+ {
+ return (unsigned)(duration_cast<minutes>(GetTime()).count() % 60);
+ }
+
+ unsigned GetSecond() const
+ {
+ return (unsigned)(duration_cast<seconds>(GetTime()).count() % 60);
+ }
+
private:
Duration start_time_;
Duration pause_time_;
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CLOCK_MODEL_RING_H_
+#define _CLOCK_MODEL_RING_H_
+
+#include "Model/Counter.h"
+
+namespace model {
+
+ class Ring : public Counter<std::chrono::seconds>{
+ public:
+
+ private:
+
+ };
+
+} //namespace model
+
+#endif //_CLOCK_MODEL_RING_H_
#ifndef _CLOCK_TIMER_H_
#define _CLOCK_TIMER_H_
+#include <app_control.h>
+
#include "Model/Counter.h"
using namespace std::chrono;
unsigned GetSecond(void) const;
void SetTime(int hour, int minute, int second);
+ bool ActivateAlarm(int delay);
+ bool DeactivateAlarm(void);
seconds GetRemainingTime(void);
private:
unsigned minute_;
unsigned second_;
+ int alarm_id_;
+
+ static app_control_h CreateAppControl(void);
+
};
} /* model */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CLOCK_PRESENTER_RING_H_
+#define _CLOCK_PRESENTER_RING_H_
+
+#include "View/RingView.h"
+#include "Model/Ring.h"
+#include "Model/Alarm.h"
+#include "Common/CounterAnimator.h"
+
+namespace presenter {
+
+ class RingPresenter {
+ public:
+ RingPresenter(view::RingView *view, model::Ring *model);
+ RingPresenter(view::RingView *view, model::Alarm *alarm);
+ ~RingPresenter();
+
+ void DismissButtonClicked(void);
+ void SnoozeButtonClicked(void);
+
+ private:
+ view::RingView *view_;
+ model::Ring *model_;
+
+ model::Alarm *alarm_;
+
+ common::CounterAnimator animator_;
+
+ void TimeUpdateRequest(void);
+ };
+
+} //namespace presenter
+
+#endif //_CLOCK_PRESENTER_RING_H_
void ResetButtonClicked();
void CancelButtonClicked();
+ void TimeIsUp();
+
void TimeUpdateRequest();
};
std::string GetFormattedTime(const char *icu_format) const;
std::string GetFormattedTimeByTimezoneOffset(const char *icu_format, int timezone_offset) const;
int GetLocalTimezoneOffset(void) const;
+ std::string GetDate() const;
};
} /* utils */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CLOCK_VIEW_RING_H_
+#define _CLOCK_VIEW_RING_H_
+
+#include <Elementary.h>
+#include <vector>
+#include <functional>
+
+#include "View/CounterView.h"
+
+namespace view {
+
+ enum class RingSignal {
+ BUTTON_DISMISS_CLICKED,
+ BUTTON_SNOOZE_CLICKED,
+
+ MAX,
+ };
+
+ class RingView : public ui::IView {
+ public:
+ RingView();
+ ~RingView();
+
+ void ShowCounter(void);
+ void SetTitle(const char *title);
+ void SetTimeLabel(const char *ampm, const char *hour, const char *date);
+
+ void DisplayTime(int hour, int min, int sec);
+
+ void RegisterSignal(std::function<void(void)>func, RingSignal type);
+ void EmitSignal(RingSignal type);
+ void EnableSnooze(bool enabled);
+
+ Evas_Object *GetEvasObject();
+
+ private:
+ Evas_Object *win_;
+ Evas_Object *layout_;
+ view::CounterView *counter_;
+
+ std::vector<std::function<void(void)>> signals_
+ = std::vector<std::function<void(void)>>((int)RingSignal::MAX, nullptr);
+
+ static const char *GROUP;
+ static const char *EDJE_FILE;
+
+ static void DismissCb(void *data, Evas_Object *obj, const char *emission, const char *source);
+ static void SnoozeCb(void *data, Evas_Object *obj, const char *emission, const char *source);
+
+ void SetMainContent(Evas_Object *ly);
+ };
+
+} //namespace view
+
+#endif //_CLOCK_VIEW_RING_H_
void RegisterSignal(std::function<void(void)>func, TimerSignal type);
void SetEnabledStartButton(bool enable);
- void ShowTimeIsUpAlert();
void DisplayTime(int hour, int min, int sec);
void GetTime(int *hour, int *minute, int *second);
name: "ATO012L";
base: "font=Tizen:style=Thin color=#FAFAFA wrap=none font_size=88 align=center";
}
+ style {
+ name: "ATO021L";
+ base: "font=Tizen:style=Thin color=#FAFAFA wrap=none font_size=154 align=center";
+ }
}
base_scale: 2.6;
desc { "timer";
text.style: "ATO010";
}
+ desc { "ring";
+ text.style: "ATO021L";
+ }
}
program {
signal: "digits,set,stopwatch,expand";
action: STATE_SET "timer";
target: "digit";
}
+ program {
+ signal: "digits,set,ring";
+ source: "counter";
+ action: STATE_SET "ring";
+ target: "digit";
+ }
}
}
inherit: "default";
text.style: "ATO010";
}
+ desc { "ring";
+ inherit: "default";
+ text.style: "ATO021L";
+ }
}
program {
signal: "digits,set,stopwatch,expand";
action: STATE_SET "timer";
target: "colon";
}
+ program {
+ signal: "digits,set,ring";
+ source: "counter";
+ action: STATE_SET "ring";
+ target: "colon";
+ }
}
}
base: "font=Tizen:style=Regular color=#FAFAFA5E wrap=none font_size=31 align=center";
}
style {
- name: "ATO009L";
- base: "font=Tizen:style=Regular color=#FAFAFA5E wrap=none font_size=31";
- }
- style {
name: "ATO010";
base: "font=Tizen:style=Thin color=#FAFAFA wrap=none font_size=160 align=center";
}
#include "color_classes.edc"
#define ALARM_TITLE_HEIGHT 69
-#define ALARM_TITLE_AMPM_PADDING_HEIGHT 100
-#define ALARM_TITLE_HOUR_PADDING_HEIGHT 127
collections {
name: "ATO008";
base: "font=Tizen:style=Light color=#FAFAFA wrap=none font_size=48 align=center";
}
+ style {
+ name: "ATO009";
+ base: "font=Tizen:style=Regular color=#FAFAFA wrap=none font_size=31 align=center";
+ }
+ style {
+ name: "ATO021L";
+ base: "font=Tizen:style=Thin color=#FAFAFA wrap=none font_size=154 align=center";
+ }
}
images {
group { "main";
parts {
- rect { "bg"; scale; nomouse;
+ rect { "bg"; nomouse;
desc { "default";
color: 20 107 147 255;
align: 0.0 0.0;
}
spacer { "pd.top"; scale; nomouse;
desc { "default";
+ fixed: 0 1;
min: 0 120;
max: -1 120;
align: 0.5 0.0;
}
spacer { "pd.bottom"; scale; nomouse;
desc { "default";
- min: 0 120+60;
- max: -1 120+60;
+ fixed: 0 1;
+ min: 0 60;
+ max: -1 60;
align: 0.0 1.0;
rel1.to: "bg";
rel2.to: "bg";
textblock { "txt.title"; scale; nomouse;
effect: FAR_SOFT_SHADOW;
desc { "default";
- fixed: 1 1;
- min: 0 ALARM_TITLE_HEIGHT;
- max: -1 ALARM_TITLE_HEIGHT;
+ fixed: 0 1;
+ min: 0 69;
+ max: -1 69;
align: 0.5 0.0;
rel1 { relative: 0.0 1.0; to_y: "pd.top"; }
- text { style: "ATO006"; }
+ text { style: "ATO006"; }
+ }
+ }
+ swallow { "sw.content"; scale; nomouse;
+ desc { "default";
+ rel1 { relative: 0.0 1.0; to_y: "txt.title"; }
+ rel2 { relative: 1.0 0.0; to_y: "pd.bottom"; }
+ }
+ desc { "contracted";
+ inherit: "default";
+ fixed: 1 0;
+ min: 620 0;
+ max: 620 230;
+ }
+ }
+ textblock { "txt.minus"; scale;
+ desc { "default";
+ fixed: 1 1;
+ min: 36 204;
+ max: 36 204;
+ align: 1.0 0.0;
+ rel1 { relative: 0.0 0.0; to_y: "sw.content"; }
+ rel2 { relative: 0.0 1.0; to: "sw.content"; }
+ text {
+ style: "ATO021L";
+ text: "-";
+ align: 1.0 0.5;
+ }
+ hid;
+ }
+ desc { "visible";
+ inherit: "default";
+ vis;
+ }
+ }
+ group { "sw.swipe.area"; scale;
+ source: "swipe_area";
+ desc { "default";
+ max: -1 438;
+ align: 0.0 1.0;
+ }
+ }
+ spacer { "pd.title"; scale;
+ desc { "default";
+ fixed: 0 1;
+ min: 0 157;
+ max: -1 157;
+ align: 0.5 0.0;
+ rel1 { relative: 0.0 1.0; to_y: "txt.title"; }
+ }
+ }
+ textblock { "txt.hours"; scale;
+ desc { "default";
+ fixed: 1 1;
+ min: 146 42;
+ max: 146 42;
+ align: 0.0 0.0;
+ rel1 { relative: 0.0 1.0; to_x: "sw.content"; to_y: "pd.title"; offset: 18 0; }
+ rel2 { relative: 1.0 1.0; to: "sw.content"; }
+ text {
+ style: "ATO009";
+ text: "Hours";
+ }
+ hid;
+ }
+ desc { "visible";
+ inherit: "default";
+ vis;
+ }
+ }
+ textblock { "txt.minutes"; scale;
+ desc { "default";
+ fixed: 1 1;
+ min: 146 42;
+ max: 146 42;
+ align: 0.5 0.0;
+ rel1 { relative: 0.0 1.0; to_x: "sw.content"; to_y: "pd.title"; }
+ rel2 { relative: 1.0 1.0; to: "sw.content";}
+ text {
+ style: "ATO009";
+ text: "Minutes";
+ }
+ hid;
+ }
+ desc { "visible";
+ inherit: "default";
+ vis;
+ }
+ }
+ textblock { "txt.seconds"; scale;
+ desc { "default";
+ fixed: 1 1;
+ min: 146 42;
+ max: 146 42;
+ align: 1.0 0.0;
+ rel1 { relative: 0.0 1.0; to_x: "sw.content"; to_y: "pd.title"; }
+ rel2 { relative: 1.0 1.0; to: "sw.content"; offset: -18 0; }
+ text {
+ style: "ATO009";
+ text: "Seconds";
+ }
+ hid;
+ }
+ desc { "visible";
+ inherit: "default";
+ vis;
+ }
+ }
+ program {
+ signal: "set,ring,alarm,view";
+ source: "ring";
+ script {
+ set_state(PART:"sw.content", "default", 0.0);
+ set_state(PART:"txt.minus", "default", 0.0);
+ set_state(PART:"txt.hours", "default", 0.0);
+ set_state(PART:"txt.minutes", "default", 0.0);
+ set_state(PART:"txt.seconds", "default", 0.0);
+ }
+ }
+ program {
+ signal: "set,ring,counter,view";
+ source: "ring";
+ script {
+ set_state(PART:"sw.content", "contracted", 0.0);
+ set_state(PART:"txt.minus", "visible", 0.0);
+ set_state(PART:"txt.hours", "visible", 0.0);
+ set_state(PART:"txt.minutes", "visible", 0.0);
+ set_state(PART:"txt.seconds", "visible", 0.0);
+ }
+ }
+ }
+ }
+
+ group { "alarm_info";
+ parts {
+ spacer { "pd.top"; scale;
+ desc { "default";
+ align: 0.5 0.0;
+ fixed: 0 1;
+ min: 0 127;
+ max: -1 127;
+ }
+ }
+ spacer { "pd.ampm"; scale;
+ desc { "default";
+ align: 0.5 0.0;
+ fixed: 0 1;
+ min: 0 100;
+ max: -1 100;
}
}
textblock { "txt.ampm"; scale; nomouse;
effect: FAR_SOFT_SHADOW;
desc { "default";
- min: 0 ALARM_TITLE_HEIGHT;
- max: -1 ALARM_TITLE_HEIGHT;
+ fixed: 0 1;
+ min: 0 69;
+ max: -1 69;
align: 0.5 0.0;
- rel1 { relative: 0.0 1.0; to_y: "pd.top";
- offset: 0 ALARM_TITLE_HEIGHT+ALARM_TITLE_AMPM_PADDING_HEIGHT; }
+ rel1 { relative: 0.0 1.0; to_y: "pd.ampm"; }
text { style: "ATO006"; }
}
}
min: 0 230;
max: -1 230;
align: 0.5 0.0;
- rel1 { relative: 0.0 1.0; to_y: "pd.top";
- offset: 0 ALARM_TITLE_HEIGHT+ALARM_TITLE_HOUR_PADDING_HEIGHT; }
+ rel1 { relative: 0.0 1.0; to_y: "pd.top"; }
text { style: "ATO007"; }
}
}
desc { "default";
min: 0 64;
max: -1 64;
- align: 0.5 1.0;
- rel2 { to_y: "pd.bottom"; relative: 1.0 0.0; }
+ align: 0.5 0.0;
+ rel1 { relative: 0.0 1.0; to_y: "txt.time"; }
text { style: "ATO008"; }
}
}
- group { "sw.swipe.area"; scale;
- source: "swipe_area";
- desc { "default";
- fixed: 1 1;
- min: 0 438;
- max: -1 438;
- align: 0.0 1.0;
- rel1 { relative: 0.0 1.0; to: "bg"; }
- rel2 { relative: 1.0 1.0; }
- }
- }
}
}
- group {
- name: "swipe_area";
+
+ group { "swipe_area";
parts {
- rect { "bg"; scale; nomouse;
+ rect { "bg"; nomouse;
desc {
state: "default" 0.0;
color: 255 255 255 255;
}
}
- spacer { "left.padding";
+ spacer { "pd.left"; scale;
desc { "default";
min: 36 0;
max: 36 -1;
align: 0.0 0.5;
}
}
- spacer { "right.padding";
+ spacer { "pd.right"; scale;
desc { "default";
min: 36 0;
max: 36 -1;
align: 1.0 0.5;
}
}
- swallow { "swipe.left.button"; scale;
+ group { "sw.btn.dismiss"; scale;
+ source: "button_dismiss";
desc { "default";
fixed: 1 1;
+ min: 180 180;
+ max: 180 180;
align: 0.0 0.5;
- rel1 { relative: 1.0 0.0; to_x: "left.padding"; }
- rel2 { relative: 1.0 1.0; }
+ rel1 { relative: 1.0 0.0; to_x: "pd.left"; }
+ rel2 { relative: 0.0 1.0; to_x: "pd.right"; }
+ }
+ desc { "contracted";
+ inherit: "default";
+ align: 0.5 0.5;
}
}
- swallow { "swipe.right.button"; scale;
+ group { "sw.btn.snooze"; scale;
+ source: "button_snooze";
desc { "default";
fixed: 1 1;
+ min: 180 180;
+ max: 180 180;
align: 1.0 0.5;
rel1 { relative: 0.0 0.0; }
- rel2 { relative: 0.0 1.0; to_x: "right.padding"; }
+ rel2 { relative: 0.0 1.0; to_x: "pd.right"; }
}
- }
- group { "swipe.center.button"; scale;
- source: "button_dismiss";
- desc { "default";
- fixed: 1 1;
- align: 0.5 0.5;
+ desc { "contracted";
+ inherit: "default";
+ hid;
}
}
+ program {
+ name: "buttons,expand";
+ source: "ring";
+ signal: "buttons,expand";
+ action: STATE_SET "default";
+ target: "sw.btn.dismiss";
+ target: "sw.btn.snooze";
+ }
+ program {
+ name: "buttons,contract";
+ source: "ring";
+ signal: "buttons,contract";
+ action: STATE_SET "contracted";
+ target: "sw.btn.dismiss";
+ target: "sw.btn.snooze";
+ }
}
}
group { "button_dismiss";
parts {
- image { "ic.circle.line"; nomouse;
+ image { "ic.circle.line"; nomouse; scale;
desc { "default";
hid;
fixed: 1 1;
max: -1 -1;
}
}
- image { "ic.circle.fill"; nomouse;
+ image { "ic.circle.fill"; nomouse; scale;
desc { "default";
hid;
max: 180 180;
}
image { "bg"; scale;
desc { "default";
- fixed: 1 1;
- min: 180 180;
- max: 180 180;
align: 0.5 0.5;
color_class: "AO003";
image.normal: "alarm_btn_bg.png";
color_class: "AO003P";
}
}
- image { "ic.dismiss"; nomouse;
+ image { "ic.dismiss"; nomouse; scale;
desc { "default";
max: 80 80;
align: 0.5 0.5;
}
group { "button_snooze";
parts {
- image { "ic.circle.line"; nomouse;
+ image { "ic.circle.line"; nomouse; scale;
desc { "default";
hid;
fixed: 1 1;
max: -1 -1;
}
}
- image { "ic.circle.fill"; nomouse;
+ image { "ic.circle.fill"; nomouse; scale;
desc { "default";
hid;
max: 180 180;
vis;
}
}
- image { "bg"; scale;
+ image { "bg";
desc { "default";
- fixed: 1 1;
- min: 180 180;
- max: 180 180;
- align: 1.0 0.5;
+ align: 0.5 0.5;
color_class: "AO004";
image.normal: "alarm_btn_bg.png";
}
color_class: "AO004P";
}
}
- image { "ic.dismiss"; nomouse;
+ image { "ic.snooze"; nomouse; scale;
desc { "default";
max: 80 80;
align: 0.5 0.5;
#include "app.h"
#include "Clock.h"
#include "Controller/MainController.h"
+#include "Controller/RingController.h"
+#include "Common/Defines.h"
+
using namespace controller;
If this function returns false, the application is terminated */
DBG("app_create");
- MainController::GetInstance().Init();
return true;
}
{
DBG("app_control");
/* Handle the launch request. */
+ char *opData;
+
+ int ret = app_control_get_operation(app_control, &opData);
+ if (ret != APP_CONTROL_ERROR_NONE || opData == NULL) {
+ ERR("app_control_get_operation failed");
+ return;
+ }
+ DBG("Operation: %s", opData);
+
+ char *alarmID = NULL;
+
+ if (!strcmp(opData, APP_CONTROL_OPERATION_DEFAULT))
+ MainController::GetInstance().Init();
+ else if (!strcmp(opData, APP_CONTROL_OPERATION_ALARM)) {
+
+ char *alarmID = NULL;
+
+ ret = app_control_get_extra_data(app_control, APP_CONTROL_DATA_ALARM_ID, &alarmID);
+ if (ret != APP_CONTROL_ERROR_NONE) {
+ ERR("app_control_get_extra_data failed[%d]: %s", ret, get_error_message(ret));
+ free(opData);
+ return;
+ }
+
+ RingController::GetInstance().HandleAlarm(std::atoi(alarmID));
+ free(alarmID);
+
+ } else if (!strcmp(opData, APP_CONTROL_OPERATION_TIMEOUT))
+ RingController::GetInstance().HandleTimeout();
+
+ free(opData);
}
static void
event_callback.resume = app_resume;
event_callback.app_control = app_control;
+ elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+
ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, ui_app_low_battery, NULL);
ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, ui_app_low_memory, NULL);
ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, NULL);
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <app.h>
+
+#include "Controller/RingController.h"
+#include "Presenter/RingPresenter.h"
+#include "View/RingView.h"
+#include "Model/Ring.h"
+#include "Model/AlarmProvider.h"
+
+namespace controller {
+
+RingController &RingController::GetInstance()
+{
+ static RingController instance;
+ return instance;
+}
+
+
+void RingController::HandleAlarm(int alarmID)
+{
+ if (view_ || model_ || presenter_)
+ ShutDown();
+
+ DBG("Handle alarm with id %d", alarmID);
+ model::AlarmProvider *alarmProvider = model::AlarmProvider::GetInstance();
+ model::Alarm *alarm = alarmProvider->GetAlarmWithId(alarmID);
+
+ if (!alarm) {
+ ERR("Alarm not found");
+ return;
+ }
+
+ view_ = new view::RingView();
+ presenter_ = new presenter::RingPresenter(view_, alarm);
+}
+
+void RingController::HandleTimeout()
+{
+ if (view_ || model_ || presenter_)
+ ShutDown();
+
+ view_ = new view::RingView();
+ model_ = new model::Ring();
+ presenter_ = new presenter::RingPresenter(view_, model_);
+}
+
+void RingController::ShutDown()
+{
+ delete view_;
+ delete model_;
+ delete presenter_;
+
+ view_ = nullptr;
+ model_ = nullptr;
+ presenter_ = nullptr;
+}
+
+}
return NULL;
}
+ err = app_control_set_operation(ctrl, APP_CONTROL_OPERATION_ALARM);
+ if (err != APP_CONTROL_ERROR_NONE) {
+ ERR("app_control_set_operation failed: %s", get_error_message(err));
+ app_control_destroy(ctrl);
+ return NULL;
+ }
+
return ctrl;
}
Alarm* AlarmProviderFile::GetAlarmWithId(AlarmId id)
{
- return nullptr;
+ auto it = std::find(alarms.begin(), alarms.end(), id);
+
+ if (it == alarms.end())
+ return nullptr;
+
+ return &(*it);
}
void AlarmProviderFile::Serialize(utils::IWriter &w) const
void StopWatch::ClearList()
{
for (Lap *item: laps_)
- delete(item);
+ delete item;
laps_.clear();
}
* limitations under the License.
*/
+#include <app_alarm.h>
+
#include "Model/Timer.h"
+#include "Common/Defines.h"
#include "log.h"
-using namespace model;
+namespace model {
-Timer::Timer() : hour_(0), minute_(0), second_(0)
+Timer::Timer() : hour_(0), minute_(0), second_(0), alarm_id_(0)
{
}
return time - GetTime();
}
+
+app_control_h Timer::CreateAppControl()
+{
+ app_control_h appControl;
+
+ int ret = app_control_create(&appControl);
+ if (ret != APP_CONTROL_ERROR_NONE) {
+ ERR("app_control_create failed");
+ return NULL;
+ }
+
+ ret = app_control_set_app_id(appControl, PACKAGE);
+ if (ret != APP_CONTROL_ERROR_NONE) {
+ ERR("app_control_set_app_id failed");
+ app_control_destroy(appControl);
+ return NULL;
+ }
+
+ ret = app_control_set_operation(appControl, APP_CONTROL_OPERATION_TIMEOUT);
+ if (ret != APP_CONTROL_ERROR_NONE) {
+ ERR("app_control_set_operation failed");
+ app_control_destroy(appControl);
+ return NULL;
+ }
+
+ return appControl;
+}
+
+bool Timer::ActivateAlarm(int delay)
+{
+ DBG("Activate alarm with delay: %d", delay);
+
+ if (delay < 0) {
+ ERR("Invalid delay value");
+ return false;
+ }
+
+ app_control_h appControl = CreateAppControl();
+ if (!appControl) {
+ ERR("appControl == NULL");
+ return false;
+ }
+
+ int ret = alarm_schedule_once_after_delay(appControl, delay, &alarm_id_);
+ if (ret != ALARM_ERROR_NONE) {
+ app_control_destroy(appControl);
+ ERR("alarm_schedule_after_delay failed[%d]: %s", ret, get_error_message(ret));
+ return false;
+ }
+
+ app_control_destroy(appControl);
+
+ return true;
+}
+
+bool Timer::DeactivateAlarm()
+{
+ int ret = alarm_cancel(alarm_id_);
+ if (ret != ALARM_ERROR_NONE) {
+ ERR("alarm_cancel failed[%d]: %s", ret, get_error_message(ret));
+ return false;
+ }
+
+ alarm_id_ = 0;
+
+ return true;
+}
+
+} //namespace model
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Presenter/RingPresenter.h"
+#include "Utils/Time.h"
+#include "Controller/RingController.h"
+
+namespace presenter {
+
+RingPresenter::RingPresenter(view::RingView *view, model::Ring *model)
+ : view_(view), model_(model)
+{
+ view_->SetTitle("Time is up");
+ view_->ShowCounter();
+
+ animator_.RegisterSignal(std::bind(&RingPresenter::TimeUpdateRequest, this));
+
+ view_->RegisterSignal(std::bind(&RingPresenter::DismissButtonClicked, this),
+ view::RingSignal::BUTTON_DISMISS_CLICKED);
+ view_->RegisterSignal(std::bind(&RingPresenter::SnoozeButtonClicked, this),
+ view::RingSignal::BUTTON_SNOOZE_CLICKED);
+
+ model_->Run();
+ animator_.Start();
+ view_->EnableSnooze(false);
+}
+
+RingPresenter::RingPresenter(view::RingView *view, model::Alarm *alarm)
+ : view_(view), model_(NULL), alarm_(alarm)
+{
+
+ view_->RegisterSignal(std::bind(&RingPresenter::DismissButtonClicked, this),
+ view::RingSignal::BUTTON_DISMISS_CLICKED);
+ view_->RegisterSignal(std::bind(&RingPresenter::SnoozeButtonClicked, this),
+ view::RingSignal::BUTTON_SNOOZE_CLICKED);
+
+ utils::Time time = alarm->GetTime();
+
+ view->SetTitle(alarm->GetName().c_str());
+ view->SetTimeLabel(time.Meridiem().c_str(), time.GetFormattedTime("HH:mm").c_str(), time.GetDate().c_str());
+
+ if (alarm->IsSnoozeEnabled())
+ view_->EnableSnooze(true);
+ else
+ view_->EnableSnooze(false);
+}
+
+RingPresenter::~RingPresenter()
+{
+}
+
+void RingPresenter::TimeUpdateRequest()
+{
+ view_->DisplayTime(model_->GetHour(), model_->GetMinute(), model_->GetSecond());
+}
+
+void RingPresenter::DismissButtonClicked()
+{
+ animator_.Remove();
+ controller::RingController::GetInstance().ShutDown();
+}
+
+void RingPresenter::SnoozeButtonClicked()
+{
+ alarm_->Snooze();
+ animator_.Remove();
+ controller::RingController::GetInstance().ShutDown();
+}
+
+} //namespace presenter
#include "Presenter/TimerPresenter.h"
#include "log.h"
-using namespace presenter;
+namespace presenter {
+
using namespace std::chrono;
TimerPresenter::TimerPresenter(view::TimerView *view, model::Timer *model)
TimerPresenter::~TimerPresenter()
{
-
+ animator_.Remove();
}
void TimerPresenter::TimeUpdateRequest()
view_->DisplayTime(h, m, s);
if (!h && !m && !s)
- view_->ShowTimeIsUpAlert();
+ TimeIsUp();
}
void TimerPresenter::StartButtonClicked()
int hour = 0, minute = 0, second = 0;
view_->GetTime(&hour, &minute, &second);
+
+ DBG("hour: %d min: %d src: %d", hour, minute, second);
+
model_->SetTime(hour, minute, second);
if (!model_->Run())
view_->ShowRunningMenu();
animator_.Start();
+
+ int timeLeft = model_->GetRemainingTime().count();
+ model_->ActivateAlarm(timeLeft);
}
void TimerPresenter::PauseButtonClicked()
model_->Stop();
animator_.Stop();
view_->ShowPausedMenu();
+ model_->DeactivateAlarm();
}
void TimerPresenter::ResumeButtonClicked()
model_->Resume();
animator_.Resume();
view_->ShowRunningMenu();
+
+ int timeLeft = model_->GetRemainingTime().count();
+ model_->ActivateAlarm(timeLeft);
}
void TimerPresenter::ResetButtonClicked()
model_->Reset();
animator_.Stop();
view_->ShowStartupMenu();
+ model_->DeactivateAlarm();
+}
+
+void TimerPresenter::TimeIsUp()
+{
+ model_->Stop();
+ model_->Reset();
+ animator_.Stop();
+ view_->ShowStartupMenu();
}
+
+} //namespace presenter
#include "Utils/Time.h"
#include <utils_i18n.h>
#include <cstring>
+#include <ctime>
+#include <Elementary.h>
using namespace utils;
{
return 60;
}
+
+std::string Time::GetDate() const
+{
+ time_t now;
+ time(&now);
+
+ struct timeval *day;
+
+ struct tm *timeInfo = localtime(&now);
+
+ char buffer[128] = {0, };
+
+ std::strftime(buffer, sizeof(buffer)/sizeof(buffer[0]), "%a, %e %B", timeInfo);
+
+ return std::string(buffer);
+}
#include "View/EditAlarmView.h"
#include "View/MainView.h"
+#include "View/RingView.h"
+
#include "Clock.h"
#include "Utils/Utils.h"
#include "log.h"
static void WinDeleteRequestCb(void *data, Evas_Object *obj, void *event_info)
{
- ui_app_exit();
+ elm_win_lower(obj);
}
static Eina_Bool naviframe_pop_cb(void *data, Elm_Object_Item *it)
{
- ui_app_exit();
- return EINA_FALSE;
+ Evas_Object *win = static_cast<Evas_Object *>(data);
+
+ elm_win_lower(win);
}
void toolbar_it_cb (void *data, Evas_Object *obj, void *event_info)
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <efl_util.h>
+
+#include "View/RingView.h"
+#include "View/MainView.h"
+#include "Utils/Utils.h"
+
+#include "log.h"
+
+namespace view {
+
+const char *RingView::EDJE_FILE = "edje/ring.edj";
+const char *RingView::GROUP = "main";
+
+RingView::RingView() : win_(NULL), layout_(NULL), counter_(NULL)
+{
+ win_ = elm_win_add(NULL, "Ring", ELM_WIN_NOTIFICATION);
+ if (!win_) {
+ ERR("elm_win_add failed");
+ return;
+ }
+
+ int ret = efl_util_set_notification_window_level(win_, EFL_UTIL_NOTIFICATION_LEVEL_HIGH);
+ if (ret != EFL_UTIL_ERROR_NONE) {
+ ERR("efl_util_set_notification_window_level failed");
+ evas_object_del(win_);
+ return;
+ }
+
+ ret = efl_util_set_window_opaque_state(win_, 1);
+ if (ret != EFL_UTIL_ERROR_NONE) {
+ ERR("efl_util_set_window_opaque_state failed");
+ evas_object_del(win_);
+ return;
+ }
+
+ elm_win_indicator_mode_set(win_, ELM_WIN_INDICATOR_SHOW);
+ elm_win_indicator_opacity_set(win_, ELM_WIN_INDICATOR_OPAQUE);
+ elm_win_autodel_set(win_, EINA_FALSE);
+
+ Evas_Object *conformant = elm_conformant_add(win_);
+ elm_win_resize_object_add(win_, conformant);
+
+ layout_ = elm_layout_add(conformant);
+ if (!layout_) {
+ ERR("elm_layout_add failed");
+ evas_object_del(win_);
+ return;
+ }
+
+ if (!elm_layout_file_set(layout_, utils::Utils::GetAppResourcePath(
+ utils::Utils::APP_DIR_RESOURCE, EDJE_FILE), GROUP)) {
+ ERR("elm_layout_file_set failed");
+ evas_object_del(layout_);
+ evas_object_del(win_);
+ return;
+ }
+
+ evas_object_size_hint_align_set(layout_, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(layout_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+ elm_object_content_set(conformant, layout_);
+
+ evas_object_show(layout_);
+ evas_object_show(conformant);
+ evas_object_show(win_);
+
+ elm_object_signal_callback_add(layout_, "button,swipe,accept", "sw.swipe.area:sw.btn.dismiss:button", DismissCb, this);
+ elm_object_signal_callback_add(layout_, "button,swipe,accept", "sw.swipe.area:sw.btn.snooze:button", SnoozeCb, this);
+}
+
+RingView::~RingView()
+{
+ evas_object_del(win_);
+
+ if (counter_) {
+ delete counter_;
+ counter_ = nullptr;
+ }
+}
+Evas_Object *RingView::GetEvasObject()
+{
+ return layout_;
+}
+
+void RingView::SetTitle(const char *title)
+{
+ elm_object_part_text_set(layout_, "txt.title", title);
+}
+
+void RingView::ShowCounter()
+{
+ if (!counter_)
+ counter_ = new view::CounterView(*this, view::CounterType::COUNTER_TYPE_TIMER);
+
+ SetMainContent(counter_->GetEvasObject());
+
+ elm_object_signal_emit(layout_, "set,ring,counter,view", "ring");
+}
+
+void RingView::DisplayTime(int hour, int min, int sec)
+{
+ if (!counter_)
+ return;
+
+ counter_->DisplayTime(hour, min, sec);
+}
+
+void RingView::SetTimeLabel(const char *ampm, const char *hour, const char *date)
+{
+ Evas_Object *content = elm_layout_add(layout_);
+ if (!content)
+ return;
+
+ if (!elm_layout_file_set(content, utils::Utils::GetAppResourcePath(
+ utils::Utils::APP_DIR_RESOURCE, EDJE_FILE), "alarm_info")) {
+ ERR("elm_layout_file_set failed");
+ return;
+ }
+
+ elm_object_part_text_set(content, "txt.ampm", ampm);
+ elm_object_part_text_set(content, "txt.time", hour);
+ elm_object_part_text_set(content, "txt.date", date);
+
+ evas_object_size_hint_weight_set(content, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(content, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+ evas_object_show(content);
+
+ SetMainContent(content);
+
+ elm_object_signal_emit(layout_, "set,ring,alarm,view", "ring");
+}
+
+void RingView::EnableSnooze(bool enabled)
+{
+ if (enabled)
+ elm_object_signal_emit(layout_, "sw.swipe.area:buttons,expand", "ring");
+ else
+ elm_object_signal_emit(layout_, "sw.swipe.area:buttons,contract", "ring");
+}
+
+void RingView::SetMainContent(Evas_Object *ly)
+{
+ Evas_Object *content = elm_object_part_content_unset(layout_, "sw.content");
+ if (content)
+ evas_object_del(content);
+
+ elm_object_part_content_set(layout_, "sw.content", ly);
+}
+
+void RingView::DismissCb(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+ RingView *object = static_cast<RingView *>(data);
+
+ object->EmitSignal(view::RingSignal::BUTTON_DISMISS_CLICKED);
+ evas_object_del(object->win_);
+}
+
+void RingView::SnoozeCb(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+ RingView *object = static_cast<RingView *>(data);
+
+ object->EmitSignal(view::RingSignal::BUTTON_SNOOZE_CLICKED);
+ evas_object_del(object->win_);
+}
+
+void RingView::RegisterSignal(std::function<void(void)>func, RingSignal type)
+{
+ signals_.at((int)type) = func;
+}
+
+void RingView::EmitSignal(RingSignal type)
+{
+ if (signals_.at((int)type) != nullptr)
+ signals_.at((int)type)();
+}
+
+} //namespace view
StopWatchView::~StopWatchView()
{
- delete(main_counter_);
- delete(lap_counter_);
+ delete main_counter_;
+ delete lap_counter_;
evas_object_del(layout_);
}
TimerView::~TimerView()
{
- delete(counter_);
+ delete counter_;
}
Evas_Object *TimerView::GetEvasObject()
elm_object_focus_set(entry, EINA_FALSE);
}
-void TimerView::ShowTimeIsUpAlert()
-{
- if (alarmWin)
- return;
-
- alarmWin = elm_win_add(NULL, "Alarm", ELM_WIN_NOTIFICATION);
- if (!alarmWin) {
- ERR("Could not create alarm window");
- return;
- }
-
- int ret = efl_util_set_notification_window_level(alarmWin, EFL_UTIL_NOTIFICATION_LEVEL_HIGH);
- if (ret != EFL_UTIL_ERROR_NONE) {
- ERR("efl_util_set_notification_window_level failed");
- return;
- }
-
- ret = efl_util_set_window_opaque_state(alarmWin, 1);
- if (ret != EFL_UTIL_ERROR_NONE) {
- ERR("efl_util_set_window_opaque_state failed");
- return;
- }
-
- elm_win_indicator_mode_set(alarmWin, ELM_WIN_INDICATOR_SHOW);
- elm_win_indicator_opacity_set(alarmWin, ELM_WIN_INDICATOR_OPAQUE);
- elm_win_autodel_set(alarmWin, EINA_FALSE);
-
- Evas_Object *alarmLy = elm_layout_add(alarmWin);
- if (!alarmLy) {
- ERR("Could not create alarm layout");
- return;
- }
-
- if (!elm_layout_file_set(alarmLy, utils::Utils::GetAppResourcePath(
- utils::Utils::APP_DIR_RESOURCE, "edje/ring.edj"), "main")) {
- ERR("Could not load ring edje file");
- return;
- }
-
- evas_object_size_hint_align_set(alarmLy, EVAS_HINT_FILL, EVAS_HINT_FILL);
- evas_object_size_hint_weight_set(alarmLy, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-
- elm_win_resize_object_add(alarmWin, alarmLy);
-
- elm_object_part_text_set(alarmLy, "txt.title", "Time is up");
-
- evas_object_show(alarmLy);
- evas_object_show(alarmWin);
-
- elm_object_signal_callback_add(alarmLy, "button,swipe,accept", "sw.swipe.area:swipe.center.button:button", AlarmDismiss, this);
-}
-
void TimerView::ShowStartupMenu(void)
{
if (!layout_)