-
-
Notifications
You must be signed in to change notification settings - Fork 688
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[widget audit] toga.DateInput, toga.TimeInput #1951
Changes from 20 commits
e872383
390b785
b52d3da
c89a123
02f1036
111842f
ea0f7bf
a01c78c
4ba446b
99478b6
a99b4ee
ef36395
5238706
614bea1
8128400
7cbc5c1
ce7b0a0
b265eb1
f746aee
ab3765c
457a00b
7cd87bf
0eeba0a
fb572b8
a6a020a
b9fa936
94244f8
96f30ea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
from datetime import date, datetime, time | ||
|
||
from ..libs.android import R__drawable | ||
from ..libs.android.widget import ( | ||
DatePickerDialog, | ||
DatePickerDialog__OnDateSetListener as OnDateSetListener, | ||
) | ||
from .internal.pickers import PickerBase | ||
|
||
NO_MIN = date(1799, 1, 1) | ||
NO_MAX = date(9999, 1, 1) | ||
|
||
|
||
def py_date(native_date): | ||
return date.fromtimestamp(native_date / 1000) | ||
|
||
|
||
def native_date(py_date): | ||
return int(datetime.combine(py_date, time.min).timestamp() * 1000) | ||
|
||
|
||
class DatePickerListener(OnDateSetListener): | ||
def __init__(self, impl): | ||
super().__init__() | ||
self.impl = impl | ||
|
||
def onDateSet(self, view, year, month_0, day): | ||
self.impl.set_value(date(year, month_0 + 1, day)) | ||
|
||
|
||
class DateInput(PickerBase): | ||
@classmethod | ||
def _get_icon(cls): | ||
return R__drawable.ic_menu_my_calendar | ||
|
||
def create(self): | ||
super().create() | ||
self.native.setText("1970-01-01") # Dummy value used during initialization | ||
|
||
def get_value(self): | ||
return date.fromisoformat(str(self.native.getText())) | ||
|
||
def set_value(self, value): | ||
self.native.setText(value.isoformat()) | ||
self._dialog.updateDate(value.year, value.month - 1, value.day) | ||
self.interface.on_change(None) | ||
|
||
def get_min_date(self): | ||
result = py_date(self._picker.getMinDate()) | ||
return None if (result == NO_MIN) else result | ||
|
||
def set_min_date(self, value): | ||
self._picker.setMinDate(native_date(NO_MIN if value is None else value)) | ||
|
||
def get_max_date(self): | ||
result = py_date(self._picker.getMaxDate()) | ||
return None if (result == NO_MAX) else result | ||
|
||
def set_max_date(self, value): | ||
self._picker.setMaxDate(native_date(NO_MAX if value is None else value)) | ||
|
||
def _create_dialog(self): | ||
return DatePickerDialog( | ||
self._native_activity, | ||
DatePickerListener(self), | ||
2000, # year | ||
0, # month (0 = January) | ||
1, # day | ||
) | ||
|
||
@property | ||
def _picker(self): | ||
return self._dialog.getDatePicker() |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
from datetime import time | ||
|
||
from ..libs.android import R__drawable | ||
from ..libs.android.widget import ( | ||
TimePickerDialog, | ||
TimePickerDialog__OnTimeSetListener as OnTimeSetListener, | ||
) | ||
from .internal.pickers import PickerBase | ||
|
||
|
||
class TimePickerListener(OnTimeSetListener): | ||
def __init__(self, impl): | ||
super().__init__() | ||
self.impl = impl | ||
|
||
def onTimeSet(self, view, hour, minute): | ||
self.impl.set_value(time(hour, minute)) | ||
|
||
|
||
class TimeInput(PickerBase): | ||
@classmethod | ||
def _get_icon(cls): | ||
return R__drawable.ic_menu_recent_history | ||
|
||
def create(self): | ||
super().create() | ||
|
||
# Dummy values used during initialization | ||
self.native.setText("00:00") | ||
self._min_time = None | ||
self._max_time = None | ||
|
||
def get_value(self): | ||
return time.fromisoformat(str(self.native.getText())) | ||
|
||
def set_value(self, value): | ||
self.native.setText(value.isoformat(timespec="minutes")) | ||
self._dialog.updateTime(value.hour, value.minute) | ||
self.interface.on_change(None) | ||
|
||
# Unlike DatePicker, TimePicker does not natively support min or max, so these | ||
# properties currently have no effect. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it be worth doing a "soft" min/max? i.e., we have control over |
||
def get_min_time(self): | ||
return self._min_time | ||
|
||
def set_min_time(self, value): | ||
self._min_time = value | ||
|
||
def get_max_time(self): | ||
return self._max_time | ||
|
||
def set_max_time(self, value): | ||
self._max_time = value | ||
|
||
def _create_dialog(self): | ||
return TimePickerDialog( | ||
self._native_activity, | ||
TimePickerListener(self), | ||
0, # hour | ||
0, # minute | ||
True, # is24HourView | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these values with a significance to Android? We should document why these dates in particular has been picked - both in the code, and in the user-facing widget notes as a functional limitation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, I've changed the implementation to allow years between 1800 and 8999 on all platforms, and updated the documentation to match.