*/
#include <vector>
+#include <sstream>
+
+#include <efl_extension.h>
#include "View/WorldClockView.h"
#include "View/MainView.h"
using namespace view;
using namespace utils;
+struct LocationItemData {
+ WorldClockView *wc_view;
+ Evas_Object *time;
+
+ char *ampm;
+ char *date;
+ char *city_country;
+ char *gmt_offset_relative;
+ int gmt_offset;
+ Elm_Object_Item *it;
+};
+
+
+/* Custom list View */
+
+Elm_Genlist_Item_Class WorldClockView::world_clock_itc_= {
+ .item_style = "worldclock.custom.list",
+ .func.content_get = WorldClockView::ContentGet,
+ .func.text_get = WorldClockView::TextGet,
+ .func.del = WorldClockView::Del,
+};
+
+
+void WorldClockView::CreateCustomLocationsList()
+{
+ custom_locations_list_ = elm_genlist_add(MainView::GetInstance().GetEvasObject());
+ evas_object_size_hint_expand_set(custom_locations_list_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(custom_locations_list_, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ elm_genlist_homogeneous_set(custom_locations_list_, EINA_TRUE);
+ elm_layout_content_set(world_clock_, TIMEZONE_CUSTOM_LOCATIONS_LIST_PART, custom_locations_list_);
+}
+
+void WorldClockView::AppendItemToCustomList(const model::Location *location)
+{
+ LocationItemData *data = new LocationItemData;
+ Time t;
+ std::stringstream ss;
+
+ data->wc_view = this;
+ ss << location->name << ", " << location->country;
+ data->city_country = strdup(ss.str().c_str());
+
+ data->ampm = strdup(t.GetMeridiemByOffset(location->gmt_offset_).c_str());
+ data->gmt_offset_relative = strdup(t.GetTimezoneRelativeToLocalString(location->gmt_offset_).c_str());
+ data->gmt_offset = location->gmt_offset_;
+ data->date = strdup(t.GetTimezoneDate(location->gmt_offset_).c_str());
+
+ data->it = elm_genlist_item_append(custom_locations_list_,
+ &world_clock_itc_,
+ data,
+ NULL,
+ ELM_GENLIST_ITEM_NONE,
+ WorldClockView::ItemClicked,
+ data);
+
+ return;
+}
+
+void WorldClockView::ItemClicked(void *data, Evas_Object *obj, void *event_info)
+{
+ LocationItemData *lid = static_cast<LocationItemData *>(data);
+
+ /* TODO send event to WC model to update 'Current' timezone.
+ (Model need to fire event(view refresh update) when data are updated.)*/
+
+ const model::Timezone *tz = lid->wc_view->world_clock_data_->GetTimezoneByOffset(lid->gmt_offset);
+ lid->wc_view->world_clock_data_->SetCurrentTimezone(lid->wc_view->world_clock_data_->GetTimezoneNo(tz));
+ lid->wc_view->UpdateMapAndTimezoneDetails(tz);
+
+ elm_genlist_item_selected_set(lid->it, EINA_FALSE);
+}
+
+Evas_Object *WorldClockView::ContentGet(void *data, Evas_Object *obj, const char *part)
+{
+ LocationItemData *lid = static_cast<LocationItemData *>(data);
+
+ if (!strcmp(part, "time")) {
+
+ lid->time = elm_table_add(obj);
+ evas_object_size_hint_align_set(lid->time, 0.0, 0.0);
+
+ Evas_Object *time = CreateTimezoneTime(lid->time);
+ Evas_Object *padding = CreatePadding(lid->time, 8);
+ Evas_Object *ampm = CreateTimezoneXMeridiem(lid->time);
+
+ Evas_Object *dynamic_padding = elm_bg_add(lid->time);
+ evas_object_color_set(dynamic_padding, 0, 0, 0, 0);
+ evas_object_size_hint_weight_set(dynamic_padding, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+ elm_table_pack(lid->time, time, 0, 0, 1, 1);
+ elm_table_pack(lid->time, padding, 1, 0, 1, 1);
+ elm_table_pack(lid->time, ampm, 2, 0, 1, 1);
+ elm_table_pack(lid->time, dynamic_padding, 3, 0, 1, 1);
+
+ //TODO Time need to be set as current for specific timezone
+ Time t;
+
+ std::string timezone_time = t.GetFormattedTimeByTimezoneOffset("HH:MM", lid->gmt_offset);
+ char time_formatted[MAX_STYLE_LEN] = { 0, };
+ snprintf(time_formatted, sizeof(time_formatted),
+ CUSTOM_LIST_TIME_STYLE("%s"), timezone_time.c_str());
+ elm_object_text_set(time, time_formatted);
+
+ std::string meridiem = t.GetMeridiemByOffset(lid->gmt_offset);
+ char ampm_formatted[MAX_STYLE_LEN] = { 0, };
+ snprintf(ampm_formatted, sizeof(ampm_formatted),
+ CUSTOM_LIST_AMPM_STYLE("%s"), meridiem.c_str());
+ elm_object_text_set(ampm, ampm_formatted);
+
+ return lid->time;
+ }
+ return NULL;
+}
+
+char *WorldClockView::TextGet(void *data, Evas_Object *obj, const char *part)
+{
+ LocationItemData *lid = static_cast<LocationItemData *>(data);
+ if (!strcmp(part, "ampm"))
+ return strdup(lid->ampm);
+ if (!strcmp(part, "date"))
+ return strdup(lid->date);
+ if (!strcmp(part, "city.country"))
+ return strdup(lid->city_country);
+ if (!strcmp(part, "gmt.offset.desc"))
+ return strdup(lid->gmt_offset_relative);
+ return NULL;
+}
+
+void WorldClockView::Del(void *data, Evas_Object *obj)
+{
+ LocationItemData *lid = static_cast<LocationItemData *>(data);
+
+ free(lid->ampm);
+ free(lid->city_country);
+ free(lid->date);
+ free(lid->gmt_offset_relative);
+
+ delete lid;
+}
+/*[END] Custom list View */
+
+
void WorldClockView::ChangeTimezoneCb(void *data, Evas_Object *obj, const char *emission,
const char *source)
{
+ /* TODO send event to WC presenter to update 'Current' timezone.
+ (Model need to fire event(view refresh update) when data are updated.)*/
+
WorldClockView *world_clock_view = static_cast<WorldClockView *>(data);
model::WorldClock *world_clock_data = world_clock_view->world_clock_data_;
else
world_clock_data->SetCurrentTimezone(current_tz + 1);
}
- world_clock_view->UpdateTimezoneDetails(world_clock_data->GetCurrentTimezone());
+ world_clock_view->UpdateMapAndTimezoneDetails(world_clock_data->GetCurrentTimezone());
}
// TODO FOR DEBUGING ONLY - need to be removed when application is ready
WorldClockView::WorldClockView()
{
- world_clock_data_ = new model::WorldClock(); // TODO Move to controller and create Presenter for WorldClock
+ world_clock_data_ = new model::WorldClock(); // TODO create Presenter for WorldClock
world_clock_ = elm_layout_add(MainView::GetInstance().GetEvasObject());
if(!elm_layout_file_set(world_clock_,
FAT("Failed to load layout file");
}
-
evas_object_size_hint_align_set(world_clock_, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(world_clock_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
edje_object_message_handler_set(elm_layout_edje_get(world_clock_), message_cb, NULL);
CreateTimezoneDetails();
+ CreateCustomLocationsList();
+
+ elm_theme_extension_add(NULL,
+ Utils::GetAppResourcePath(Utils::APP_DIR_RESOURCE, "edje/CitiesListItem.edj"));
+
+ /* Temporary hardcoded list items */
+ AppendItemToCustomList(world_clock_data_->GetLocation(0));
+ AppendItemToCustomList(world_clock_data_->GetLocation(12));
+ AppendItemToCustomList(world_clock_data_->GetLocation(32));
+ AppendItemToCustomList(world_clock_data_->GetLocation(54));
+ AppendItemToCustomList(world_clock_data_->GetLocation(70));
elm_layout_signal_callback_add(world_clock_, "timezone,go,left",
"main.world.map:arrow.left", WorldClockView::ChangeTimezoneCb,
static_cast<void *>(this));
}
-void WorldClockView::UpdateTimezoneLocationsDots()
+void WorldClockView::UpdateTimezoneLocationsDots(const model::Timezone *timezone)
{
- int current_tz = world_clock_data_->GetCurrentTimezoneNo();
-
for (int i = 0; i < 8; i++) {
Edje_Message_Int_Set *msg;
msg = (Edje_Message_Int_Set *) malloc(
sizeof(Edje_Message_Int_Set) + 3 * sizeof(int));
msg->count = 4;
- if (i >= world_clock_data_->GetCurrentTimezone()->places.size()) {
+ if (i >= timezone->places.size()) {
msg->val[0] = 100;
msg->val[1] = 100;
msg->val[2] = PART_NOT_VISIBLE;
} else {
- model::Location loc = world_clock_data_->GetCurrentTimezone()->places.at(i);
+ model::Location loc = timezone->places.at(i);
msg->val[0] = loc.x;
msg->val[1] = loc.y;
msg->val[2] = PART_VISIBLE;
}
}
-void WorldClockView::UpdateGmtOffset()
+void WorldClockView::UpdateGmtOffset(const model::Timezone *timezone)
{
- const char *offset = world_clock_data_->GetCurrentTzString();
+ const char *offset = world_clock_data_->OffsetToString(timezone->gmt_offset);
elm_object_part_text_set(world_clock_, "main.world.map:timezone_offset", offset);
}
-void WorldClockView::UpdateTimezoneArea()
+void WorldClockView::UpdateTimezoneArea(const model::Timezone *timezone)
{
- Edje_Message_Int_Set *msg;
-
- msg = static_cast<Edje_Message_Int_Set *>(malloc(
- sizeof(Edje_Message_Int_Set) + sizeof(int)));
+ Edje_Message_Int_Set *msg = static_cast<Edje_Message_Int_Set *>
+ (malloc(sizeof(Edje_Message_Int_Set) + sizeof(int)));
msg->count = 2;
- msg->val[0] = world_clock_data_->GetCurrentTimezone()->x_coord;
- msg->val[1] = world_clock_data_->GetCurrentTimezone()->zone_width;
+ msg->val[0] = timezone->x_coord;
+ msg->val[1] = timezone->zone_width;
edje_object_message_send(elm_layout_edje_get(world_clock_), EDJE_MESSAGE_INT_SET,
MESSAGE_ID_SET_TIMEZONE, (void *) msg);
+ free(msg);
}
void WorldClockView::CreateTimezoneDetails()
{
timezone_details_ = elm_table_add(world_clock_);
- Evas_Object *time = CreateTimezoneTime();
- Evas_Object *padding_1 = CreatePadding(12);
- Evas_Object *ampm = CreateTimezoneXMeridiem();
- Evas_Object *padding_2 = CreatePadding(20);
- Evas_Object *relative = CreateTimezoneRelativeToLocalObject();
+ Evas_Object *time = CreateTimezoneTime(world_clock_);
+ Evas_Object *padding_1 = CreatePadding(timezone_details_, 12);
+ Evas_Object *ampm = CreateTimezoneXMeridiem(world_clock_);
+ Evas_Object *padding_2 = CreatePadding(timezone_details_, 20);
+ Evas_Object *relative = CreateTimezoneRelativeToLocalObject(world_clock_);
elm_table_pack(timezone_details_, time, 0, 0, 1, 1);
elm_table_pack(timezone_details_, padding_1, 1, 0, 1, 1);
CreateTimezoneCitiesList();
- UpdateTimezoneDetails(world_clock_data_->GetCurrentTimezone());
+ // TODO load timezone to display on map from app preferences(it must be saved on app temination)
+ UpdateMapAndTimezoneDetails(world_clock_data_->GetCurrentTimezone());
}
-void WorldClockView::UpdateTimezoneDetails(model::Timezone *timezone)
+void WorldClockView::UpdateMapAndTimezoneDetails(const model::Timezone *timezone)
{
- UpdateTimezoneLocationsDots();
- UpdateTimezoneArea();
- UpdateGmtOffset();
+ UpdateTimezoneLocationsDots(timezone);
+ UpdateTimezoneArea(timezone);
+ UpdateGmtOffset(timezone);
UpdateTimezoneTime(timezone->gmt_offset);
UpdateTimezoneXMeridiem(timezone->gmt_offset);
UpdateTimezoneCitiesList(timezone);
}
-Evas_Object *WorldClockView::CreateTimezoneTime()
+Evas_Object *WorldClockView::CreateTimezoneTime(Evas_Object *parent)
{
- Evas_Object *label = elm_label_add(world_clock_);
+ Evas_Object *label = elm_label_add(parent);
evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(label);
void WorldClockView::UpdateTimezoneTime(int timezone_offset)
{
- utils::Time t;
+ Time t;
//TODO This must be formated according to global device settings
std::string timezone_time = t.GetFormattedTimeByTimezoneOffset("HH:MM", timezone_offset);
elm_object_text_set(elm_table_child_get(timezone_details_, 0, 0), time_formatted);
}
-Evas_Object *WorldClockView::CreateTimezoneXMeridiem()
+Evas_Object *WorldClockView::CreateTimezoneXMeridiem(Evas_Object *parent)
{
- Evas_Object *ampm = elm_label_add(world_clock_);
+ Evas_Object *ampm = elm_label_add(parent);
evas_object_size_hint_align_set(ampm, EVAS_HINT_FILL, 0.75);
evas_object_show(ampm);
void WorldClockView::UpdateTimezoneXMeridiem(int timezone_offset)
{
- utils::Time t;
+ Time t;
//TODO This must be formated according to global device settings
std::string meridiem = t.GetMeridiemByOffset(timezone_offset);
elm_object_text_set(elm_table_child_get(timezone_details_, 2, 0), ampm_formatted);
}
-Evas_Object *WorldClockView::CreateTimezoneRelativeToLocalObject()
+Evas_Object *WorldClockView::CreateTimezoneRelativeToLocalObject(Evas_Object *parent)
{
- Evas_Object *relative = elm_label_add(world_clock_);
+ Evas_Object *relative = elm_label_add(parent);
evas_object_size_hint_align_set(relative, EVAS_HINT_FILL, 0.75);
evas_object_show(relative);
void WorldClockView::UpdateTimezoneRelativeToLocal(int timezone_offset)
{
- char *message_pattern;
- char message[64] = { 0, };
- utils::Time t;
-
- int local_timezone_offset = t.GetLocalTimezoneOffset();
- int offset_integer = (abs(timezone_offset - local_timezone_offset)) / 60;
- int offset_remainder = (abs(timezone_offset - local_timezone_offset)) % 60;
-
- DBG("passed offset:%d, local:%d, remainder:%d", timezone_offset,
- local_timezone_offset, offset_remainder);
-
- if (timezone_offset < local_timezone_offset) {
- if (offset_remainder > 0) {
- message_pattern = gettext("IDS_CLOCK_BODY_PS1D_H_P2SD_M_BEHIND_ABB");
- snprintf(message, sizeof(message), message_pattern, offset_integer,
- offset_remainder);
- } else {
- message_pattern = gettext("IDS_CLOCK_BODY_PD_H_BEHIND_ABB");
- snprintf(message, sizeof(message), message_pattern, offset_integer);
- }
-
- } else if (timezone_offset > local_timezone_offset) {
- if (offset_remainder > 0) {
- message_pattern = gettext("IDS_CLOCK_BODY_PS1D_H_P2SD_M_AHEAD_ABB");
- snprintf(message, sizeof(message), message_pattern, offset_integer,
- offset_remainder);
- } else {
- message_pattern = gettext("IDS_CLOCK_BODY_PD_H_AHEAD_ABB");
- snprintf(message, sizeof(message), message_pattern, offset_integer);
- }
-
- } else {
- snprintf(message, sizeof(message), "Same as local time");
- }
+ Time t;
char relative_formatted[MAX_STYLE_LEN] = { 0, };
snprintf(relative_formatted, sizeof(relative_formatted),
- TIMEZONE_DETAILS_FIRST_LINE_RELATIVE_TO_LOCAL_STYLE("%s"), message);
+ TIMEZONE_DETAILS_FIRST_LINE_RELATIVE_TO_LOCAL_STYLE("%s"),
+ t.GetTimezoneRelativeToLocalString(timezone_offset).c_str());
elm_object_text_set(elm_table_child_get(timezone_details_, 4, 0), relative_formatted);
}
-Evas_Object *WorldClockView::CreatePadding(int width)
+Evas_Object *WorldClockView::CreatePadding(Evas_Object *parent, int width)
{
- Evas_Object *padding = elm_bg_add(timezone_details_);
+ Evas_Object *padding = elm_bg_add(parent);
evas_object_size_hint_min_set(padding, width, 10);
evas_object_size_hint_max_set(padding, width, 10);
evas_object_color_set(padding, 0, 0, 0, 0);
timezone_cities_);
}
-void WorldClockView::UpdateTimezoneCitiesList(model::Timezone *timezone)
+void WorldClockView::UpdateTimezoneCitiesList(const model::Timezone *timezone)
{
-
- std::vector < model::Location > *cities_list = ( (timezone) ?
+ const std::vector < model::Location > *cities_list = ( (timezone) ?
&timezone->places : &world_clock_data_->GetCurrentTimezone()->places);
char cities[MAX_CITIES_LEN];
elm_object_text_set(timezone_cities_, cities_formatted);
}
+