Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Yunitsky <yunik@mapswithme.com>2015-12-03 17:25:18 +0300
committerDmitry Yunitsky <yunik@mapswithme.com>2016-01-05 15:22:40 +0300
commitb3ceb797f6215469e499d9ce7d475e3342d72510 (patch)
treeead7b61f8a150b4b7139964878b4df3b068d5814
parent4308be1c61efc7c97eb577229282521c34ecd20c (diff)
REBASE[android] Add timetable editor UI.TEMP
-rw-r--r--android/AndroidManifest.xml1
-rw-r--r--android/jni/Android.mk7
-rw-r--r--android/jni/com/mapswithme/maps/editor/OpeningHours.cpp311
-rw-r--r--android/res/color/color_timepicker_tab.xml11
-rw-r--r--android/res/color/color_timepicker_title.xml11
-rw-r--r--android/res/layout-w840dp/routing_plan_details.xml60
-rw-r--r--android/res/layout/fragment_edit_bookmark.xml47
-rw-r--r--android/res/layout/fragment_timetable.xml56
-rw-r--r--android/res/layout/fragment_timetable_advanced.xml93
-rw-r--r--android/res/layout/fragment_timetable_picker.xml26
-rw-r--r--android/res/layout/fragment_timetable_simple.xml10
-rw-r--r--android/res/layout/item_timetable.xml320
-rw-r--r--android/res/layout/item_timetable_add.xml19
-rw-r--r--android/res/layout/place_page_details.xml7
-rw-r--r--android/res/layout/tab.xml23
-rw-r--r--android/res/layout/tab_timepicker.xml14
-rw-r--r--android/res/values/dimens.xml6
-rw-r--r--android/res/values/font_sizes.xml1
-rw-r--r--android/res/values/styles-text.xml15
-rw-r--r--android/res/values/styles.xml11
-rw-r--r--android/res/values/themes.xml23
-rw-r--r--android/src/com/mapswithme/country/DownloadAdapter.java4
-rw-r--r--android/src/com/mapswithme/country/DownloadFragment.java2
-rw-r--r--android/src/com/mapswithme/country/DownloadedAdapter.java3
-rw-r--r--android/src/com/mapswithme/maps/MwmActivity.java13
-rw-r--r--android/src/com/mapswithme/maps/base/BaseMwmFragmentActivity.java1
-rw-r--r--android/src/com/mapswithme/maps/base/BaseMwmListFragment.java15
-rw-r--r--android/src/com/mapswithme/maps/base/BaseMwmRecyclerFragment.java16
-rw-r--r--android/src/com/mapswithme/maps/base/BaseMwmToolbarFragment.java41
-rw-r--r--android/src/com/mapswithme/maps/bookmarks/ChooseBookmarkCategoryFragment.java1
-rw-r--r--android/src/com/mapswithme/maps/bookmarks/data/Bookmark.java14
-rw-r--r--android/src/com/mapswithme/maps/editor/EditorActivity.java16
-rw-r--r--android/src/com/mapswithme/maps/editor/OpeningHours.java42
-rw-r--r--android/src/com/mapswithme/maps/editor/data/HoursMinutes.java57
-rw-r--r--android/src/com/mapswithme/maps/editor/data/Timespan.java19
-rw-r--r--android/src/com/mapswithme/maps/editor/data/Timetable.java48
-rw-r--r--android/src/com/mapswithme/maps/widget/ToolbarController.java14
-rw-r--r--android/src/com/mapswithme/maps/widget/placepage/DirectionFragment.java3
-rw-r--r--android/src/com/mapswithme/maps/widget/placepage/HoursMinutesPickerFragment.java154
-rw-r--r--android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java1
-rw-r--r--android/src/com/mapswithme/maps/widget/placepage/SimpleTimetableAdapter.java386
-rw-r--r--android/src/com/mapswithme/maps/widget/placepage/TimetableAdvancedFragment.java105
-rw-r--r--android/src/com/mapswithme/maps/widget/placepage/TimetableFragment.java151
-rw-r--r--android/src/com/mapswithme/maps/widget/placepage/TimetableSimpleFragment.java68
44 files changed, 2126 insertions, 120 deletions
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index c8e77a2f95..653113eb68 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -233,6 +233,7 @@
android:name="com.mapswithme.maps.editor.EditorActivity"
android:configChanges="orientation|screenLayout|screenSize"
android:label="@string/pp_place_edit"
+ android:theme="@style/MwmTheme.EditorActivity"
android:parentActivityName="com.mapswithme.maps.MwmActivity">
<!-- The meta-data element is needed for versions lower than 4.1 -->
<meta-data
diff --git a/android/jni/Android.mk b/android/jni/Android.mk
index 134621354e..268abfcbd7 100644
--- a/android/jni/Android.mk
+++ b/android/jni/Android.mk
@@ -25,8 +25,8 @@ define add_prebuild_static_lib
include $(PREBUILT_STATIC_LIBRARY)
endef
-prebuild_static_libs := osrm protobuf tomcrypt jansson minizip fribidi freetype expat succinct opening_hours pugixml \
- base coding geometry editor platform indexer storage search routing drape drape_frontend map stats_client
+prebuild_static_libs := osrm protobuf tomcrypt jansson minizip fribidi freetype expat base coding geometry \
+ editor platform indexer storage search routing drape drape_frontend map stats_client succinct opening_hours pugixml
$(foreach item,$(prebuild_static_libs),$(eval $(call add_prebuild_static_lib,$(item))))
@@ -98,10 +98,11 @@ LOCAL_SRC_FILES := \
com/mapswithme/platform/MethodRef.cpp \
com/mapswithme/platform/PThreadImpl.cpp \
com/mapswithme/util/StringUtils.cpp \
- com/mapswithme/util/Config.cpp \
+ com/mapswithme/util/Config.cpp \
com/mapswithme/opengl/android_gl_utils.cpp \
com/mapswithme/opengl/androidoglcontext.cpp \
com/mapswithme/opengl/androidoglcontextfactory.cpp \
+ com/mapswithme/maps/editor/OpeningHours.cpp \
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv2 -latomic -lz
diff --git a/android/jni/com/mapswithme/maps/editor/OpeningHours.cpp b/android/jni/com/mapswithme/maps/editor/OpeningHours.cpp
new file mode 100644
index 0000000000..ba641a94c9
--- /dev/null
+++ b/android/jni/com/mapswithme/maps/editor/OpeningHours.cpp
@@ -0,0 +1,311 @@
+#include <jni.h>
+
+#include "com/mapswithme/core/jni_helper.hpp"
+
+#include "editor/opening_hours_ui.hpp"
+#include "editor/ui2oh.hpp"
+
+#include "base/logging.hpp"
+
+#include "std/algorithm.hpp"
+#include "std/set.hpp"
+#include "std/vector.hpp"
+
+#include "3party/opening_hours/opening_hours.hpp"
+
+namespace
+{
+using namespace editor;
+using namespace editor::ui;
+using namespace osmoh;
+using THours = std::chrono::hours;
+using TMinutes = std::chrono::minutes;
+
+// ID-s for HoursMinutes class
+jclass g_clazzHoursMinutes;
+jmethodID g_ctorHoursMinutes;
+jfieldID g_fidHours;
+jfieldID g_fidMinutes;
+// ID-s for Timespan class
+jclass g_clazzTimespan;
+jmethodID g_ctorTimespan;
+jfieldID g_fidStart;
+jfieldID g_fidEnd;
+// ID-s for Timetable class
+jclass g_clazzTimetable;
+jmethodID g_ctorTimetable;
+jfieldID g_fidWorkingTimespan;
+jfieldID g_fidClosedTimespans;
+jfieldID g_fidIsFullday;
+jfieldID g_fidWeekdays;
+
+
+void LogTt(TimeTable tt)
+{
+ LOG(LINFO, ("Valid : ", tt.IsValid()));
+ LOG(LINFO, ("Fullday : ", tt.IsValid()));
+ LOG(LINFO, ("OpeningHours : ", tt.GetOpeningTime()));
+ LOG(LINFO, ("OpeningDays : ", tt.GetOpeningDays()));
+}
+
+void LogTts(TimeTableSet tts)
+{
+ LOG(LINFO, ("TTS size : ", tts.Size()));
+ for (int i = 0; i < tts.Size(); i++)
+ LogTt((TimeTable)tts.Get(i));
+}
+
+jobject JavaHoursMinutes(JNIEnv * env, jlong hours, jlong minutes)
+{
+ jobject hoursMinutes = env->NewObject(g_clazzHoursMinutes, g_ctorHoursMinutes, hours, minutes);
+ ASSERT(hoursMinutes, (jni::DescribeException()));
+ return hoursMinutes;
+}
+
+jobject JavaTimespan(JNIEnv * env, jobject const & start, jobject const & end)
+{
+ jobject span = env->NewObject(g_clazzTimespan, g_ctorTimespan, start, end);
+ ASSERT(span, (jni::DescribeException()));
+ return span;
+}
+
+jobject JavaTimespan(JNIEnv * env, osmoh::Timespan const & timespan)
+{
+ auto const start = timespan.GetStart();
+ auto const end = timespan.GetEnd();
+ return JavaTimespan(env,
+ JavaHoursMinutes(env, start.GetHoursCount(), start.GetMinutesCount()),
+ JavaHoursMinutes(env, end.GetHoursCount(), end.GetMinutesCount()));
+}
+
+jobject JavaTimetable(JNIEnv * env, jobject const & workingHours, jobject const & closedHours, bool isFullday, jintArray const & weekdays)
+{
+ jobject tt = env->NewObject(g_clazzTimetable, g_ctorTimetable, workingHours, closedHours, isFullday, weekdays);
+ ASSERT(tt, (jni::DescribeException()));
+ return tt;
+}
+
+jobject JavaTimetable(JNIEnv * env, TimeTable const & tt)
+{
+ auto const excludeSpans = tt.GetExcludeTime();
+ set<Weekday> weekdays = tt.GetOpeningDays();
+ vector<int> weekdaysVector;
+ weekdaysVector.reserve(weekdays.size());
+ transform(weekdays.begin(), weekdays.end(), back_inserter(weekdaysVector), [](Weekday weekday)
+ {
+ return static_cast<int>(weekday);
+ });
+ jintArray jWeekdays = env->NewIntArray(weekdays.size());
+ env->SetIntArrayRegion(jWeekdays, 0, weekdaysVector.size(), &weekdaysVector[0]);
+
+ return JavaTimetable(env,
+ JavaTimespan(env, tt.GetOpeningTime()),
+ excludeSpans.size() == 0 ? nullptr : JavaTimespan(env, excludeSpans[0]),
+ tt.IsTwentyFourHours(),
+ jWeekdays);
+}
+
+jobjectArray JavaTimetables(JNIEnv * env, TimeTableSet & tts)
+{
+ int const size = tts.Size();
+ jobjectArray result = env->NewObjectArray(size, g_clazzTimetable, 0);
+ for (int i = 0; i < size; i++)
+ {
+ jobject jTable = JavaTimetable(env, tts.Get(i));
+ env->SetObjectArrayElement(result, i, jTable);
+ }
+
+ return result;
+}
+
+HourMinutes NativeHoursMinutes(JNIEnv * env, jobject jHourMinutes)
+{
+ jlong const hours = env->GetLongField(jHourMinutes, g_fidHours);
+ jlong const minutes = env->GetLongField(jHourMinutes, g_fidMinutes);
+ return HourMinutes(THours(hours) + TMinutes(minutes));
+}
+
+Timespan NativeTimespan(JNIEnv * env, jobject jTimespan)
+{
+ Timespan span;
+ span.SetStart(NativeHoursMinutes(env, env->GetObjectField(jTimespan, g_fidStart)));
+ span.SetEnd(NativeHoursMinutes(env, env->GetObjectField(jTimespan, g_fidEnd)));
+ return span;
+}
+
+TimeTable NativeTimetable(JNIEnv * env, jobject jTimetable)
+{
+ TimeTable tt;
+ jintArray const & jWeekdays = static_cast<jintArray>(env->GetObjectField(jTimetable, g_fidWeekdays));
+ int* weekdaysArr = static_cast<int*>(env->GetIntArrayElements(jWeekdays, nullptr));
+ jint size = env->GetArrayLength(jWeekdays);
+ std::set<Weekday> weekdays;
+ for (int i = 0; i < size; i++)
+ weekdays.insert(ToWeekday(weekdaysArr[i]));
+ tt.SetOpeningDays(weekdays);
+ env->ReleaseIntArrayElements(jWeekdays, weekdaysArr, 0);
+ tt.SetOpeningTime(NativeTimespan(env, env->GetObjectField(jTimetable, g_fidWorkingTimespan)));
+ tt.SetTwentyFourHours(env->GetBooleanField(jTimetable, g_fidIsFullday));
+ // TODO
+// tt.AddExcludeTime(NativeTimespan(env, env->GetObjectField(jTimetable, g_fidClosedTimespans)));
+ LogTt(tt);
+ return tt;
+}
+
+TimeTableSet NativeTimetables(JNIEnv * env, jobjectArray jTimetables)
+{
+ TimeTableSet tts;
+ int const size = env->GetArrayLength(jTimetables);
+ jobject const & timetable = env->GetObjectArrayElement(jTimetables, 0);
+ tts.Replace(NativeTimetable(env, timetable), 0);
+
+ for (int i = 1; i < size; i++)
+ {
+ jobject const & timetable = env->GetObjectArrayElement(jTimetables, i);
+ tts.Append(NativeTimetable(env, timetable));
+ }
+
+ return tts;
+}
+
+} // namespace
+
+extern "C"
+{
+ JNIEXPORT void JNICALL
+ Java_com_mapswithme_maps_editor_OpeningHours_nativeInit(JNIEnv * env, jclass clazz)
+ {
+ g_clazzHoursMinutes = jni::GetGlobalClassRef(env, "com/mapswithme/maps/editor/data/HoursMinutes");
+ // Java signature : HoursMinutes(@IntRange(from = 0, to = 24) long hours, @IntRange(from = 0, to = 60) long minutes)
+ g_ctorHoursMinutes = env->GetMethodID(g_clazzHoursMinutes, "<init>", "(JJ)V");
+ ASSERT(g_ctorHoursMinutes, (jni::DescribeException()));
+ g_fidHours = env->GetFieldID(g_clazzHoursMinutes, "mHours", "J");
+ ASSERT(g_fidHours, ());
+ g_fidMinutes = env->GetFieldID(g_clazzHoursMinutes, "mMinutes", "J");
+ ASSERT(g_fidMinutes, ());
+
+ g_clazzTimespan = jni::GetGlobalClassRef(env, "com/mapswithme/maps/editor/data/Timespan");
+ // Java signature : Timespan(HoursMinutes start, HoursMinutes end)
+ g_ctorTimespan =
+ env->GetMethodID(g_clazzTimespan, "<init>","(Lcom/mapswithme/maps/editor/data/HoursMinutes;Lcom/mapswithme/maps/editor/data/HoursMinutes;)V");
+ ASSERT(g_ctorTimespan, (jni::DescribeException()));
+ g_fidStart = env->GetFieldID(g_clazzTimespan, "mStart", "Lcom/mapswithme/maps/editor/data/HoursMinutes;");
+ ASSERT(g_fidStart, (jni::DescribeException()));
+ g_fidEnd = env->GetFieldID(g_clazzTimespan, "mEnd", "Lcom/mapswithme/maps/editor/data/HoursMinutes;");
+ ASSERT(g_fidEnd, (jni::DescribeException()));
+
+ g_clazzTimetable = jni::GetGlobalClassRef(env, "com/mapswithme/maps/editor/data/Timetable");
+ // Java signature : Timetable(Timespan workingTime, Timespan closedHours, boolean isFullday, int weekdays[])
+ g_ctorTimetable =
+ env->GetMethodID(g_clazzTimetable, "<init>","(Lcom/mapswithme/maps/editor/data/Timespan;Lcom/mapswithme/maps/editor/data/Timespan;Z[I)V");
+ ASSERT(g_ctorTimetable, (jni::DescribeException()));
+ g_fidWorkingTimespan = env->GetFieldID(g_clazzTimetable, "mWorkingTimespan", "Lcom/mapswithme/maps/editor/data/Timespan;");
+ ASSERT(g_fidWorkingTimespan, ());
+ g_fidClosedTimespans = env->GetFieldID(g_clazzTimetable, "mClosedTimespans", "[Lcom/mapswithme/maps/editor/data/Timespan;");
+ ASSERT(g_fidClosedTimespans, ());
+ g_fidIsFullday = env->GetFieldID(g_clazzTimetable, "mIsFullday", "Z");
+ ASSERT(g_fidIsFullday, ());
+ g_fidWeekdays = env->GetFieldID(g_clazzTimetable, "mWeekdays", "[I");
+ ASSERT(g_fidWeekdays, ());
+ }
+
+ JNIEXPORT jobjectArray JNICALL
+ Java_com_mapswithme_maps_editor_OpeningHours_nativeGetDefaultTimetables(JNIEnv * env, jclass clazz)
+ {
+ TimeTableSet tts;
+ LogTts(tts);
+ return JavaTimetables(env, tts);
+ }
+
+ JNIEXPORT jobject JNICALL
+ Java_com_mapswithme_maps_editor_OpeningHours_nativeGetComplementTimetable(JNIEnv * env, jclass clazz, jobjectArray timetables)
+ {
+ TimeTableSet tts = NativeTimetables(env, timetables);
+ return JavaTimetable(env, tts.GetComplementTimeTable());
+ }
+
+ JNIEXPORT jobject JNICALL
+ Java_com_mapswithme_maps_editor_OpeningHours_nativeRemoveWorkingDay(JNIEnv * env, jclass clazz,
+ jobjectArray timetables, jint ttIndex, jint dayIndex)
+ {
+ TimeTableSet tts = NativeTimetables(env, timetables);
+ auto tt = tts.Get(ttIndex);
+ LogTts(tts);
+ tt.RemoveWorkingDay(ToWeekday(dayIndex));
+ tt.Commit();
+ return JavaTimetables(env, tts);
+ }
+
+ JNIEXPORT jobject JNICALL
+ Java_com_mapswithme_maps_editor_OpeningHours_nativeAddWorkingDay(JNIEnv * env, jclass clazz,
+ jobjectArray timetables, jint ttIndex, jint dayIndex)
+ {
+ TimeTableSet tts = NativeTimetables(env, timetables);
+ auto tt = tts.Get(ttIndex);
+ LogTts(tts);
+ tt.AddWorkingDay(ToWeekday(dayIndex));
+ tt.Commit();
+ return JavaTimetables(env, tts);
+ }
+
+ JNIEXPORT jobject JNICALL
+ Java_com_mapswithme_maps_editor_OpeningHours_nativeSetIsFullday(JNIEnv * env, jclass clazz,
+ jobject jTimetable, jboolean jIsFullday)
+ {
+ TimeTable tt = NativeTimetable(env, jTimetable);
+ if (jIsFullday)
+ tt.SetTwentyFourHours(true);
+ else
+ {
+ tt.SetTwentyFourHours(false);
+ tt.SetOpeningTime(tt.GetPredefinedOpeningTime());
+ }
+ return JavaTimetable(env, tt);
+ }
+
+ JNIEXPORT jobject JNICALL
+ Java_com_mapswithme_maps_editor_OpeningHours_nativeSetOpeningTime(JNIEnv * env, jclass clazz,
+ jobject jTimetable, jobject jOpeningTime)
+ {
+ TimeTable tt = NativeTimetable(env, jTimetable);
+ tt.SetOpeningTime(NativeTimespan(env, jOpeningTime));
+ return JavaTimetable(env, tt);
+ }
+
+ JNIEXPORT jobject JNICALL
+ Java_com_mapswithme_maps_editor_OpeningHours_nativeAddClosedSpan(JNIEnv * env, jclass clazz,
+ jobject jTimetable, jobject jClosedSpan)
+ {
+ TimeTable tt = NativeTimetable(env, jTimetable);
+ tt.AddExcludeTime(NativeTimespan(env, jClosedSpan));
+ return JavaTimetable(env, tt);
+ }
+
+ JNIEXPORT jobject JNICALL
+ Java_com_mapswithme_maps_editor_OpeningHours_nativeRemoveClosedSpan(JNIEnv * env, jclass clazz,
+ jobject jTimetable, jint jClosedSpanIndex)
+ {
+ TimeTable tt = NativeTimetable(env, jTimetable);
+ tt.RemoveExcludeTime(static_cast<size_t>(jClosedSpanIndex));
+ return JavaTimetable(env, tt);
+ }
+
+ JNIEXPORT jobjectArray JNICALL
+ Java_com_mapswithme_maps_editor_OpeningHours_nativeTimetablesFromString(JNIEnv * env, jclass clazz, jstring jSource)
+ {
+ TimeTableSet tts;
+ if (MakeTimeTableSet(OpeningHours(jni::ToNativeString(env, jSource)), tts))
+ return JavaTimetables(env, tts);
+
+ return nullptr;
+ }
+
+ JNIEXPORT jstring JNICALL
+ Java_com_mapswithme_maps_editor_OpeningHours_nativeTimetablesToString(JNIEnv * env, jclass clazz, jobjectArray jTts)
+ {
+ TimeTableSet tts = NativeTimetables(env, jTts);
+ stringstream sstr;
+ sstr << MakeOpeningHours(tts).GetRule();
+ return jni::ToJavaString(env, sstr.str());
+ }
+}
diff --git a/android/res/color/color_timepicker_tab.xml b/android/res/color/color_timepicker_tab.xml
new file mode 100644
index 0000000000..99ec5ba9ba
--- /dev/null
+++ b/android/res/color/color_timepicker_tab.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item
+ android:color="@color/base_blue_light"
+ android:state_selected="true"/>
+
+ <item
+ android:color="@color/text_dark_subtitle"/>
+</selector> \ No newline at end of file
diff --git a/android/res/color/color_timepicker_title.xml b/android/res/color/color_timepicker_title.xml
new file mode 100644
index 0000000000..dc2e248d4e
--- /dev/null
+++ b/android/res/color/color_timepicker_title.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item
+ android:color="@color/base_blue"
+ android:state_selected="true"/>
+
+ <item
+ android:color="@color/base_blue_light"/>
+</selector> \ No newline at end of file
diff --git a/android/res/layout-w840dp/routing_plan_details.xml b/android/res/layout-w840dp/routing_plan_details.xml
index 51e236ff67..c46a5fb3fb 100644
--- a/android/res/layout-w840dp/routing_plan_details.xml
+++ b/android/res/layout-w840dp/routing_plan_details.xml
@@ -1,23 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
+ android:id="@+id/planning_frame"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:wheel="http://schemas.android.com/apk/res-auto"
- android:id="@+id/planning_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="vertical"
- android:clickable="true">
- <FrameLayout android:layout_width="match_parent"
- android:layout_height="@dimen/routing_selector_size"
- android:elevation="3dp"
- style="@style/MwmWidget.Floating.Panel">
+ android:clickable="true"
+ android:orientation="vertical">
+ <FrameLayout
+ style="@style/MwmWidget.Floating.Panel"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/routing_selector_size"
+ android:elevation="3dp">
<LinearLayout
android:id="@+id/progress_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:orientation="horizontal"
android:layout_gravity="center"
+ android:orientation="horizontal"
tools:background="#8000FF00">
<com.mapswithme.maps.widget.WheelProgressView
android:id="@+id/progress_vehicle"
@@ -28,8 +29,9 @@
wheel:wheelSecondaryColor="@color/base_black_divider"
wheel:wheelThickness="@dimen/margin_eighth"/>
- <Space android:layout_width="32dp"
- android:layout_height="0dp"/>
+ <Space
+ android:layout_width="32dp"
+ android:layout_height="0dp"/>
<com.mapswithme.maps.widget.WheelProgressView
android:id="@+id/progress_pedestrian"
@@ -66,8 +68,8 @@
android:id="@+id/details_divider"
android:layout_width="match_parent"
android:layout_height="24dp"
- android:src="@drawable/shadow_top"
- android:scaleType="fitXY"/>
+ android:scaleType="fitXY"
+ android:src="@drawable/shadow_top"/>
<FrameLayout
android:id="@+id/details_frame"
@@ -77,16 +79,17 @@
android:background="@android:color/white"
android:visibility="gone"
tools:visibility="visible">
- <View android:layout_width="match_parent"
- android:layout_height="1dp"
- android:background="?dividerHorizontal"/>
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="?dividerHorizontal"/>
<RelativeLayout
android:id="@+id/numbers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_margin="@dimen/margin_base"
android:layout_gravity="center_vertical"
+ android:layout_margin="@dimen/margin_base"
tools:background="#400000FF">
<TextView
android:id="@+id/time"
@@ -97,12 +100,12 @@
<TextView
android:id="@+id/dot"
style="@style/MwmWidget.TextView.PlanDetail.Number"
- android:layout_toRightOf="@id/time"
- android:textColor="@color/base_black_hint"
- android:text="•"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginTop="2dp"
+ android:layout_toRightOf="@id/time"
+ android:text="•"
+ android:textColor="@color/base_black_hint"
tools:ignore="HardcodedText"/>
<TextView
@@ -115,9 +118,9 @@
<TextView
android:id="@+id/arrival"
style="@style/MwmWidget.TextView.PlanDetail.Number"
- android:textSize="@dimen/text_size_routing_plan_detail_arrival"
android:layout_below="@id/time"
android:textColor="@color/base_black_hint"
+ android:textSize="@dimen/text_size_routing_plan_detail_arrival"
tools:text="Arrive at 12:34"/>
</RelativeLayout>
@@ -129,8 +132,8 @@
android:text="@string/p2p_planning"
android:textColor="@color/text_dark_hint"
android:visibility="gone"
- tools:visibility="visible"
- tools:layout_gravity="right"/>
+ tools:layout_gravity="right"
+ tools:visibility="visible"/>
<TextView
android:id="@+id/error"
@@ -139,14 +142,15 @@
android:text="@string/routing_planning_error"
android:textColor="@color/base_red"
android:visibility="gone"
- tools:visibility="visible"
+ tools:layout_gravity="right|bottom"
tools:layout_marginTop="14dp"
- tools:layout_gravity="right|bottom"/>
+ tools:visibility="visible"/>
- <View android:layout_width="match_parent"
- android:layout_height="1dp"
- android:layout_gravity="bottom"
- android:background="?dividerHorizontal"/>
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_gravity="bottom"
+ android:background="?dividerHorizontal"/>
</FrameLayout>
</LinearLayout>
diff --git a/android/res/layout/fragment_edit_bookmark.xml b/android/res/layout/fragment_edit_bookmark.xml
index ae4d262f4a..86bfd1dd82 100644
--- a/android/res/layout/fragment_edit_bookmark.xml
+++ b/android/res/layout/fragment_edit_bookmark.xml
@@ -1,34 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@android:color/white">
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@android:color/white">
<android.support.v7.widget.Toolbar
- android:id="@+id/toolbar"
- style="@style/MwmWidget.ToolbarStyle"
- android:layout_width="match_parent"
- android:layout_height="?attr/actionBarSize"
- android:theme="@style/MwmWidget.ToolbarTheme">
+ android:id="@+id/toolbar"
+ style="@style/MwmWidget.ToolbarStyle"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize"
+ android:theme="@style/MwmWidget.ToolbarTheme">
<TextView
- android:id="@+id/tv__save"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="right"
- android:background="?attr/selectableItemBackgroundBorderless"
- android:clickable="true"
- android:gravity="center_vertical"
- android:padding="@dimen/margin_half"
- android:text="@string/save"
- android:textAppearance="@style/MwmTextAppearance.Toolbar.Button"/>
+ android:id="@+id/tv__save"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="end"
+ android:background="?attr/selectableItemBackgroundBorderless"
+ android:clickable="true"
+ android:gravity="center_vertical"
+ android:padding="@dimen/margin_half"
+ android:text="@string/save"
+ android:textAppearance="@style/MwmTextAppearance.Toolbar.Button"/>
</android.support.v7.widget.Toolbar>
<FrameLayout
- style="@style/MwmWidget.FrameLayout.Elevation"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/toolbar">
+ style="@style/MwmWidget.FrameLayout.Elevation"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/toolbar">
<include layout="@layout/edit_bookmark_common"/>
diff --git a/android/res/layout/fragment_timetable.xml b/android/res/layout/fragment_timetable.xml
new file mode 100644
index 0000000000..cd31063866
--- /dev/null
+++ b/android/res/layout/fragment_timetable.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/toolbar"
+ style="@style/MwmWidget.ToolbarStyle"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize"
+ android:gravity="end"
+ android:theme="@style/MwmWidget.ToolbarTheme">
+
+ <ImageView
+ android:id="@+id/iv__submit"
+ android:layout_width="?actionBarSize"
+ android:layout_height="?actionBarSize"
+ android:layout_gravity="end|center_vertical"
+ android:background="?selectableItemBackgroundBorderless"
+ android:padding="@dimen/margin_half_plus"
+ android:scaleType="center"
+ android:src="@drawable/ic_toolbar_check"/>
+
+ </android.support.v7.widget.Toolbar>
+
+ <FrameLayout
+ android:id="@+id/fragment_container"
+ style="@style/MwmWidget.FrameLayout.Elevation"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_above="@+id/tv__mode_switch"
+ android:layout_below="@id/toolbar"
+ android:background="@color/divider_standard">
+ </FrameLayout>
+
+ <TextView
+ android:id="@+id/tv__mode_switch"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/base_block_size"
+ android:layout_alignParentBottom="true"
+ android:background="?selectableItemBackground"
+ android:gravity="center_vertical"
+ android:padding="@dimen/margin_base"
+ android:text="@string/editor_time_advanced"
+ android:textAllCaps="true"
+ android:textAppearance="@style/MwmTextAppearance.Body3"
+ android:textColor="@color/base_blue_light"/>
+
+ <include
+ layout="@layout/shadow_bottom"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_above="@id/tv__mode_switch"/>
+
+</RelativeLayout> \ No newline at end of file
diff --git a/android/res/layout/fragment_timetable_advanced.xml b/android/res/layout/fragment_timetable_advanced.xml
new file mode 100644
index 0000000000..9dfb0a6e23
--- /dev/null
+++ b/android/res/layout/fragment_timetable_advanced.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:card_view="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="@dimen/margin_half">
+
+ <android.support.v7.widget.CardView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@android:color/white"
+ card_view:cardBackgroundColor="@android:color/white"
+ card_view:cardCornerRadius="2dp"
+ card_view:cardElevation="4dp">
+
+ <EditText
+ android:id="@+id/et__timetable"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/base_block_size"
+ android:layout_alignParentBottom="true"
+ android:background="@null"
+ android:hint="hint"
+ android:padding="@dimen/margin_base"
+ android:textAppearance="@style/MwmTextAppearance.Body3"/>
+
+ </android.support.v7.widget.CardView>
+
+ <android.support.v7.widget.CardView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/margin_half"
+ android:background="@android:color/white"
+ card_view:cardBackgroundColor="@android:color/white"
+ card_view:cardCornerRadius="2dp"
+ card_view:cardElevation="4dp">
+
+ <RelativeLayout
+ android:id="@+id/examples"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:animateLayoutChanges="true">
+
+ <TextView
+ android:id="@+id/tv__examples_title"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/base_block_size"
+ android:background="@null"
+ android:drawableLeft="@drawable/ic_type_text"
+ android:drawablePadding="@dimen/margin_base"
+ android:drawableStart="@drawable/ic_type_text"
+ android:gravity="center_vertical"
+ android:text="Example values"
+ android:padding="@dimen/margin_base"
+ android:textAppearance="@style/MwmTextAppearance.Body3"
+ android:textColor="@color/base_blue_light"/>
+
+ <ImageView
+ android:id="@+id/iv__indicator"
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/base_block_size"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentRight="true"
+ android:gravity="center_vertical"
+ android:scaleType="center"/>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_below="@id/tv__examples_title"
+ android:background="@color/divider_standard"/>
+
+ <TextView
+ android:id="@+id/tv__examples"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/tv__examples_title"
+ android:padding="@dimen/margin_base"
+ android:text="trololo \ntrololo \ntrololo"/>
+
+ </RelativeLayout>
+
+
+ </android.support.v7.widget.CardView>
+
+ </LinearLayout>
+
+</ScrollView> \ No newline at end of file
diff --git a/android/res/layout/fragment_timetable_picker.xml b/android/res/layout/fragment_timetable_picker.xml
new file mode 100644
index 0000000000..d5a4852704
--- /dev/null
+++ b/android/res/layout/fragment_timetable_picker.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <android.support.design.widget.TabLayout
+ android:id="@+id/tabs"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/base_block_size"
+ android:elevation="@dimen/appbar_elevation"
+ android:background="@android:color/white"
+ app:tabGravity="fill"
+ app:tabIndicatorColor="@color/base_blue_light"
+ app:tabMode="fixed"
+ tools:ignore="UnusedAttribute"/>
+
+ <TimePicker
+ android:id="@+id/picker"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@android:color/white"/>
+</LinearLayout> \ No newline at end of file
diff --git a/android/res/layout/fragment_timetable_simple.xml b/android/res/layout/fragment_timetable_simple.xml
new file mode 100644
index 0000000000..f0d3847ad6
--- /dev/null
+++ b/android/res/layout/fragment_timetable_simple.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.v7.widget.RecyclerView
+ android:id="@+id/recycler"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingLeft="@dimen/margin_half"
+ android:paddingRight="@dimen/margin_half"
+ android:textAllCaps="true"
+ android:textAppearance="@style/MwmTextAppearance.Body3"/> \ No newline at end of file
diff --git a/android/res/layout/item_timetable.xml b/android/res/layout/item_timetable.xml
new file mode 100644
index 0000000000..3b160b60b2
--- /dev/null
+++ b/android/res/layout/item_timetable.xml
@@ -0,0 +1,320 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.v7.widget.CardView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginBottom="@dimen/margin_half"
+ android:layout_marginTop="@dimen/margin_half"
+ android:background="@color/divider_standard">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/tt_height_days"
+ android:layout_gravity="center_vertical"
+ android:baselineAligned="false"
+ android:orientation="horizontal"
+ android:padding="@dimen/margin_half_plus">
+
+ <LinearLayout
+ android:id="@+id/day1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/tv__day_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/MwmTextAppearance.Body1"
+ tools:text="Su"/>
+
+ <CheckBox
+ android:id="@+id/chb__day_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:checked="true"/>
+
+ </LinearLayout>
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0.5"/>
+
+ <LinearLayout
+ android:id="@+id/day2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/tv__day_2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/MwmTextAppearance.Body1"
+ tools:text="Mo"/>
+
+ <CheckBox
+ android:id="@+id/chb__day_2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/day3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/tv__day_3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/MwmTextAppearance.Body1"
+ tools:text="Tu"/>
+
+ <CheckBox
+ android:id="@+id/chb__day_3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/day4"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/tv__day_4"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/MwmTextAppearance.Body1"
+ tools:text="We"/>
+
+ <CheckBox
+ android:id="@+id/chb__day_4"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/day5"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/tv__day_5"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/MwmTextAppearance.Body1"
+ tools:text="Th"/>
+
+ <CheckBox
+ android:id="@+id/chb__day_5"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/day6"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/tv__day_6"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/MwmTextAppearance.Body1"
+ tools:text="Fr"/>
+
+ <CheckBox
+ android:id="@+id/chb__day_6"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ </LinearLayout>
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0.5"/>
+
+ <LinearLayout
+ android:id="@+id/day7"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/tv__day_7"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/MwmTextAppearance.Body1"
+ tools:text="Sa"/>
+
+ <CheckBox
+ android:id="@+id/chb__day_7"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ </LinearLayout>
+
+ </LinearLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@color/divider_standard"/>
+
+ <LinearLayout
+ android:id="@+id/allday"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/tt_height_allday"
+ android:layout_gravity="center_vertical"
+ android:gravity="center_vertical"
+ android:orientation="horizontal"
+ android:padding="@dimen/margin_half_plus">
+
+ <TextView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/editor_time_allday"
+ android:textAppearance="@style/MwmTextAppearance.Body1"/>
+
+ <Switch
+ android:id="@+id/sw__allday"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/schedule"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:visibility="gone"
+ tools:visibility="visible">
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@color/divider_standard"/>
+
+ <LinearLayout
+ android:id="@+id/time_open_close"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/tt_height_hours"
+ android:baselineAligned="false"
+ android:gravity="center_vertical"
+ android:orientation="horizontal">
+
+ <LinearLayout
+ android:id="@+id/time_open"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:background="?clickableBackground"
+ android:orientation="vertical"
+ android:padding="@dimen/margin_half_plus">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/margin_eighth"
+ android:text="@string/editor_time_open"
+ android:textAppearance="@style/MwmTextAppearance.Body3"/>
+
+ <TextView
+ android:id="@+id/tv__time_open"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/MwmTextAppearance.Title"
+ tools:text="09:00"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/time_close"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:background="?clickableBackground"
+ android:orientation="vertical"
+ android:padding="@dimen/margin_half_plus">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/margin_eighth"
+ android:text="@string/editor_time_close"
+ android:textAppearance="@style/MwmTextAppearance.Body3"/>
+
+ <TextView
+ android:id="@+id/tv__time_close"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/MwmTextAppearance.Title"
+ tools:text="16:00"/>
+
+ </LinearLayout>
+
+ </LinearLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@color/divider_standard"/>
+
+ <TextView
+ android:id="@+id/tv__add_closed"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="?clickableBackground"
+ android:padding="@dimen/margin_half_plus"
+ android:text="@string/editor_time_add_closed"
+ android:textAllCaps="true"
+ android:textAppearance="@style/MwmTextAppearance.Body1"
+ android:textColor="@color/base_blue_light"/>
+
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/tv__remove_timetable"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="?clickableBackground"
+ android:padding="@dimen/margin_half_plus"
+ android:text="@string/editor_time_delete"
+ android:textAllCaps="true"
+ android:textAppearance="@style/MwmTextAppearance.Body1"
+ android:textColor="@color/base_red"/>
+
+ </LinearLayout>
+
+</android.support.v7.widget.CardView> \ No newline at end of file
diff --git a/android/res/layout/item_timetable_add.xml b/android/res/layout/item_timetable_add.xml
new file mode 100644
index 0000000000..5e4454a535
--- /dev/null
+++ b/android/res/layout/item_timetable_add.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <Button
+ android:id="@+id/btn__add_time"
+ android:layout_width="124dp"
+ android:layout_height="36dp"
+ android:layout_gravity="center"
+ android:layout_marginBottom="@dimen/margin_base_plus"
+ android:layout_marginTop="@dimen/margin_base_plus"
+ android:background="@color/base_blue_light"
+ android:text="@string/editor_time_add"
+ android:textAllCaps="true"
+ android:textAppearance="@style/MwmTextAppearance.Body3.Light"/>
+
+</FrameLayout> \ No newline at end of file
diff --git a/android/res/layout/place_page_details.xml b/android/res/layout/place_page_details.xml
index 53f18cc9f2..e617416eb3 100644
--- a/android/res/layout/place_page_details.xml
+++ b/android/res/layout/place_page_details.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
<com.mapswithme.maps.widget.ObservableScrollView
android:id="@+id/pp__details"
android:layout_width="match_parent"
diff --git a/android/res/layout/tab.xml b/android/res/layout/tab.xml
index d6ff857a4e..c5e14b428c 100644
--- a/android/res/layout/tab.xml
+++ b/android/res/layout/tab.xml
@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:padding="@dimen/margin_half_plus"
- android:textAppearance="@style/MwmTextAppearance.Body4"
- android:gravity="center"
- android:textAllCaps="true"
- android:singleLine="true"
- tools:drawableLeft="@drawable/ic_menu_open"
- tools:text="Some tab"/>
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:padding="@dimen/margin_half_plus"
+ android:singleLine="true"
+ android:textAllCaps="true"
+ android:textAppearance="@style/MwmTextAppearance.Body4"
+ tools:drawableLeft="@drawable/ic_menu_open"
+ tools:text="Some tab"/>
diff --git a/android/res/layout/tab_timepicker.xml b/android/res/layout/tab_timepicker.xml
new file mode 100644
index 0000000000..b8b9a8d1d6
--- /dev/null
+++ b/android/res/layout/tab_timepicker.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:padding="@dimen/margin_half_plus"
+ android:singleLine="true"
+ android:textAllCaps="true"
+ android:textAppearance="@style/MwmTextAppearance.Body3"
+ android:textColor="@color/color_timepicker_tab"
+ tools:drawableLeft="@drawable/ic_menu_open"
+ tools:text="Some tab"/>
diff --git a/android/res/values/dimens.xml b/android/res/values/dimens.xml
index 3d38e9de46..3f25a0b4a2 100644
--- a/android/res/values/dimens.xml
+++ b/android/res/values/dimens.xml
@@ -94,4 +94,10 @@
<dimen name="news_max_width">560dp</dimen>
<dimen name="news_max_height">500dp</dimen>
+
+ <!-- Editor -->
+ <dimen name="tt_height_days">72dp</dimen>
+ <dimen name="tt_height_allday">56dp</dimen>
+ <dimen name="tt_height_hours">80dp</dimen>
+ <dimen name="tt_height_add_delete_schedule">92dp</dimen>
</resources>
diff --git a/android/res/values/font_sizes.xml b/android/res/values/font_sizes.xml
index dca2d3ed18..475d716aec 100644
--- a/android/res/values/font_sizes.xml
+++ b/android/res/values/font_sizes.xml
@@ -37,5 +37,6 @@
<dimen name="text_size_routing_dimension">14sp</dimen>
<dimen name="text_size_routing_plan_detail">18sp</dimen>
<dimen name="text_size_routing_plan_detail_arrival">14sp</dimen>
+ <dimen name="text_size_time_picker">56sp</dimen>
</resources>
diff --git a/android/res/values/styles-text.xml b/android/res/values/styles-text.xml
index 347f44113f..330c5674c4 100644
--- a/android/res/values/styles-text.xml
+++ b/android/res/values/styles-text.xml
@@ -128,4 +128,19 @@
<item name="android:textSize">@dimen/text_size_routing_plan_detail</item>
<item name="android:fontFamily" tools:ignore="NewApi">@string/robotoMedium</item>
</style>
+
+ <style name="MwmTextAppearance.Editor">
+ <item name="android:textColor">@color/base_blue_light</item>
+ </style>
+
+ <style name="MwmTextAppearance.Editor.TimePicker">
+ <item name="android:textSize">@dimen/text_size_time_picker</item>
+ <item name="android:textColor">@color/color_timepicker_title</item>
+ </style>
+
+ <style name="MwmTextAppearance.Editor.Buttons">
+ <item name="android:textSize">@dimen/text_size_body_3</item>
+ </style>
+
+
</resources> \ No newline at end of file
diff --git a/android/res/values/styles.xml b/android/res/values/styles.xml
index c2f2a93a2f..3e599a3eb0 100644
--- a/android/res/values/styles.xml
+++ b/android/res/values/styles.xml
@@ -155,4 +155,15 @@
<item name="android:progressDrawable">@drawable/rating_bar</item>
<item name="android:indeterminateDrawable">@drawable/rating_bar</item>
</style>
+
+ <style name="MwmWidget.Editor.TimePicker" parent="MwmWidget">
+ <item name="colorPrimary">@color/base_blue_light</item>
+ <item name="android:headerBackground">@null</item>
+ <item name="android:headerTimeTextAppearance" tools:targetApi="lollipop">@style/MwmTextAppearance.Editor.TimePicker</item>
+ <item name="android:numbersSelectorColor" tools:targetApi="lollipop">@color/base_blue_light</item>
+ <item name="android:numbersBackgroundColor" tools:targetApi="lollipop">@color/divider_standard</item>
+ <item name="android:headerAmPmTextAppearance" tools:targetApi="lollipop">@style/MwmTextAppearance.Editor.Buttons</item>
+ <item name="android:timePickerMode" tools:targetApi="lollipop">clock</item>
+ </style>
+
</resources> \ No newline at end of file
diff --git a/android/res/values/themes.xml b/android/res/values/themes.xml
index 2677132055..148725db98 100644
--- a/android/res/values/themes.xml
+++ b/android/res/values/themes.xml
@@ -17,20 +17,13 @@
</style>
<style name="MwmTheme.MainActivity">
- <item name="android:colorPrimaryDark" tools:ignore="NewApi">@android:color/black</item>
+ <item name="android:colorPrimaryDark" tools:targetApi="lollipop">@android:color/black</item>
<item name="android:windowBackground">@null</item>
</style>
- <style name="MwmTheme.Light">
- <item name="android:windowFrame">@null</item>
- <item name="android:windowTitleStyle">@style/TextAppearance.AppCompat.Title</item>
- <item name="android:windowIsFloating">true</item>
- <item name="android:windowContentOverlay">@null</item>
- <item name="android:windowActionModeOverlay">true</item>
- <item name="android:windowCloseOnTouchOutside">false</item>
- <item name="android:buttonBarStyle">@style/Theme.AppCompat.Dialog</item>
- <item name="listPreferredItemPaddingLeft">16dip</item>
- <item name="listPreferredItemPaddingRight">16dip</item>
+ <style name="MwmTheme.EditorActivity">
+ <item name="colorAccent">@color/base_blue_light</item>
+ <item name="android:timePickerStyle" tools:targetApi="lollipop">@style/MwmWidget.Editor.TimePicker</item>
</style>
<style name="MwmMain.DialogFragment" parent="android:Theme.Holo.Light.Dialog.NoActionBar">
@@ -68,4 +61,12 @@
<style name="MwmMain.DialogFragment.Fullscreen.SemiTransparent">
<item name="android:windowBackground">@color/semitransparent_black</item>
</style>
+
+ <style name="MwmMain.DialogFragment.TimePicker" parent="Theme.AppCompat.Light.Dialog.Alert">
+ <item name="android:fontFamily" tools:targetApi="jelly_bean">@string/robotoMedium</item>
+ <item name="android:background">@android:color/white</item>
+ <item name="colorPrimary">@color/base_blue_light</item>
+ <item name="colorAccent">@color/base_blue_light</item>
+ </style>
+
</resources> \ No newline at end of file
diff --git a/android/src/com/mapswithme/country/DownloadAdapter.java b/android/src/com/mapswithme/country/DownloadAdapter.java
index 685828f124..8dc1a110d4 100644
--- a/android/src/com/mapswithme/country/DownloadAdapter.java
+++ b/android/src/com/mapswithme/country/DownloadAdapter.java
@@ -2,6 +2,8 @@ package com.mapswithme.country;
import android.view.View;
+import com.mapswithme.util.Utils;
+
class DownloadAdapter extends BaseDownloadAdapter implements CountryTree.CountryTreeListener
{
public DownloadAdapter(DownloadFragment fragment)
@@ -43,7 +45,7 @@ class DownloadAdapter extends BaseDownloadAdapter implements CountryTree.Country
{
CountryTree.showLeafOnMap(position);
resetCountryListener();
- mFragment.navigateUpToParent();
+ Utils.navigateToParent(mFragment.getActivity());
}
protected void expandGroup(int position)
diff --git a/android/src/com/mapswithme/country/DownloadFragment.java b/android/src/com/mapswithme/country/DownloadFragment.java
index 6d28bcc451..aea3ab75e6 100644
--- a/android/src/com/mapswithme/country/DownloadFragment.java
+++ b/android/src/com/mapswithme/country/DownloadFragment.java
@@ -109,7 +109,7 @@ public class DownloadFragment extends BaseMwmListFragment implements View.OnClic
updateToolbar();
}
else
- navigateUpToParent();
+ Utils.navigateToParent(getActivity());
return true;
}
diff --git a/android/src/com/mapswithme/country/DownloadedAdapter.java b/android/src/com/mapswithme/country/DownloadedAdapter.java
index e6d920c884..2f7ae7bf1a 100644
--- a/android/src/com/mapswithme/country/DownloadedAdapter.java
+++ b/android/src/com/mapswithme/country/DownloadedAdapter.java
@@ -7,6 +7,7 @@ import android.view.ViewGroup;
import com.mapswithme.maps.BuildConfig;
import com.mapswithme.maps.R;
+import com.mapswithme.util.Utils;
public class DownloadedAdapter extends BaseDownloadAdapter implements ActiveCountryTree.ActiveCountryListener
{
@@ -294,7 +295,7 @@ public class DownloadedAdapter extends BaseDownloadAdapter implements ActiveCoun
{
ActiveCountryTree.showOnMap(groupAndPosition.first, groupAndPosition.second);
resetCountryListener();
- mFragment.navigateUpToParent();
+ Utils.navigateToParent(mFragment.getActivity());
}
}
diff --git a/android/src/com/mapswithme/maps/MwmActivity.java b/android/src/com/mapswithme/maps/MwmActivity.java
index 26359fc18c..b27675c6dd 100644
--- a/android/src/com/mapswithme/maps/MwmActivity.java
+++ b/android/src/com/mapswithme/maps/MwmActivity.java
@@ -14,6 +14,7 @@ import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
+import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
@@ -40,8 +41,8 @@ import com.mapswithme.maps.bookmarks.ChooseBookmarkCategoryFragment;
import com.mapswithme.maps.bookmarks.data.BookmarkManager;
import com.mapswithme.maps.bookmarks.data.MapObject;
import com.mapswithme.maps.bookmarks.data.MapObject.ApiPoint;
+import com.mapswithme.maps.bookmarks.data.Metadata;
import com.mapswithme.maps.editor.EditorActivity;
-import com.mapswithme.maps.editor.EditorFragment;
import com.mapswithme.maps.location.LocationHelper;
import com.mapswithme.maps.location.LocationPredictor;
import com.mapswithme.maps.routing.NavigationController;
@@ -62,6 +63,7 @@ import com.mapswithme.maps.widget.menu.MainMenu;
import com.mapswithme.maps.widget.placepage.BasePlacePageAnimationController;
import com.mapswithme.maps.widget.placepage.PlacePageView;
import com.mapswithme.maps.widget.placepage.PlacePageView.State;
+import com.mapswithme.maps.widget.placepage.TimetableFragment;
import com.mapswithme.util.Animations;
import com.mapswithme.util.BottomSheetHelper;
import com.mapswithme.util.Config;
@@ -96,7 +98,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
private static final String[] DOCKED_FRAGMENTS = { SearchFragment.class.getName(),
DownloadFragment.class.getName(),
RoutingPlanFragment.class.getName(),
- EditorFragment.class.getName() };
+ TimetableFragment.class.getName() };
// Instance state
private static final String STATE_PP_OPENED = "PpOpened";
private static final String STATE_MAP_OBJECT = "MapObject";
@@ -249,11 +251,14 @@ public class MwmActivity extends BaseMwmFragmentActivity
public void showEditor(MapObject point)
{
+ final String openingTime = point.getMetadata(Metadata.MetadataType.FMD_OPEN_HOURS);
+ // TODO use EditorFragment after is will be finished
if (mIsFragmentContainer)
{
final Bundle args = new Bundle();
- args.putParcelable(EditorFragment.EXTRA_POINT, point);
- replaceFragment(EditorFragment.class, args, null);
+ if (!TextUtils.isEmpty(openingTime))
+ args.putString(TimetableFragment.EXTRA_TIME, openingTime);
+ replaceFragment(TimetableFragment.class, args, null);
}
else
EditorActivity.start(this, point);
diff --git a/android/src/com/mapswithme/maps/base/BaseMwmFragmentActivity.java b/android/src/com/mapswithme/maps/base/BaseMwmFragmentActivity.java
index 492df558e7..d9440d54b4 100644
--- a/android/src/com/mapswithme/maps/base/BaseMwmFragmentActivity.java
+++ b/android/src/com/mapswithme/maps/base/BaseMwmFragmentActivity.java
@@ -7,6 +7,7 @@ import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
+
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.maps.R;
import com.mapswithme.util.Utils;
diff --git a/android/src/com/mapswithme/maps/base/BaseMwmListFragment.java b/android/src/com/mapswithme/maps/base/BaseMwmListFragment.java
index 9ce5cec0c3..85052c3399 100644
--- a/android/src/com/mapswithme/maps/base/BaseMwmListFragment.java
+++ b/android/src/com/mapswithme/maps/base/BaseMwmListFragment.java
@@ -1,15 +1,13 @@
package com.mapswithme.maps.base;
-import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
-import android.support.v4.app.NavUtils;
import android.support.v7.widget.Toolbar;
import android.view.View;
import com.mapswithme.maps.R;
-import com.mapswithme.maps.activity.CustomNavigateUpListener;
import com.mapswithme.util.UiUtils;
+import com.mapswithme.util.Utils;
public abstract class BaseMwmListFragment extends ListFragment
{
@@ -29,7 +27,7 @@ public abstract class BaseMwmListFragment extends ListFragment
@Override
public void onClick(View v)
{
- navigateUpToParent();
+ Utils.navigateToParent(getActivity());
}
});
}
@@ -54,13 +52,4 @@ public abstract class BaseMwmListFragment extends ListFragment
super.onPause();
org.alohalytics.Statistics.logEvent("$onPause", getClass().getSimpleName());
}
-
- public void navigateUpToParent()
- {
- final Activity activity = getActivity();
- if (activity instanceof CustomNavigateUpListener)
- ((CustomNavigateUpListener) activity).customOnNavigateUp();
- else
- NavUtils.navigateUpFromSameTask(activity);
- }
}
diff --git a/android/src/com/mapswithme/maps/base/BaseMwmRecyclerFragment.java b/android/src/com/mapswithme/maps/base/BaseMwmRecyclerFragment.java
index d8c2ab79f6..4f32c2a1fa 100644
--- a/android/src/com/mapswithme/maps/base/BaseMwmRecyclerFragment.java
+++ b/android/src/com/mapswithme/maps/base/BaseMwmRecyclerFragment.java
@@ -1,19 +1,18 @@
package com.mapswithme.maps.base;
-import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.v4.app.Fragment;
-import android.support.v4.app.NavUtils;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+
import com.mapswithme.maps.R;
-import com.mapswithme.maps.activity.CustomNavigateUpListener;
import com.mapswithme.util.UiUtils;
+import com.mapswithme.util.Utils;
public abstract class BaseMwmRecyclerFragment extends Fragment
{
@@ -52,7 +51,7 @@ public abstract class BaseMwmRecyclerFragment extends Fragment
@Override
public void onClick(View v)
{
- navigateUpToParent();
+ Utils.navigateToParent(getActivity());
}
});
}
@@ -90,13 +89,4 @@ public abstract class BaseMwmRecyclerFragment extends Fragment
super.onPause();
org.alohalytics.Statistics.logEvent("$onPause", this.getClass().getSimpleName());
}
-
- public void navigateUpToParent()
- {
- final Activity activity = getActivity();
- if (activity instanceof CustomNavigateUpListener)
- ((CustomNavigateUpListener) activity).customOnNavigateUp();
- else
- NavUtils.navigateUpFromSameTask(activity);
- }
}
diff --git a/android/src/com/mapswithme/maps/base/BaseMwmToolbarFragment.java b/android/src/com/mapswithme/maps/base/BaseMwmToolbarFragment.java
new file mode 100644
index 0000000000..b0a4010acd
--- /dev/null
+++ b/android/src/com/mapswithme/maps/base/BaseMwmToolbarFragment.java
@@ -0,0 +1,41 @@
+package com.mapswithme.maps.base;
+
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.view.View;
+
+import com.mapswithme.maps.widget.ToolbarController;
+
+public class BaseMwmToolbarFragment extends Fragment
+{
+ protected ToolbarController mToolbarController;
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
+ {
+ super.onViewCreated(view, savedInstanceState);
+ mToolbarController = onCreateToolbarController(view);
+ }
+
+ protected ToolbarController onCreateToolbarController(@NonNull View root)
+ {
+ return new ToolbarController(root, getActivity());
+ }
+
+ @Override
+ public void onResume()
+ {
+ super.onResume();
+ org.alohalytics.Statistics.logEvent("$onResume", this.getClass().getSimpleName()
+ + ":" + com.mapswithme.util.UiUtils.deviceOrientationAsString(getActivity()));
+ }
+
+ @Override
+ public void onPause()
+ {
+ super.onPause();
+ org.alohalytics.Statistics.logEvent("$onPause", this.getClass().getSimpleName());
+ }
+}
diff --git a/android/src/com/mapswithme/maps/bookmarks/ChooseBookmarkCategoryFragment.java b/android/src/com/mapswithme/maps/bookmarks/ChooseBookmarkCategoryFragment.java
index ea25acc36b..07018e78a9 100644
--- a/android/src/com/mapswithme/maps/bookmarks/ChooseBookmarkCategoryFragment.java
+++ b/android/src/com/mapswithme/maps/bookmarks/ChooseBookmarkCategoryFragment.java
@@ -28,7 +28,6 @@ public class ChooseBookmarkCategoryFragment extends BaseMwmDialogFragment implem
private ChooseBookmarkCategoryAdapter mAdapter;
private RecyclerView mRecycler;
-
public interface Listener
{
void onCategoryChanged(int bookmarkId, int newCategoryId);
diff --git a/android/src/com/mapswithme/maps/bookmarks/data/Bookmark.java b/android/src/com/mapswithme/maps/bookmarks/data/Bookmark.java
index 36279c2bbf..e51bfc4292 100644
--- a/android/src/com/mapswithme/maps/bookmarks/data/Bookmark.java
+++ b/android/src/com/mapswithme/maps/bookmarks/data/Bookmark.java
@@ -40,6 +40,20 @@ public class Bookmark extends MapObject
this(source.readInt(), source.readInt(), source.readString());
}
+ public static final Creator<Bookmark> CREATOR = new Creator<Bookmark>() {
+ @Override
+ public Bookmark createFromParcel(Parcel source)
+ {
+ return (Bookmark) MapObject.readFromParcel(source);
+ }
+
+ @Override
+ public Bookmark[] newArray(int size)
+ {
+ return new Bookmark[size];
+ }
+ };
+
private native ParcelablePointD getXY(int catId, long bookmarkId);
private native String getIcon(int catId, long bookmarkId);
diff --git a/android/src/com/mapswithme/maps/editor/EditorActivity.java b/android/src/com/mapswithme/maps/editor/EditorActivity.java
index 24b01a9866..a9dd052b5e 100644
--- a/android/src/com/mapswithme/maps/editor/EditorActivity.java
+++ b/android/src/com/mapswithme/maps/editor/EditorActivity.java
@@ -3,29 +3,37 @@ package com.mapswithme.maps.editor;
import android.app.Activity;
import android.content.Intent;
import android.support.v4.app.Fragment;
+import android.text.TextUtils;
import com.mapswithme.maps.base.BaseMwmFragmentActivity;
import com.mapswithme.maps.bookmarks.data.MapObject;
+import com.mapswithme.maps.bookmarks.data.Metadata;
+import com.mapswithme.maps.widget.placepage.TimetableFragment;
public class EditorActivity extends BaseMwmFragmentActivity
{
@Override
protected Class<? extends Fragment> getFragmentClass()
{
- return EditorFragment.class;
+ // TODO use EditorFragment after is will be finished
+ return TimetableFragment.class;
}
@Override
public void onBackPressed()
{
- final EditorFragment fragment = (EditorFragment)getSupportFragmentManager().findFragmentByTag(getFragmentClass().getName());
+ final TimetableFragment fragment = (TimetableFragment) getSupportFragmentManager().findFragmentByTag(getFragmentClass().getName());
if ((fragment == null) || !fragment.isAdded() || !fragment.onBackPressed())
super.onBackPressed();
}
public static void start(Activity activity, MapObject point)
{
- activity.startActivity(new Intent(activity, EditorActivity.class)
- .putExtra(EditorFragment.EXTRA_POINT, point));
+ final Intent intent = new Intent(activity, EditorActivity.class);
+ final String openHours = point.getMetadata(Metadata.MetadataType.FMD_OPEN_HOURS);
+ if (!TextUtils.isEmpty(openHours))
+ intent.putExtra(TimetableFragment.EXTRA_TIME, openHours);
+
+ activity.startActivity(intent);
}
}
diff --git a/android/src/com/mapswithme/maps/editor/OpeningHours.java b/android/src/com/mapswithme/maps/editor/OpeningHours.java
new file mode 100644
index 0000000000..c458c555fd
--- /dev/null
+++ b/android/src/com/mapswithme/maps/editor/OpeningHours.java
@@ -0,0 +1,42 @@
+package com.mapswithme.maps.editor;
+
+import android.support.annotation.IntRange;
+
+import com.mapswithme.maps.editor.data.Timespan;
+import com.mapswithme.maps.editor.data.Timetable;
+
+public final class OpeningHours
+{
+ private OpeningHours() {}
+
+ static
+ {
+ nativeInit();
+ }
+
+ private static native void nativeInit();
+
+ public static native Timetable[] nativeGetDefaultTimetables();
+
+ public static native Timetable nativeGetComplementTimetable(Timetable[] timetableSet);
+
+ public static native Timetable[] nativeAddTimetable(Timetable[] timetableSet);
+
+ public static native Timetable[] nativeRemoveTimetable(Timetable[] timetableSet, int timetableIndex);
+
+ public static native Timetable nativeSetIsFullday(Timetable timetable, boolean isFullday);
+
+ public static native Timetable[] nativeAddWorkingDay(Timetable[] timetables, int timetableIndex, @IntRange(from = 1, to = 7) int day);
+
+ public static native Timetable[] nativeRemoveWorkingDay(Timetable[] timetables, int timetableIndex, @IntRange(from = 1, to = 7) int day);
+
+ public static native Timetable nativeSetOpeningTime(Timetable timetable, Timespan openingTime);
+
+ public static native Timetable nativeAddClosedSpan(Timetable timetable, Timespan closedSpan);
+
+ public static native Timetable nativeRemoveClosedSpan(Timetable timetable, int spanIndex);
+
+ public static native Timetable[] nativeTimetablesFromString(String source);
+
+ public static native String nativeTimetablesToString(Timetable timetables[]);
+}
diff --git a/android/src/com/mapswithme/maps/editor/data/HoursMinutes.java b/android/src/com/mapswithme/maps/editor/data/HoursMinutes.java
new file mode 100644
index 0000000000..b9a1903c95
--- /dev/null
+++ b/android/src/com/mapswithme/maps/editor/data/HoursMinutes.java
@@ -0,0 +1,57 @@
+package com.mapswithme.maps.editor.data;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.annotation.IntRange;
+
+public class HoursMinutes implements Parcelable
+{
+ public final long mHours;
+ public final long mMinutes;
+
+ public HoursMinutes(@IntRange(from = 0, to = 24) long hours, @IntRange(from = 0, to = 60) long minutes)
+ {
+ mHours = hours;
+ mMinutes = minutes;
+ }
+
+ protected HoursMinutes(Parcel in)
+ {
+ mHours = in.readLong();
+ mMinutes = in.readLong();
+ }
+
+ @Override
+ public String toString()
+ {
+ return mHours + "." + mMinutes;
+ }
+
+ @Override
+ public int describeContents()
+ {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags)
+ {
+ dest.writeLong(mHours);
+ dest.writeLong(mMinutes);
+ }
+
+ public static final Creator<HoursMinutes> CREATOR = new Creator<HoursMinutes>()
+ {
+ @Override
+ public HoursMinutes createFromParcel(Parcel in)
+ {
+ return new HoursMinutes(in);
+ }
+
+ @Override
+ public HoursMinutes[] newArray(int size)
+ {
+ return new HoursMinutes[size];
+ }
+ };
+}
diff --git a/android/src/com/mapswithme/maps/editor/data/Timespan.java b/android/src/com/mapswithme/maps/editor/data/Timespan.java
new file mode 100644
index 0000000000..f405f961ba
--- /dev/null
+++ b/android/src/com/mapswithme/maps/editor/data/Timespan.java
@@ -0,0 +1,19 @@
+package com.mapswithme.maps.editor.data;
+
+public class Timespan
+{
+ public final HoursMinutes mStart;
+ public final HoursMinutes mEnd;
+
+ public Timespan(HoursMinutes start, HoursMinutes end)
+ {
+ mStart = start;
+ mEnd = end;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "From : " + mStart + " to : " + mEnd;
+ }
+}
diff --git a/android/src/com/mapswithme/maps/editor/data/Timetable.java b/android/src/com/mapswithme/maps/editor/data/Timetable.java
new file mode 100644
index 0000000000..a45b7f2d22
--- /dev/null
+++ b/android/src/com/mapswithme/maps/editor/data/Timetable.java
@@ -0,0 +1,48 @@
+package com.mapswithme.maps.editor.data;
+
+import android.support.annotation.NonNull;
+
+public class Timetable
+{
+ public final Timespan mWorkingTimespan;
+ public final Timespan[] mClosedTimespans;
+ public final boolean mIsFullday;
+ public final int[] mWeekdays;
+
+ public Timetable(String time)
+ {
+ // FIXME initialize correctly with string
+ mWorkingTimespan = new Timespan(new HoursMinutes(24, 0), new HoursMinutes(0, 0));
+ mClosedTimespans = new Timespan[0];
+ mWeekdays = new int[0];
+ mIsFullday = false;
+ }
+
+ public Timetable(@NonNull Timespan workingTime, @NonNull Timespan closedHours, boolean isFullday, @NonNull int[] weekdays)
+ {
+ this(workingTime, new Timespan[]{closedHours}, isFullday, weekdays);
+ }
+
+ public Timetable(@NonNull Timespan workingTime, @NonNull Timespan[] closedHours, boolean isFullday, @NonNull int[] weekdays)
+ {
+ mWorkingTimespan = workingTime;
+ mClosedTimespans = closedHours;
+ mIsFullday = isFullday;
+ mWeekdays = weekdays;
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append("Working timespan : ").append(mWorkingTimespan).append("\n")
+ .append("Closed timespans : ");
+ for (Timespan timespan : mClosedTimespans)
+ stringBuilder.append(timespan).append("\n");
+ stringBuilder.append("Fullday : ").append(mIsFullday).append("\n")
+ .append("Weekdays : ");
+ for (int i : mWeekdays)
+ stringBuilder.append(i);
+ return stringBuilder.toString();
+ }
+}
diff --git a/android/src/com/mapswithme/maps/widget/ToolbarController.java b/android/src/com/mapswithme/maps/widget/ToolbarController.java
index f202e584c6..013d9470f7 100644
--- a/android/src/com/mapswithme/maps/widget/ToolbarController.java
+++ b/android/src/com/mapswithme/maps/widget/ToolbarController.java
@@ -1,9 +1,11 @@
package com.mapswithme.maps.widget;
import android.app.Activity;
+import android.support.annotation.IdRes;
import android.support.annotation.StringRes;
import android.support.v7.widget.Toolbar;
import android.view.View;
+
import com.mapswithme.maps.R;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.Utils;
@@ -16,7 +18,7 @@ public class ToolbarController
public ToolbarController(View root, Activity activity)
{
mActivity = activity;
- mToolbar = (Toolbar) root.findViewById(R.id.toolbar);
+ mToolbar = (Toolbar) root.findViewById(getToolbarId());
UiUtils.showHomeUpButton(mToolbar);
mToolbar.setNavigationOnClickListener(new View.OnClickListener()
{
@@ -28,6 +30,11 @@ public class ToolbarController
});
}
+ protected @IdRes int getToolbarId()
+ {
+ return R.id.toolbar;
+ }
+
public void onUpClick()
{
Utils.navigateToParent(mActivity);
@@ -49,4 +56,9 @@ public class ToolbarController
{
return mToolbar;
}
+
+ public View findViewById(@IdRes int res)
+ {
+ return mToolbar.findViewById(res);
+ }
}
diff --git a/android/src/com/mapswithme/maps/widget/placepage/DirectionFragment.java b/android/src/com/mapswithme/maps/widget/placepage/DirectionFragment.java
index 1db0d3d4e4..557f664900 100644
--- a/android/src/com/mapswithme/maps/widget/placepage/DirectionFragment.java
+++ b/android/src/com/mapswithme/maps/widget/placepage/DirectionFragment.java
@@ -12,6 +12,7 @@ import android.widget.TextView;
import com.mapswithme.maps.Framework;
import com.mapswithme.maps.R;
+import com.mapswithme.maps.base.BaseMwmDialogFragment;
import com.mapswithme.maps.bookmarks.data.DistanceAndAzimut;
import com.mapswithme.maps.bookmarks.data.MapObject;
import com.mapswithme.maps.location.LocationHelper;
@@ -20,7 +21,7 @@ import com.mapswithme.util.LocationUtils;
import com.mapswithme.util.statistics.AlohaHelper;
import com.mapswithme.util.statistics.Statistics;
-public class DirectionFragment extends DialogFragment implements LocationHelper.LocationListener
+public class DirectionFragment extends BaseMwmDialogFragment implements LocationHelper.LocationListener
{
private static final String EXTRA_MAP_OBJECT = "MapObject";
diff --git a/android/src/com/mapswithme/maps/widget/placepage/HoursMinutesPickerFragment.java b/android/src/com/mapswithme/maps/widget/placepage/HoursMinutesPickerFragment.java
new file mode 100644
index 0000000000..cd6ab53f1a
--- /dev/null
+++ b/android/src/com/mapswithme/maps/widget/placepage/HoursMinutesPickerFragment.java
@@ -0,0 +1,154 @@
+package com.mapswithme.maps.widget.placepage;
+
+import android.annotation.SuppressLint;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.annotation.IntRange;
+import android.support.annotation.NonNull;
+import android.support.design.widget.TabLayout;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v7.app.AlertDialog;
+import android.text.format.DateFormat;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.TimePicker;
+
+import com.mapswithme.maps.R;
+import com.mapswithme.maps.base.BaseMwmDialogFragment;
+import com.mapswithme.maps.editor.data.HoursMinutes;
+
+public class HoursMinutesPickerFragment extends BaseMwmDialogFragment
+{
+ private static final String EXTRA_FROM = "HoursMinutesFrom";
+ private static final String EXTRA_TO = "HoursMinutesTo";
+ private static final String EXTRA_SELECT_FIRST = "SelectedTab";
+
+ public static final int TAB_FROM = 0;
+ public static final int TAB_TO = 1;
+
+ private HoursMinutes mFrom;
+ private HoursMinutes mTo;
+
+ private TimePicker mPicker;
+ @IntRange(from = 0, to = 1) private int mSelectedTab;
+ private TabLayout mTabs;
+
+ public interface OnPickListener
+ {
+ void onHoursMinutesPicked(HoursMinutes from, HoursMinutes to);
+ }
+
+ public static void pick(Context context, FragmentManager manager, @NonNull HoursMinutes from, @NonNull HoursMinutes to,
+ @IntRange(from = 0, to = 1) int selectedPosition)
+ {
+ final Bundle args = new Bundle();
+ args.putParcelable(EXTRA_FROM, from);
+ args.putParcelable(EXTRA_TO, to);
+ args.putInt(EXTRA_SELECT_FIRST, selectedPosition);
+ final HoursMinutesPickerFragment fragment = (HoursMinutesPickerFragment) Fragment.instantiate(context, HoursMinutesPickerFragment.class.getName(), args);
+ fragment.show(manager, null);
+ }
+
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ readArgs();
+ final View root = createView();
+ refreshPicker();
+ //noinspection ConstantConditions
+ mTabs.getTabAt(mSelectedTab).select();
+
+ final AlertDialog.Builder builder =
+ new AlertDialog.Builder(getActivity(), R.style.MwmMain_DialogFragment_TimePicker);
+ builder.setView(root)
+ .setNegativeButton(android.R.string.cancel, null)
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener()
+ {
+ @Override
+ public void onClick(DialogInterface dialog, int which)
+ {
+ saveHoursMinutes(mPicker.getCurrentHour(), mPicker.getCurrentMinute());
+ if (getParentFragment() instanceof OnPickListener)
+ ((OnPickListener) getParentFragment()).onHoursMinutesPicked(mFrom, mTo);
+ }
+ })
+ .setCancelable(true);
+
+ return builder.create();
+ }
+
+ private void readArgs()
+ {
+ final Bundle args = getArguments();
+ mFrom = args.getParcelable(EXTRA_FROM);
+ mTo = args.getParcelable(EXTRA_TO);
+ mSelectedTab = args.getInt(EXTRA_SELECT_FIRST);
+ }
+
+ private View createView()
+ {
+ final LayoutInflater inflater = LayoutInflater.from(getActivity());
+ @SuppressLint("InflateParams")
+ final View root = inflater.inflate(R.layout.fragment_timetable_picker, null);
+
+ mTabs = (TabLayout) root.findViewById(R.id.tabs);
+ TextView tabView = (TextView) inflater.inflate(R.layout.tab_timepicker, mTabs, false);
+ // TODO @yunik add translations
+ tabView.setText("From");
+ mTabs.addTab(mTabs.newTab().setCustomView(tabView), true);
+ tabView = (TextView) inflater.inflate(R.layout.tab_timepicker, mTabs, false);
+ tabView.setText("To");
+ mTabs.addTab(mTabs.newTab().setCustomView(tabView), true);
+ mTabs.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener()
+ {
+ @Override
+ public void onTabSelected(TabLayout.Tab tab)
+ {
+ mSelectedTab = tab.getPosition();
+ refreshPicker();
+ }
+
+ @Override
+ public void onTabUnselected(TabLayout.Tab tab)
+ {
+ saveHoursMinutes(mPicker.getCurrentHour(), mPicker.getCurrentMinute());
+ }
+
+ @Override
+ public void onTabReselected(TabLayout.Tab tab) {}
+ });
+
+ mPicker = (TimePicker) root.findViewById(R.id.picker);
+ mPicker.setIs24HourView(DateFormat.is24HourFormat(getActivity()));
+ mPicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
+ @Override
+ public void onTimeChanged(TimePicker view, int hourOfDay, int minute)
+ {
+ saveHoursMinutes(hourOfDay, minute);
+ }
+ });
+
+ return root;
+ }
+
+ private void saveHoursMinutes(int hourOfDay, int minute)
+ {
+ if (mSelectedTab == TAB_FROM)
+ mFrom = new HoursMinutes(hourOfDay, minute);
+ else
+ mTo = new HoursMinutes(hourOfDay, minute);
+ }
+
+ private void refreshPicker()
+ {
+ final HoursMinutes hoursMinutes = mSelectedTab == TAB_FROM ? mFrom : mTo;
+ mPicker.setCurrentHour((int) hoursMinutes.mHours);
+ mPicker.setCurrentMinute((int) hoursMinutes.mMinutes);
+ }
+}
diff --git a/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java b/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java
index 7e4e64e7ca..d2be0d0a3a 100644
--- a/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java
+++ b/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java
@@ -728,7 +728,6 @@ public class PlacePageView extends RelativeLayout implements View.OnClickListene
case R.id.ll__place_editor:
showEditor();
break;
-
case R.id.iv__bookmark_color:
saveBookmarkNameIfUpdated();
selectBookmarkColor();
diff --git a/android/src/com/mapswithme/maps/widget/placepage/SimpleTimetableAdapter.java b/android/src/com/mapswithme/maps/widget/placepage/SimpleTimetableAdapter.java
new file mode 100644
index 0000000000..8d05e0e09a
--- /dev/null
+++ b/android/src/com/mapswithme/maps/widget/placepage/SimpleTimetableAdapter.java
@@ -0,0 +1,386 @@
+package com.mapswithme.maps.widget.placepage;
+
+import android.support.annotation.IdRes;
+import android.support.v4.app.Fragment;
+import android.support.v7.widget.RecyclerView;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import com.mapswithme.maps.R;
+import com.mapswithme.maps.editor.OpeningHours;
+import com.mapswithme.maps.editor.data.HoursMinutes;
+import com.mapswithme.maps.editor.data.Timespan;
+import com.mapswithme.maps.editor.data.Timetable;
+import com.mapswithme.util.UiUtils;
+
+public class SimpleTimetableAdapter extends RecyclerView.Adapter<SimpleTimetableAdapter.BaseTimetableViewHolder>
+ implements HoursMinutesPickerFragment.OnPickListener,
+ TimetableFragment.TimetableProvider
+{
+ private static final int TYPE_TIMETABLE = 0;
+ private static final int TYPE_ADD_TIMETABLE = 1;
+
+ private final Fragment mFragment;
+
+ private List<Timetable> mItems = new ArrayList<>();
+ private Timetable mComplementItem;
+ private int mPickingPosition;
+
+ SimpleTimetableAdapter(Fragment fragment)
+ {
+ mFragment = fragment;
+ mItems = new ArrayList<>(Arrays.asList(OpeningHours.nativeGetDefaultTimetables()));
+ }
+
+ public void setTimetables(Timetable[] tts)
+ {
+ mItems = new ArrayList<>(Arrays.asList(tts));
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public Timetable[] getTimetables()
+ {
+ return mItems.toArray(new Timetable[mItems.size()]);
+ }
+
+ @Override
+ public BaseTimetableViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
+ {
+ final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
+ return viewType == TYPE_TIMETABLE ? new TimetableViewHolder(inflater.inflate(R.layout.item_timetable, parent, false))
+ : new AddTimetableViewHolder(inflater.inflate(R.layout.item_timetable_add, parent, false));
+ }
+
+ @Override
+ public void onBindViewHolder(BaseTimetableViewHolder holder, int position)
+ {
+ holder.onBind();
+ }
+
+ @Override
+ public int getItemCount()
+ {
+ return mItems.size() + 1;
+ }
+
+ @Override
+ public int getItemViewType(int position)
+ {
+ return position == getItemCount() - 1 ? TYPE_ADD_TIMETABLE
+ : TYPE_TIMETABLE;
+ }
+
+ protected void addTimetable()
+ {
+ mItems.add(OpeningHours.nativeGetComplementTimetable(mItems.toArray(new Timetable[mItems.size()])));
+ printItems();
+ notifyItemInserted(mItems.size() - 1);
+ refreshComplement();
+ }
+
+ protected void removeTimetable(int position)
+ {
+ mItems.remove(position);
+ printItems();
+ notifyItemRemoved(position);
+ refreshComplement();
+ }
+
+ protected void refreshComplement()
+ {
+ mComplementItem = OpeningHours.nativeGetComplementTimetable(mItems.toArray(new Timetable[mItems.size()]));
+ notifyItemChanged(getItemCount() - 1);
+ }
+
+ protected void pickTime(int position, int tab)
+ {
+ final Timetable data = mItems.get(position);
+ mPickingPosition = position;
+ HoursMinutesPickerFragment.pick(mFragment.getActivity(), mFragment.getChildFragmentManager(),
+ data.mWorkingTimespan.mStart,
+ data.mWorkingTimespan.mEnd,
+ tab);
+ }
+
+ @Override
+ public void onHoursMinutesPicked(HoursMinutes from, HoursMinutes to)
+ {
+ mItems.set(mPickingPosition, OpeningHours.nativeSetOpeningTime(mItems.get(mPickingPosition), new Timespan(from, to)));
+ printItems();
+ notifyItemChanged(mPickingPosition);
+ }
+
+ protected void addWorkingDay(int day, int position)
+ {
+ final Timetable tts[] = mItems.toArray(new Timetable[mItems.size()]);
+ mItems = new ArrayList<>(Arrays.asList(OpeningHours.nativeAddWorkingDay(tts, position, day)));
+ refreshComplement();
+ printItems();
+ notifyDataSetChanged();
+ }
+
+ protected void removeWorkingDay(int day, int position)
+ {
+ final Timetable tts[] = mItems.toArray(new Timetable[mItems.size()]);
+ mItems = new ArrayList<>(Arrays.asList(OpeningHours.nativeRemoveWorkingDay(tts, position, day)));
+ refreshComplement();
+ printItems();
+ notifyDataSetChanged();
+ }
+
+ // FIXME remove
+ private void printItems()
+ {
+ Log.d("TEST", "Items : \n");
+ for (Timetable tt : mItems)
+ Log.d("TEST", tt.toString() + "\n");
+ }
+
+ private void setFullday(int position, boolean fullday)
+ {
+ mItems.set(position, OpeningHours.nativeSetIsFullday(mItems.get(position), fullday));
+ notifyItemChanged(position);
+ }
+
+ public abstract class BaseTimetableViewHolder extends RecyclerView.ViewHolder
+ {
+ public BaseTimetableViewHolder(View itemView)
+ {
+ super(itemView);
+ }
+
+ abstract void onBind();
+ }
+
+ public class TimetableViewHolder extends BaseTimetableViewHolder implements View.OnClickListener, CompoundButton.OnCheckedChangeListener
+ {
+ TextView day1Text;
+ TextView day2Text;
+ TextView day3Text;
+ TextView day4Text;
+ TextView day5Text;
+ TextView day6Text;
+ TextView day7Text;
+ SparseArray<CheckBox> days = new SparseArray<>(7);
+ View allday;
+ Switch swAllday;
+ View schedule;
+ View openClose;
+ View open;
+ View close;
+ TextView tvOpen;
+ TextView tvClose;
+ View addClosed;
+ View deleteTimetable;
+
+ public TimetableViewHolder(View itemView)
+ {
+ super(itemView);
+ addDay(R.id.chb__day_1, 1);
+ addDay(R.id.chb__day_2, 2);
+ addDay(R.id.chb__day_3, 3);
+ addDay(R.id.chb__day_4, 4);
+ addDay(R.id.chb__day_5, 5);
+ addDay(R.id.chb__day_6, 6);
+ addDay(R.id.chb__day_7, 7);
+ fillDaysTexts();
+ final int[] daysIds = new int[]{R.id.day1, R.id.day2, R.id.day3, R.id.day4, R.id.day5, R.id.day6, R.id.day7};
+ for (int i = 0; i < 7; i++)
+ {
+ final int finalI = i;
+ itemView.findViewById(daysIds[i]).setOnClickListener(new View.OnClickListener()
+ {
+ @Override
+ public void onClick(View v)
+ {
+ days.get(finalI + 1).toggle();
+ }
+ });
+ }
+
+ allday = itemView.findViewById(R.id.allday);
+ allday.setOnClickListener(this);
+ swAllday = (Switch) allday.findViewById(R.id.sw__allday);
+ schedule = itemView.findViewById(R.id.schedule);
+ openClose = schedule.findViewById(R.id.time_open_close);
+ open = openClose.findViewById(R.id.time_open);
+ open.setOnClickListener(this);
+ close = openClose.findViewById(R.id.time_close);
+ close.setOnClickListener(this);
+ tvOpen = (TextView) open.findViewById(R.id.tv__time_open);
+ tvClose = (TextView) close.findViewById(R.id.tv__time_close);
+ addClosed = schedule.findViewById(R.id.tv__add_closed);
+ addClosed.setOnClickListener(this);
+ deleteTimetable = itemView.findViewById(R.id.tv__remove_timetable);
+ deleteTimetable.setOnClickListener(this);
+ }
+
+ @Override
+ void onBind()
+ {
+ final int position = getAdapterPosition();
+ final Timetable data = mItems.get(position);
+ UiUtils.showIf(position > 0, deleteTimetable);
+ tvOpen.setText(workingTime(data.mWorkingTimespan.mStart));
+ tvClose.setText(workingTime(data.mWorkingTimespan.mEnd));
+ showDays(data.mWeekdays);
+ showSchedule(!data.mIsFullday);
+ }
+
+ private String workingTime(HoursMinutes hoursMinutes)
+ {
+ // TODO @yunik add proper translated strings
+ return String.format("%02d", Long.valueOf(hoursMinutes.mHours))
+ + ":"
+ + String.format("%02d", Long.valueOf(hoursMinutes.mMinutes));
+ }
+
+ @Override
+ public void onClick(View v)
+ {
+ switch (v.getId())
+ {
+ case R.id.time_open:
+ pickTime(getAdapterPosition(), HoursMinutesPickerFragment.TAB_FROM);
+ break;
+ case R.id.time_close:
+ pickTime(getAdapterPosition(), HoursMinutesPickerFragment.TAB_TO);
+ break;
+ case R.id.tv__remove_timetable:
+ removeTimetable(getAdapterPosition());
+ break;
+ case R.id.closed:
+ // TODO @yunik
+ break;
+ case R.id.allday:
+ swAllday.toggle();
+ break;
+ }
+ }
+
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
+ {
+ switch (buttonView.getId())
+ {
+ case R.id.sw__allday:
+ setFullday(getAdapterPosition(), isChecked);
+ break;
+ case R.id.chb__day_1:
+ switchWorkingDay(1);
+ break;
+ case R.id.chb__day_2:
+ switchWorkingDay(2);
+ break;
+ case R.id.chb__day_3:
+ switchWorkingDay(3);
+ break;
+ case R.id.chb__day_4:
+ switchWorkingDay(4);
+ break;
+ case R.id.chb__day_5:
+ switchWorkingDay(5);
+ break;
+ case R.id.chb__day_6:
+ switchWorkingDay(6);
+ break;
+ case R.id.chb__day_7:
+ switchWorkingDay(7);
+ break;
+ }
+ }
+
+ void showSchedule(boolean show)
+ {
+ UiUtils.showIf(show, schedule);
+ checkWithoutCallback(swAllday, !show);
+ }
+
+ void showDays(int[] weekdays)
+ {
+ for (int i = 1; i <= 7; i++)
+ checkWithoutCallback(days.get(i), false);
+
+ for (int checked : weekdays)
+ checkWithoutCallback(days.get(checked), true);
+ }
+
+ private void addDay(@IdRes int res, final int dayIndex)
+ {
+ days.put(dayIndex, (CheckBox) itemView.findViewById(res));
+ }
+
+ private void switchWorkingDay(int day)
+ {
+ final CheckBox checkBox = days.get(day);
+ if (checkBox.isChecked())
+ addWorkingDay(day, getAdapterPosition());
+ else
+ removeWorkingDay(day, getAdapterPosition());
+ }
+
+ private void fillDaysTexts()
+ {
+ day1Text = (TextView) itemView.findViewById(R.id.tv__day_1);
+ day2Text = (TextView) itemView.findViewById(R.id.tv__day_2);
+ day3Text = (TextView) itemView.findViewById(R.id.tv__day_3);
+ day4Text = (TextView) itemView.findViewById(R.id.tv__day_4);
+ day5Text = (TextView) itemView.findViewById(R.id.tv__day_5);
+ day6Text = (TextView) itemView.findViewById(R.id.tv__day_6);
+ day7Text = (TextView) itemView.findViewById(R.id.tv__day_7);
+ // FIXME @yunik localize texts
+ day1Text.setText("Su");
+ day2Text.setText("Mo");
+ day3Text.setText("Tu");
+ day4Text.setText("We");
+ day5Text.setText("Th");
+ day6Text.setText("Fr");
+ day7Text.setText("Sa");
+ }
+
+ private void checkWithoutCallback(CompoundButton button, boolean check)
+ {
+ button.setOnCheckedChangeListener(null);
+ button.setChecked(check);
+ button.setOnCheckedChangeListener(this);
+ }
+ }
+
+ private class AddTimetableViewHolder extends BaseTimetableViewHolder
+ {
+ private TextView add;
+
+ public AddTimetableViewHolder(View itemView)
+ {
+ super(itemView);
+ add = (TextView) itemView.findViewById(R.id.btn__add_time);
+ add.setOnClickListener(new View.OnClickListener()
+ {
+ @Override
+ public void onClick(View v)
+ {
+ addTimetable();
+ }
+ });
+ }
+
+ @Override
+ void onBind()
+ {
+ // TODO @yunik add text with complement days
+ add.setEnabled(mComplementItem != null && mComplementItem.mWeekdays.length != 0);
+ }
+ }
+}
diff --git a/android/src/com/mapswithme/maps/widget/placepage/TimetableAdvancedFragment.java b/android/src/com/mapswithme/maps/widget/placepage/TimetableAdvancedFragment.java
new file mode 100644
index 0000000000..304bfe73f8
--- /dev/null
+++ b/android/src/com/mapswithme/maps/widget/placepage/TimetableAdvancedFragment.java
@@ -0,0 +1,105 @@
+package com.mapswithme.maps.widget.placepage;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.ImageView;
+
+import com.mapswithme.maps.R;
+import com.mapswithme.maps.base.BaseMwmFragment;
+import com.mapswithme.maps.editor.OpeningHours;
+import com.mapswithme.maps.editor.data.Timetable;
+import com.mapswithme.util.UiUtils;
+
+public class TimetableAdvancedFragment extends BaseMwmFragment
+ implements View.OnClickListener,
+ TimetableFragment.TimetableProvider
+{
+ private boolean mIsExampleShown;
+ private EditText mInput;
+ private View mExample;
+ private ImageView mIndicator;
+ private Timetable[] mInitTts;
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
+ {
+ return inflater.inflate(R.layout.fragment_timetable_advanced, container, false);
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
+ {
+ super.onViewCreated(view, savedInstanceState);
+ initViews(view);
+ refreshTts();
+ hideExample();
+ }
+
+ @Override
+ public void onViewStateRestored(@Nullable Bundle savedInstanceState)
+ {
+ super.onViewStateRestored(savedInstanceState);
+ refreshTts();
+ }
+
+ private void initViews(View view)
+ {
+ view.findViewById(R.id.examples).setOnClickListener(this);
+ mInput = (EditText) view.findViewById(R.id.et__timetable);
+ mExample = view.findViewById(R.id.tv__examples);
+ mIndicator = (ImageView) view.findViewById(R.id.iv__indicator);
+ }
+
+ private void showExample()
+ {
+ mIsExampleShown = true;
+ UiUtils.show(mExample);
+ // TODO yunikkk animate indicator
+ mIndicator.setImageResource(R.drawable.ic_expand_less);
+ }
+
+ private void hideExample()
+ {
+ mIsExampleShown = false;
+ UiUtils.hide(mExample);
+ mIndicator.setImageResource(R.drawable.ic_expand_more);
+ }
+
+ @Override
+ public void onClick(View v)
+ {
+ switch (v.getId())
+ {
+ case R.id.examples:
+ if (mIsExampleShown)
+ hideExample();
+ else
+ showExample();
+ }
+ }
+
+ @Override
+ public Timetable[] getTimetables()
+ {
+ if (mInput.length() == 0)
+ return OpeningHours.nativeGetDefaultTimetables();
+ return OpeningHours.nativeTimetablesFromString(mInput.getText().toString());
+ }
+
+ public void setTimetables(Timetable[] tts)
+ {
+ mInitTts = tts;
+ refreshTts();
+ }
+
+ private void refreshTts()
+ {
+ if (mInput != null && mInitTts != null)
+ mInput.setText(OpeningHours.nativeTimetablesToString(mInitTts));
+ }
+}
diff --git a/android/src/com/mapswithme/maps/widget/placepage/TimetableFragment.java b/android/src/com/mapswithme/maps/widget/placepage/TimetableFragment.java
new file mode 100644
index 0000000000..9135345511
--- /dev/null
+++ b/android/src/com/mapswithme/maps/widget/placepage/TimetableFragment.java
@@ -0,0 +1,151 @@
+package com.mapswithme.maps.widget.placepage;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.mapswithme.maps.R;
+import com.mapswithme.maps.base.BaseMwmToolbarFragment;
+import com.mapswithme.maps.base.OnBackPressListener;
+import com.mapswithme.maps.editor.OpeningHours;
+import com.mapswithme.maps.editor.data.Timetable;
+import com.mapswithme.util.UiUtils;
+import com.mapswithme.util.Utils;
+
+public class TimetableFragment extends BaseMwmToolbarFragment
+ implements View.OnClickListener,
+ OnBackPressListener
+{
+ interface TimetableProvider
+ {
+ Timetable[] getTimetables();
+ }
+
+ public static final String EXTRA_TIME = "Time";
+
+ private boolean mIsAdvancedMode;
+
+ private TextView mSwitchMode;
+
+ private TimetableSimpleFragment mSimpleModeFragment;
+ private TimetableAdvancedFragment mAdvancedModeFragment;
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
+ {
+ return inflater.inflate(R.layout.fragment_timetable, container, false);
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
+ {
+ super.onViewCreated(view, savedInstanceState);
+
+ initViews(view);
+ simpleMode();
+
+ final Bundle args = getArguments();
+ if (args != null && args.containsKey(EXTRA_TIME))
+ mSimpleModeFragment.setTimetables(OpeningHours.nativeTimetablesFromString(args.getString(EXTRA_TIME)));
+ }
+
+ private void initViews(View root)
+ {
+ mToolbarController.setTitle(R.string.editor_time_title);
+ mToolbarController.findViewById(R.id.iv__submit).setOnClickListener(this);
+ mSwitchMode = (TextView) root.findViewById(R.id.tv__mode_switch);
+ mSwitchMode.setOnClickListener(this);
+ }
+
+ @Override
+ public void onClick(View v)
+ {
+ switch (v.getId())
+ {
+ case R.id.tv__mode_switch:
+ switchMode();
+ break;
+ case R.id.iv__submit:
+ saveTimetable();
+ }
+ }
+
+ @Override
+ public boolean onBackPressed()
+ {
+ return false;
+ }
+
+ private void switchMode()
+ {
+ if (mIsAdvancedMode)
+ simpleMode();
+ else
+ advancedMode();
+ }
+
+ private void simpleMode()
+ {
+ mIsAdvancedMode = false;
+ mSwitchMode.setText(R.string.editor_time_advanced);
+ final Timetable[] filledTts = getFilledTimetables(mAdvancedModeFragment, mAdvancedModeFragment);
+ mSimpleModeFragment = (TimetableSimpleFragment) attachFragment(mSimpleModeFragment, TimetableSimpleFragment.class.getName());
+ mSimpleModeFragment.setTimetables(filledTts);
+ }
+
+ private void advancedMode()
+ {
+ mIsAdvancedMode = true;
+ mSwitchMode.setText(R.string.editor_time_simple);
+ final Timetable[] filledTts = getFilledTimetables(mSimpleModeFragment, mSimpleModeFragment);
+ mAdvancedModeFragment = (TimetableAdvancedFragment) attachFragment(mAdvancedModeFragment, TimetableAdvancedFragment.class.getName());
+ mAdvancedModeFragment.setTimetables(filledTts);
+ }
+
+ private boolean hasFilledTimetables(Fragment fragment)
+ {
+ return fragment != null && fragment.isAdded();
+ }
+
+ private Timetable[] getFilledTimetables(Fragment fragment, TimetableProvider provider)
+ {
+ if (!hasFilledTimetables(fragment))
+ return null;
+
+ final Timetable[] tts = provider.getTimetables();
+ if (tts == null)
+ {
+ // FIXME @yunikkk add correct text
+ UiUtils.showAlertDialog(getActivity(), R.string.dialog_routing_system_error);
+ return null;
+ }
+
+ return tts;
+ }
+
+ private Fragment attachFragment(Fragment current, String className)
+ {
+ Fragment fragment = current == null ? Fragment.instantiate(getActivity(), className)
+ : current;
+ getChildFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment).commit();
+ return fragment;
+ }
+
+ private void saveTimetable()
+ {
+ if (mIsAdvancedMode)
+ mAdvancedModeFragment.getTimetables();
+ else
+ mSimpleModeFragment.getTimetables();
+
+ final Timetable[] tts = mIsAdvancedMode ? mAdvancedModeFragment.getTimetables() : mSimpleModeFragment.getTimetables();
+ // TODO @yunikkk or @deathbaba save tts to the core
+
+ Utils.navigateToParent(getActivity());
+ }
+}
diff --git a/android/src/com/mapswithme/maps/widget/placepage/TimetableSimpleFragment.java b/android/src/com/mapswithme/maps/widget/placepage/TimetableSimpleFragment.java
new file mode 100644
index 0000000000..5a25d68e8e
--- /dev/null
+++ b/android/src/com/mapswithme/maps/widget/placepage/TimetableSimpleFragment.java
@@ -0,0 +1,68 @@
+package com.mapswithme.maps.widget.placepage;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.mapswithme.maps.R;
+import com.mapswithme.maps.base.BaseMwmRecyclerFragment;
+import com.mapswithme.maps.editor.data.HoursMinutes;
+import com.mapswithme.maps.editor.data.Timetable;
+
+public class TimetableSimpleFragment extends BaseMwmRecyclerFragment
+ implements TimetableFragment.TimetableProvider,
+ HoursMinutesPickerFragment.OnPickListener
+{
+ private SimpleTimetableAdapter mAdapter;
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected RecyclerView.Adapter createAdapter()
+ {
+ if (mAdapter == null)
+ mAdapter = new SimpleTimetableAdapter(this);
+ return mAdapter;
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
+ {
+ return inflater.inflate(R.layout.fragment_timetable_simple, container, false);
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
+ {
+ super.onViewCreated(view, savedInstanceState);
+ }
+
+ @Override
+ public Timetable[] getTimetables()
+ {
+ return mAdapter.getTimetables();
+ }
+
+ @Override
+ public void onHoursMinutesPicked(HoursMinutes from, HoursMinutes to)
+ {
+ mAdapter.onHoursMinutesPicked(from, to);
+ }
+
+ public void setTimetables(Timetable[] tts)
+ {
+ if (tts == null)
+ return;
+
+ createAdapter();
+ mAdapter.setTimetables(tts);
+ }
+}