#ifndef _CLOCK_MAIN_CONTROLLER_H_
#define _CLOCK_MAIN_CONTROLLER_H_
+#include "Utils/EventBus.h"
+
/**
* @file MainController.h
*/
/**
* @brief Creates new "Edit/Create" alarm page.
*/
- void CreateNewAlarmPage();
+ void CreateNewAlarmPage(utils::Event *e);
+
+ /**
+ * @brief Creates new "Delete" alarm page.
+ */
+ void CreateNewDeleteAlarmsPage(utils::Event *e);
};
}
std::vector<std::reference_wrapper<model::Alarm>> GetAlarms();
model::Alarm* GetAlarmWithId(model::AlarmId id);
void Add(model::Alarm& alarm);
- void Remove(model::Alarm& alarm);
+ void Remove(std::reference_wrapper<model::Alarm> alarm);
AlarmProviderFile(utils::IReader &r);
~AlarmProviderFile();
void Serialize(utils::IWriter &w) const;
private:
static int custom_type_;
};
+ class AlarmDeleteRequestEvent : public utils::Event {
+ public:
+ AlarmDeleteRequestEvent();
+ static int EventType();
+ private:
+ static int custom_type_;
+ };
} /* model */
#endif
virtual std::vector<std::reference_wrapper<Alarm>> GetAlarms() = 0;
virtual Alarm *GetAlarmWithId(AlarmId id) = 0;
virtual void Add(Alarm& alarm) = 0;
- virtual void Remove(Alarm& alarm) = 0;
+ virtual void Remove(std::reference_wrapper<Alarm> alarm) = 0;
protected:
AlarmProvider() {}
virtual ~AlarmProvider() {}
class AlarmAddedEvent : public utils::Event {
public:
AlarmAddedEvent(Alarm &alarm);
- const Alarm& GetAlarm() const { return alarm_; }
+ Alarm& GetAlarm() { return alarm_; }
static int EventType();
private:
Alarm &alarm_;
class AlarmRemovedEvent : public utils::Event {
public:
AlarmRemovedEvent(Alarm &alarm);
- const Alarm& GetAlarm() const { return alarm_; }
+ Alarm& GetAlarm() { return alarm_; }
static int EventType();
private:
Alarm &alarm_;
#include "Model/AlarmProvider.h"
#include "Model/AlarmProviderEvent.h"
+#include <map>
+
namespace presenter {
class AlarmPresenter {
public:
void OnAddButtonClicked();
void OnItemActiveStatusChanged(int idx);
void OnAlarmAddedEvent(utils::Event *e);
+ void OnAlarmRemovedEvent(utils::Event *e);
+ void OnDeleteItemClicked();
+ std::map<int, std::reference_wrapper<model::Alarm>> alarms_;
};
} /* presenters */
--- /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_DELETE_ALARM_H_
+#define _CLOCK_PRESENTER_DELETE_ALARM_H_
+
+#include "Model/AlarmProvider.h"
+#include "View/DeleteAlarmView.h"
+
+#include <map>
+
+namespace presenter {
+ class DeleteAlarmPresenter {
+ public:
+ DeleteAlarmPresenter(view::DeleteAlarmView *view, model::AlarmProvider *model);
+ private:
+ view::DeleteAlarmView *view_;
+ model::AlarmProvider *model_;
+ void OnDeleteButtonClicked();
+ void OnCancelButtonClicked();
+ std::map<int, std::reference_wrapper<model::Alarm>> alarms_;
+ };
+} /* presenter */
+
+#endif
AlarmView();
void Clear();
int ItemAppend(utils::Time time, const char *name,
- const model::WeekFlags flags, bool active);
+ const model::WeekFlags flags, bool active);
void RemoveItem(int idx);
void ItemUpdate(int idx, utils::Time time, const char *name,
const model::WeekFlags flags, bool active);
void SetItemToggleCallback(ToggleCallback func);
void SetItemSelectCallback(SelectCallback func);;
void SetButtonClickedCallback(ButtonClickedCallback func);
+ void SetDeleteItemClickedCallback(ButtonClickedCallback func) { onDeleteClicked_ = func;}
Evas_Object *GetEvasObject();
private:
static Elm_Genlist_Item_Class alarm_itc;
static void ItemClicked(void *data, Evas_Object *obj, void *info);
static void ItemRealized(void *data, Evas_Object *obj, void *info);
static void ButtonClicked(void *data, Evas_Object *obj, void *info);
- Evas_Object *genlist;
- Evas_Object *content;
- SelectCallback onSelected;
- ToggleCallback onToggled;
- ButtonClickedCallback onClicked;;
+ static void MoreButtonClicked(void *data, Evas_Object *obj, void *info);
+ static void DismissPopupCallback(void *data, Evas_Object *obj, void *info);
+ static void PopupDeleteItemCallback(void *data, Evas_Object *obj, void *info);
+
+ Evas_Object *genlist_;
+ Evas_Object *content_;
+ Evas_Object *popup_;
+ SelectCallback onSelected_;
+ ToggleCallback onToggled_;
+ ButtonClickedCallback onClicked_;
+ ButtonClickedCallback onDeleteClicked_;
+ void ShowDeletePopup();
};
}
--- /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_DELETE_ALARM_VIEW_
+#define _CLOCK_DELETE_ALARM_VIEW_
+
+#include "View/PageView.h"
+#include "Model/WeekFlags.h"
+#include "Utils/Time.h"
+
+#include <vector>
+
+namespace view {
+ class DeleteAlarmView : public PageView {
+ public:
+ typedef std::function<void(void)> ButtonClickedCallback;
+
+ DeleteAlarmView();
+
+ void RegisterCancelButtonClickedCallback(ButtonClickedCallback cb) { onCancelButtonClicked_ = cb; }
+ void RegisterDeleteButtonClickedCallback(ButtonClickedCallback cb) { onDeleteButtonClicked_ = cb; }
+ Evas_Object *GetEvasObject() { return content_; }
+
+ int ItemAppend(utils::Time time, const char *name,
+ const model::WeekFlags flags, bool active);
+ std::vector<int> GetSelectedItems() const;
+ protected:
+ virtual void CreateContent();
+ virtual void DestroyContent();
+ private:
+ Evas_Object *content_;
+ Evas_Object *left_btn_;
+ Evas_Object *right_btn_;
+
+ ButtonClickedCallback onDeleteButtonClicked_;
+ ButtonClickedCallback onCancelButtonClicked_;
+
+ void SelectAllStateSet(bool value);
+ void UpdateTitle(void);
+
+ bool all_selected_;
+ Evas_Object *all_selected_check_;
+
+ // EFL callbacks
+ static void OnCancelButtonClickedCb(void *data, Evas_Object *obj, void *event);
+ static void OnDeleteButtonClickedCb(void *data, Evas_Object *obj, void *event);
+ static void ItemRealized(void *data, Evas_Object *obj, void *event);
+ static void ItemSelectToggle(void *data, Evas_Object *obj, void *event);
+ static void ItemSelected(void *data, Evas_Object *obj, void *event);
+ static void ItemSelectAllClicked(void *data, Evas_Object *obj, void *event);
+
+ void CreateSelectAllItem();
+ };
+} /* view */
+
+#endif
target: "time";
}
}
+ group { name: "elm/genlist/item/select_all/default";
+ styles {
+ style { name: "font_normal";
+ base: "font=Tizen:style=Light color=#000000FF font_size=40 ellipsis=1.0";
+ }
+ }
+ data.item: "texts" "elm.text";
+ data.item: "contents" "sw.check";
+ data.item: "banded_bg_area" "elm.swallow.bg";
+ parts {
+ spacer { "base"; scale;
+ desc { "default";
+ min: 0 120;
+ }
+ }
+ swallow { "elm.swallow.bg";
+ desc { "default";
+ rel1.to: "base";
+ rel2.to: "base";
+ }
+ }
+ spacer { "padding.left"; scale;
+ desc { "default";
+ fixed: 1 0;
+ min: 32 0;
+ max: 32 -1;
+ align: 0.0 0.5;
+ rel1.to: "base";
+ rel2.to: "base";
+ }
+ }
+ spacer { "padding.right"; scale;
+ desc { "default";
+ fixed: 1 0;
+ min: 32 0;
+ max: 32 -1;
+ align: 1.0 0.5;
+ rel1.to: "base";
+ rel2.to: "base";
+ }
+ }
+ textblock { "elm.text"; scale;
+ desc { "default";
+ fixed: 0 1;
+ min: 0 93;
+ max: -1 93;
+ rel1 { relative: 1.0 0.0; to_x: "padding.left"; to_y: "base"; }
+ rel2.to: "base";
+ text.style: "font_normal";
+ }
+ }
+ swallow { "sw.check"; scale;
+ desc { "default";
+ fixed: 1 1;
+ align: 1.0 0.5;
+ min: 80 80;
+ max: 80 80;
+ rel1.to: "base";
+ rel2 { relative: 0.0 1.0; to: "padding.right"; }
+ }
+ }
+ }
+ }
}
#include "View/EditAlarmView.h"
#include "Presenter/EditAlarmPresenter.h"
#include "Model/AlarmEvent.h"
+#include "View/DeleteAlarmView.h"
+#include "Presenter/DeleteAlarmPresenter.h"
using namespace controller;
using namespace view;
using namespace utils;
using namespace presenter;
using namespace model;
+using std::placeholders::_1;
MainController &MainController::GetInstance()
{
MainView::GetInstance();
MainView::GetInstance().CreateContent();
- EventBus::RegisterHandler(AlarmCreateRequestEvent::EventType(), std::bind(&MainController::CreateNewAlarmPage, this));
+ EventBus::RegisterHandler(AlarmCreateRequestEvent::EventType(),
+ std::bind(&MainController::CreateNewAlarmPage, this, _1));
+ EventBus::RegisterHandler(AlarmDeleteRequestEvent::EventType(),
+ std::bind(&MainController::CreateNewDeleteAlarmsPage, this, _1));
return 0;
}
void MainController::Deinit()
{
- EventBus::DeregisterHandler(AlarmCreateRequestEvent::EventType(), std::bind(&MainController::CreateNewAlarmPage, this));
+ EventBus::DeregisterHandler(AlarmCreateRequestEvent::EventType(),
+ std::bind(&MainController::CreateNewAlarmPage, this, _1));
+ EventBus::DeregisterHandler(AlarmDeleteRequestEvent::EventType(),
+ std::bind(&MainController::CreateNewDeleteAlarmsPage, this, _1));
}
-void MainController::CreateNewAlarmPage()
+void MainController::CreateNewAlarmPage(Event *e)
{
static EditAlarmView *view;
static EditAlarmPresenter *presenter;
view = new EditAlarmView();
presenter = new EditAlarmPresenter(nullptr, *view);
}
+
+void MainController::CreateNewDeleteAlarmsPage(Event *e)
+{
+ static DeleteAlarmView *view;
+ static DeleteAlarmPresenter *presenter;
+
+ if (view) delete view;
+ if (presenter) delete presenter;
+
+ view = new DeleteAlarmView();
+ presenter = new DeleteAlarmPresenter(view, AlarmProvider::GetInstance());
+}
using namespace utils;
int AlarmCreateRequestEvent::custom_type_;
+int AlarmDeleteRequestEvent::custom_type_;
AlarmCreateRequestEvent::AlarmCreateRequestEvent() :
Event(AlarmCreateRequestEvent::EventType())
}
return custom_type_;
}
+
+AlarmDeleteRequestEvent::AlarmDeleteRequestEvent() :
+ Event(AlarmDeleteRequestEvent::EventType())
+{
+}
+
+int AlarmDeleteRequestEvent::EventType()
+{
+ if (custom_type_ == 0) {
+ custom_type_ = EventBus::RegisterNewEventType();
+ }
+ return custom_type_;
+}
}
AlarmRemovedEvent::AlarmRemovedEvent(Alarm &alarm) :
- Event(AlarmAddedEvent::EventType()), alarm_(alarm)
+ Event(AlarmRemovedEvent::EventType()), alarm_(alarm)
{
}
alarms.push_back(alarm);
EventBus::FireEvent(new AlarmAddedEvent(alarm));
}
+ Sync();
}
-void AlarmProviderFile::Remove(model::Alarm& alarm)
+void AlarmProviderFile::Remove(std::reference_wrapper<Alarm> alarm)
{
- auto it = std::find(alarms.begin(), alarms.end(), alarm);
+ auto it = std::find(alarms.begin(), alarms.end(), alarm.get());
if (it != alarms.end()) {
- alarms.erase(it);
EventBus::FireEvent(new AlarmRemovedEvent(alarm));
+ alarm.get().Deactivate();
+ alarms.erase(it);
}
+ Sync();
}
AlarmProviderFile::AlarmProviderFile(IReader &r)
AlarmPresenter::AlarmPresenter(AlarmView *v, AlarmProvider *m) : view(v), model(m)
{
view->SetButtonClickedCallback(std::bind(&AlarmPresenter::OnAddButtonClicked, this));
+ view->SetDeleteItemClickedCallback(std::bind(&AlarmPresenter::OnDeleteItemClicked, this));
EventBus::RegisterHandler(AlarmAddedEvent::EventType(),
std::bind(&AlarmPresenter::OnAlarmAddedEvent, this, _1));
+ EventBus::RegisterHandler(AlarmRemovedEvent::EventType(),
+ std::bind(&AlarmPresenter::OnAlarmRemovedEvent, this, _1));
ShowAll();
}
{
EventBus::DeregisterHandler(AlarmAddedEvent::EventType(),
std::bind(&AlarmPresenter::OnAlarmAddedEvent, this, _1));
+ EventBus::DeregisterHandler(AlarmRemovedEvent::EventType(),
+ std::bind(&AlarmPresenter::OnAlarmRemovedEvent, this, _1));
}
void AlarmPresenter::ShowAll()
view->Clear();
for (auto a: alarms) {
- view->ItemAppend(
+ int id = view->ItemAppend(
a.get().GetTime(),
a.get().GetName().c_str(),
a.get().GetWeekFlags(),
a.get().IsActivated());
+ alarms_.insert(std::map<int, std::reference_wrapper<Alarm>>::value_type (id, std::reference_wrapper<Alarm>(a)));
}
}
AlarmAddedEvent *ev = dynamic_cast<AlarmAddedEvent*>(e);
- view->ItemAppend(
+ int id = view->ItemAppend(
ev->GetAlarm().GetTime(),
ev->GetAlarm().GetName().c_str(),
ev->GetAlarm().GetWeekFlags(),
ev->GetAlarm().IsActivated());
+ alarms_.insert(std::map<int, std::reference_wrapper<Alarm>>::value_type (id, std::reference_wrapper<Alarm>(ev->GetAlarm())));
+}
+
+void AlarmPresenter::OnDeleteItemClicked()
+{
+ EventBus::FireEvent(new AlarmDeleteRequestEvent());
+}
+
+void AlarmPresenter::OnAlarmRemovedEvent(Event *e)
+{
+ if (!e || (e->GetType() != AlarmRemovedEvent::EventType()))
+ return;
+
+ AlarmRemovedEvent *ev = dynamic_cast<AlarmRemovedEvent*>(e);
+ for (auto it = alarms_.begin(); it != alarms_.end(); ++it) {
+ if (ev->GetAlarm() == it->second.get()) {
+ view->RemoveItem(it->first);
+ alarms_.erase(it);
+ break;
+ }
+ }
}
--- /dev/null
+#include "Presenter/DeleteAlarmPresenter.h"
+
+using namespace model;
+using namespace view;
+
+namespace presenter {
+DeleteAlarmPresenter::DeleteAlarmPresenter(DeleteAlarmView *view, AlarmProvider *model)
+ : view_(view), model_(model)
+{
+ view->RegisterCancelButtonClickedCallback(
+ std::bind(&DeleteAlarmPresenter::OnCancelButtonClicked, this)
+ );
+ view->RegisterDeleteButtonClickedCallback(
+ std::bind(&DeleteAlarmPresenter::OnDeleteButtonClicked, this)
+ );
+
+ std::vector<std::reference_wrapper<Alarm>> alarms = model_->GetAlarms();
+
+ for (auto a: alarms) {
+ int id = view_->ItemAppend(
+ a.get().GetTime(),
+ a.get().GetName().c_str(),
+ a.get().GetWeekFlags(),
+ a.get().IsActivated());
+ alarms_.insert(std::map<int, std::reference_wrapper<Alarm>>::value_type (id, std::reference_wrapper<Alarm>(a)));
+ }
+}
+
+void DeleteAlarmPresenter::OnDeleteButtonClicked()
+{
+ std::vector<int> deleted = view_->GetSelectedItems();
+
+ for (auto idx: deleted) {
+ model_->Remove(alarms_.find(idx)->second);
+ }
+ view_->PopPage();
+}
+
+void DeleteAlarmPresenter::OnCancelButtonClicked()
+{
+ view_->PopPage();
+}
+
+}
#include "Utils/EventBus.h"
#include <algorithm>
+#include "log.h"
+
using namespace utils;
int EventBus::RegisterNewEventType()
void EventBus::FireEvent(Event *event)
{
EventBus &bus = GetInstance();
+ DBG("Fire %d event", event->GetType());
for (auto func: bus.callbacks_[event->GetType()]) {
func(event);
}
AlarmView::AlarmView()
{
/* Base Layout */
- content = elm_layout_add(MainView::GetInstance().GetEvasObject());
- evas_object_size_hint_weight_set(content, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- elm_layout_theme_set(content, "layout", "application", "default");
- evas_object_show(content);
+ content_ = elm_layout_add(MainView::GetInstance().GetEvasObject());
+ evas_object_size_hint_weight_set(content_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ elm_layout_theme_set(content_, "layout", "application", "default");
+ evas_object_show(content_);
/* Genlist */
- genlist = elm_genlist_add(content);
- elm_genlist_homogeneous_set(genlist, EINA_TRUE);
- evas_object_size_hint_expand_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
- evas_object_smart_callback_add(genlist, "realized", AlarmView::ItemRealized, this);
- evas_object_show(genlist);
+ genlist_ = elm_genlist_add(content_);
+ elm_genlist_homogeneous_set(genlist_, EINA_TRUE);
+ evas_object_size_hint_expand_set(genlist_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(genlist_, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_smart_callback_add(genlist_, "realized", AlarmView::ItemRealized, this);
+ evas_object_show(genlist_);
- elm_object_content_set(content, genlist);
+ elm_object_content_set(content_, genlist_);
/* Floating Button */
- Evas_Object *fb = eext_floatingbutton_add(content);
- elm_object_part_content_set(content, "elm.swallow.floatingbutton", fb);
+ Evas_Object *fb = eext_floatingbutton_add(content_);
+ elm_object_part_content_set(content_, "elm.swallow.floatingbutton", fb);
/* Floating Button 1 */
Evas_Object *btn = elm_button_add(fb);
elm_object_part_content_set(fb, "button1", btn);
elm_theme_extension_add(NULL, Utils::GetAppResourcePath(Utils::APP_DIR_RESOURCE, "edje/alarm.edj"));
+
+ eext_object_event_callback_add(content_, EEXT_CALLBACK_MORE,
+ AlarmView::MoreButtonClicked, this);
+}
+
+void AlarmView::MoreButtonClicked(void *data, Evas_Object *obj, void *info)
+{
+ AlarmView *view = static_cast<AlarmView*>(data);
+
+ DBG("More button clicked");
+ view->ShowDeletePopup();
}
void AlarmView::Clear()
{
- elm_genlist_clear(genlist);
+ elm_genlist_clear(genlist_);
}
int AlarmView::ItemAppend(Time time, const char *name, const WeekFlags flags, bool active)
data->active = active;
data->time = time;
- data->it = elm_genlist_item_append(genlist,
+ data->it = elm_genlist_item_append(genlist_,
&alarm_itc,
data,
NULL,
ELM_GENLIST_ITEM_NONE,
NULL, NULL);
- return elm_genlist_item_index_get(data->it);
+ return (uintptr_t)data->it;
}
void AlarmView::ItemUpdate(int idx, Time time, const char *name,
const WeekFlags flags, bool active)
{
- Elm_Object_Item *it = elm_genlist_nth_item_get(genlist, idx);
+ Elm_Object_Item *it = (Elm_Object_Item*)idx;
if (!it) return;
ItemData *data = static_cast<ItemData*>(elm_object_item_data_get(it));
void AlarmView::RemoveItem(int idx)
{
- //Elm_Object_Item *it = elm_genlist_item_nth_get(idx);
- //if (it) elm_object_item_del(it);
+ Elm_Object_Item *it = (Elm_Object_Item*)idx;
+ if (it) elm_object_item_del(it);
}
void AlarmView::SetItemToggleCallback(ToggleCallback func)
{
- onToggled = std::move(func);
+ onToggled_ = std::move(func);
}
void AlarmView::SetItemSelectCallback(SelectCallback func)
{
- onSelected = std::move(func);
+ onSelected_ = std::move(func);
}
void AlarmView::SetButtonClickedCallback(ButtonClickedCallback func)
{
- onClicked = std::move(func);
+ onClicked_ = std::move(func);
}
Evas_Object *AlarmView::GetEvasObject()
{
- return content;
+ return content_;
}
void AlarmView::ButtonClicked(void *data, Evas_Object *obj, void *event_info)
{
AlarmView *view = static_cast<AlarmView*>(data);
- if (view->onClicked) view->onClicked();
+ if (view->onClicked_) view->onClicked_();
+}
+
+void AlarmView::DismissPopupCallback(void *data, Evas_Object *obj, void *event_info)
+{
+ Evas_Object *popup = static_cast<Evas_Object*>(data);
+ evas_object_del(popup);
+}
+
+void AlarmView::PopupDeleteItemCallback(void *data, Evas_Object *obj, void *event_info)
+{
+ AlarmView *view = static_cast<AlarmView*>(data);
+ if (view->onDeleteClicked_) view->onDeleteClicked_();
+ evas_object_del(view->popup_);
+}
+
+void AlarmView::ShowDeletePopup()
+{
+ popup_ = elm_popup_add(elm_object_top_widget_get(content_));
+ elm_popup_align_set(popup_, ELM_NOTIFY_ALIGN_FILL, 1.0);
+ evas_object_size_hint_weight_set(popup_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_smart_callback_add(popup_, "block,clicked", AlarmView::DismissPopupCallback, popup_);
+ eext_object_event_callback_add(popup_, EEXT_CALLBACK_BACK, AlarmView::DismissPopupCallback, popup_);
+
+ Evas_Object *list = elm_list_add(popup_);
+ elm_list_mode_set(list, ELM_LIST_EXPAND);
+ evas_object_show(list);
+
+ elm_list_item_append(list, "Delete", NULL, NULL, AlarmView::PopupDeleteItemCallback, this);
+ elm_object_content_set(popup_, list);
+ evas_object_show(popup_);
}
--- /dev/null
+#include "View/DeleteAlarmView.h"
+#include "log.h"
+
+#include <sstream>
+
+using namespace model;
+using namespace utils;
+
+namespace view {
+
+struct ItemData {
+ DeleteAlarmView *instance;
+ char *name;
+ bool active;
+ bool selected;
+ WeekFlags flags;
+ Time time;
+ Elm_Object_Item *it;
+ Evas_Object *check;
+};
+
+static char *WeekFlag2FormattedString(WeekFlags flags)
+{
+ std::stringstream weekflags;
+
+ weekflags << (flags.IsOn(WeekDay::MONDAY) ? "M" : "<off>M</off>");
+ weekflags << (flags.IsOn(WeekDay::TUESDAY) ? "T" : "<off>T</off>");
+ weekflags << (flags.IsOn(WeekDay::WEDNESDAY) ? "W" : "<off>W</off>");
+ weekflags << (flags.IsOn(WeekDay::THURSDAY) ? "T" : "<off>T</off>");
+ weekflags << (flags.IsOn(WeekDay::FRIDAY) ? "F" : "<off>F</off>");
+ weekflags << (flags.IsOn(WeekDay::SATURDAY) ? "S" : "<off>S</off>");
+ weekflags << (flags.IsOn(WeekDay::SUNDAY) ? "S" : "<off>S</off>");
+
+ return strdup(weekflags.str().c_str());
+}
+
+static char *Time2FormattedString(const Time &time)
+{
+ std::stringstream formatted_time;
+
+ formatted_time << time.Format(FORMAT_12H);
+ formatted_time << " <meridiem>";
+ formatted_time << time.Meridiem();
+ formatted_time << "</meridiem>";
+
+ return strdup(formatted_time.str().c_str());
+}
+
+DeleteAlarmView::DeleteAlarmView()
+ : all_selected_(false)
+{
+ PushPage();
+}
+
+void DeleteAlarmView::ItemSelectToggle(void *data, Evas_Object *obj, void *event)
+{
+ ItemData *id = static_cast<ItemData*>(data);
+ id->selected = !id->selected;
+ if (!id->selected) {
+ id->instance->all_selected_ = false;
+ elm_check_state_set(id->instance->all_selected_check_, id->instance->all_selected_);
+ }
+ id->instance->UpdateTitle();
+}
+
+void DeleteAlarmView::ItemSelected(void *data, Evas_Object *obj, void *event)
+{
+ ItemData *id = static_cast<ItemData*>(data);
+ id->selected = !id->selected;
+ if (id->check) {
+ elm_check_state_set(id->check, id->selected);
+ }
+ if (!id->selected) {
+ id->instance->all_selected_ = false;
+ elm_check_state_set(id->instance->all_selected_check_, id->instance->all_selected_);
+ }
+ id->instance->UpdateTitle();
+ elm_genlist_item_selected_set(id->it, EINA_FALSE);
+}
+
+void DeleteAlarmView::CreateContent()
+{
+ elm_object_item_style_set(navi_item_, "basic");
+
+ // left toolbar button
+ left_btn_ = elm_button_add(GetNaviframe());
+ elm_object_text_set(left_btn_, "CANCEL");
+ elm_object_style_set(left_btn_, "naviframe/title_left");
+ evas_object_smart_callback_add(left_btn_, "clicked", OnCancelButtonClickedCb, this);
+ evas_object_show(left_btn_);
+
+ // right toolbar button
+ right_btn_ = elm_button_add(GetNaviframe());
+ elm_object_style_set(right_btn_, "naviframe/title_right");
+ elm_object_text_set(right_btn_, "DELETE");
+ evas_object_smart_callback_add(right_btn_, "clicked", OnDeleteButtonClickedCb, this);
+ evas_object_show(right_btn_);
+
+ // main scrollable content
+ content_ = elm_genlist_add(GetNaviframe());
+ evas_object_size_hint_expand_set(content_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(content_, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ elm_genlist_mode_set(content_, ELM_LIST_COMPRESS);
+ elm_genlist_homogeneous_set(content_, EINA_TRUE);
+ evas_object_smart_callback_add(content_, "realized", DeleteAlarmView::ItemRealized, this);
+ evas_object_show(content_);
+
+ // fill created parts in object item
+ elm_object_item_part_text_set(navi_item_, "elm.text.title", "0 selected");
+ elm_object_item_part_content_set(navi_item_, "title_left_btn", left_btn_);
+ elm_object_item_part_content_set(navi_item_, "title_right_btn", right_btn_);
+ elm_object_item_content_set(navi_item_, content_);
+
+ CreateSelectAllItem();
+}
+
+void DeleteAlarmView::ItemSelectAllClicked(void *data, Evas_Object *obj, void *event)
+{
+ Elm_Object_Item *it = static_cast<Elm_Object_Item*>(event);
+ DeleteAlarmView *view = static_cast<DeleteAlarmView*>(data);
+
+ view->all_selected_ = !view->all_selected_;
+
+ view->SelectAllStateSet(view->all_selected_);
+ if (view->all_selected_check_)
+ elm_check_state_set(view->all_selected_check_, view->all_selected_);
+
+ view->UpdateTitle();
+ elm_genlist_item_selected_set(it, EINA_FALSE);
+}
+
+void DeleteAlarmView::CreateSelectAllItem()
+{
+ Elm_Genlist_Item_Class *itc = elm_genlist_item_class_new();
+ Elm_Genlist_Item *it;
+
+ itc->item_style = "select_all";
+ itc->func.text_get = [](void *data, Evas_Object *obj, const char *part) -> char* {
+ if (!strcmp(part, "elm.text")) {
+ return strdup("Select all");
+ }
+ return nullptr;
+ };
+ itc->func.content_get = [](void *data, Evas_Object *obj, const char *part) -> Evas_Object* {
+ DeleteAlarmView *view = static_cast<DeleteAlarmView*>(data);
+ if (!strcmp(part, "sw.check")) {
+ view->all_selected_check_ = elm_check_add(obj);
+ elm_check_state_set(view->all_selected_check_, view->all_selected_);
+ evas_object_show(view->all_selected_check_);
+ return view->all_selected_check_;
+ }
+ return nullptr;
+ };
+ it = elm_genlist_item_append(content_, itc, this, NULL, ELM_GENLIST_ITEM_NONE,
+ DeleteAlarmView::ItemSelectAllClicked, this);
+ elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_ALWAYS);
+
+ elm_genlist_item_class_unref(itc);
+}
+
+void DeleteAlarmView::ItemRealized(void *data, Evas_Object *obj, void *info)
+{
+ Elm_Object_Item *it = static_cast<Elm_Object_Item*>(info);
+ ItemData *id = static_cast<ItemData*>(elm_object_item_data_get(it));
+
+ // return if select all item
+ if (!id) return;
+
+ if (id->active)
+ elm_object_item_signal_emit(id->it, "alarm,state,enabled", "clock");
+ else
+ elm_object_item_signal_emit(id->it, "alarm,state,disabled", "clock");
+}
+
+void DeleteAlarmView::DestroyContent()
+{
+ evas_object_del(content_);
+ evas_object_del(left_btn_);
+ evas_object_del(right_btn_);
+}
+
+void DeleteAlarmView::OnCancelButtonClickedCb(void *data, Evas_Object *obj, void *event)
+{
+ DeleteAlarmView *view = static_cast<DeleteAlarmView*>(data);
+ if (view->onCancelButtonClicked_) view->onCancelButtonClicked_();
+}
+
+void DeleteAlarmView::OnDeleteButtonClickedCb(void *data, Evas_Object *obj, void *event)
+{
+ DeleteAlarmView *view = static_cast<DeleteAlarmView*>(data);
+ if (view->onDeleteButtonClicked_) view->onDeleteButtonClicked_();
+}
+
+int DeleteAlarmView::ItemAppend(utils::Time time, const char *name,
+ const model::WeekFlags flags, bool active)
+{
+ ItemData *data = new ItemData;
+ Elm_Genlist_Item_Class *itc;
+
+ data->instance = this;
+ data->name = name ? strdup(name) : nullptr;
+ data->flags = flags;
+ data->active = active;
+ data->time = time;
+ data->selected = false;
+
+ itc = elm_genlist_item_class_new();
+ itc->item_style = "alarm";
+ itc->func.content_get = [](void *data, Evas_Object *obj, const char *part) -> Evas_Object* {
+ ItemData *id = static_cast<ItemData*>(data);
+ if (!strcmp(part, "onoff")) {
+ id->check = elm_check_add(obj);
+ evas_object_propagate_events_set(id->check, EINA_FALSE);
+ elm_check_state_set(id->check, id->selected ? EINA_TRUE : EINA_FALSE);
+ evas_object_smart_callback_add(id->check, "changed", DeleteAlarmView::ItemSelectToggle, id);
+ evas_object_show(id->check);
+ return id->check;
+ }
+ return nullptr;
+ };
+ itc->func.text_get = [](void *data, Evas_Object *obj, const char *part) -> char* {
+ ItemData *id = static_cast<ItemData*>(data);
+ if (!strcmp(part, "name"))
+ return strdup(id->name);
+ if (!strcmp(part, "time"))
+ return Time2FormattedString(id->time);
+ if (!strcmp(part, "weekflags"))
+ return WeekFlag2FormattedString(id->flags);
+ return NULL;
+ };
+ itc->func.del = [](void *data, Evas_Object *obj) {
+ ItemData *id = static_cast<ItemData*>(data);
+ delete id->name;
+ delete id;
+ };
+
+ data->it = elm_genlist_item_append(content_,
+ itc,
+ data,
+ NULL,
+ ELM_GENLIST_ITEM_NONE,
+ DeleteAlarmView::ItemSelected, data);
+ elm_genlist_item_class_unref(itc);
+
+ return (uintptr_t)data->it;
+}
+
+std::vector<int> DeleteAlarmView::GetSelectedItems() const
+{
+ std::vector<int> selected_ids;
+ Elm_Object_Item *it = elm_genlist_nth_item_get(content_, 1);
+
+ while (it) {
+ ItemData *data = static_cast<ItemData*>(elm_object_item_data_get(it));
+ if (data->selected)
+ selected_ids.push_back((uintptr_t)it);
+ it = elm_genlist_item_next_get(it);
+ }
+ return selected_ids;
+}
+
+void DeleteAlarmView::SelectAllStateSet(bool state)
+{
+ Elm_Object_Item *it = elm_genlist_nth_item_get(content_, 1);
+
+ while (it) {
+ ItemData *data = static_cast<ItemData*>(elm_object_item_data_get(it));
+ data->selected = state;
+ if (data->check) elm_check_state_set(data->check, data->selected);
+ it = elm_genlist_item_next_get(it);
+ }
+}
+
+void DeleteAlarmView::UpdateTitle()
+{
+ char buf[64];
+ std::vector<int> ids = GetSelectedItems();
+ snprintf(buf, sizeof(buf), "%d selected", ids.size());
+ elm_object_item_part_text_set(navi_item_, "elm.text.title", buf);
+}
+
+}