mirror of
https://github.com/google/pebble.git
synced 2025-07-14 02:01:59 -04:00
109 lines
3.5 KiB
C
109 lines
3.5 KiB
C
/*
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "date_time_selection_window_private.h"
|
|
|
|
#include "services/common/clock.h"
|
|
#include "services/common/i18n/i18n.h"
|
|
#include "util/date.h"
|
|
#include "util/math.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
static const int MIN_SELECTABLE_YEAR = 2010;
|
|
static const int MAX_SELECTABLE_YEAR = 2037; // Work around Y2038 problem
|
|
|
|
static int prv_wrap(int x, int max, int delta) {
|
|
x = (x + delta) % max;
|
|
return x < 0 ? x + max : x;
|
|
}
|
|
|
|
int date_time_selection_step_hour(int hour, int delta) {
|
|
return prv_wrap(hour, 24, delta);
|
|
}
|
|
|
|
int date_time_selection_step_minute(int minute, int delta) {
|
|
return prv_wrap(minute, 60, delta);
|
|
}
|
|
|
|
int date_time_selection_step_day(int year, int month, int day, int delta) {
|
|
bool is_leap_year = date_util_is_leap_year(year);
|
|
// This function expects Jan == 0, but date_util_get_max_days_in_month expects Jan == 1
|
|
int max_days = date_util_get_max_days_in_month(month + 1, is_leap_year);
|
|
// This functions expects the first day of the month is 1, but wrap expects the first day of the
|
|
// month is 0 (based off the mday element of the "tm" struct)
|
|
return prv_wrap(day - 1, max_days, delta) + 1;
|
|
}
|
|
|
|
int date_time_selection_step_month(int month, int delta) {
|
|
return prv_wrap(month, 12, delta);
|
|
}
|
|
|
|
int date_time_selection_truncate_date(int year, int month, int day) {
|
|
bool is_leap_year = date_util_is_leap_year(year);
|
|
|
|
// date_util_get_max_days_in_month expects Jan == 1, but this function expects Jan == 0
|
|
int max_days = date_util_get_max_days_in_month(month + 1, is_leap_year);
|
|
return MIN(day, max_days);
|
|
}
|
|
|
|
int date_time_selection_step_year(int year, int delta) {
|
|
year += delta;
|
|
return CLIP(year, MIN_SELECTABLE_YEAR - STDTIME_YEAR_OFFSET,
|
|
MAX_SELECTABLE_YEAR - STDTIME_YEAR_OFFSET);
|
|
}
|
|
|
|
char *date_time_selection_get_text(TimeData *data, TimeInputIndex index, char *buf) {
|
|
switch (index) {
|
|
case TimeInputIndexHour: {
|
|
unsigned hour = data->hour;
|
|
if (!clock_is_24h_style()) {
|
|
hour = hour % 12;
|
|
if (hour == 0) {
|
|
hour = 12;
|
|
}
|
|
}
|
|
snprintf(buf, 3, "%02u", hour);
|
|
return buf;
|
|
}
|
|
case TimeInputIndexMinute:
|
|
snprintf(buf, 3, "%02u", data->minute);
|
|
return buf;
|
|
case TimeInputIndexAMPM: // We should only get this in 12h style
|
|
if (data->hour < 12) {
|
|
i18n_get_with_buffer("AM", buf, 3);
|
|
} else {
|
|
i18n_get_with_buffer("PM", buf, 3);
|
|
}
|
|
return buf;
|
|
default:
|
|
return "";
|
|
}
|
|
}
|
|
|
|
void date_time_handle_time_change(TimeData *data, TimeInputIndex index, int delta) {
|
|
switch (index) {
|
|
case TimeInputIndexHour:
|
|
data->hour = date_time_selection_step_hour(data->hour, delta);
|
|
break;
|
|
case TimeInputIndexMinute:
|
|
data->minute = date_time_selection_step_minute(data->minute, delta);
|
|
break;
|
|
case TimeInputIndexAMPM: // We should only get this in 12h style
|
|
data->hour = date_time_selection_step_hour(data->hour, 12 * delta);
|
|
break;
|
|
}
|
|
}
|