diff --git a/README.md b/README.md
index 8495d007..de83d890 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,9 @@ This README is being written.
## Announcements
+* **13 May 2018**
+ * Added new functions to work with uiDateTimePickers: `uiDateTimePickerTime()`, `uiDateTimePickerSetTime()`, and `uiDateTimePickerOnChanged()`. These operate on standard `` `struct tm`s. Thanks @cody271!
+
* **2 May 2018**
* On Windows, you no longer need to carry around a `libui.res` file with static builds. You do need to link in the appropriate manifest file, such as the one in the `windows/` folder (I still need to figure out exactly what is needed apart from the Common Controls v6 dependency, or at least to create a complete-ish template), or at least include it alongside your executables. This also means you should no longer see random cmake errors when building the static libraries.
diff --git a/darwin/datetimepicker.m b/darwin/datetimepicker.m
index 54c6ba38..d4424678 100644
--- a/darwin/datetimepicker.m
+++ b/darwin/datetimepicker.m
@@ -8,8 +8,10 @@ struct uiDateTimePicker {
void *onChangedData;
};
-@interface uiprivDatePickerDelegateClass : NSObject {
- struct uiprivMap *pickers;
+// TODO see if target-action works here or not; I forgot what cody271@ originally said
+// the primary advantage of the delegate is the ability to reject changes, but libui doesn't support that yet — we should consider that API option as well
+@interface uiprivDatePickerDelegateClass : NSObject {
+ uiprivMap *pickers;
}
- (void)datePickerCell:(NSDatePickerCell *)aDatePickerCell validateProposedDateValue:(NSDate **)proposedDateValue timeInterval:(NSTimeInterval *)proposedTimeInterval;
- (void)doTimer:(NSTimer *)timer;
@@ -33,13 +35,11 @@ struct uiDateTimePicker {
[super dealloc];
}
-- (void)datePickerCell:(NSDatePickerCell *)aDatePickerCell
- validateProposedDateValue:(NSDate **)proposedDateValue
- timeInterval:(NSTimeInterval *)proposedTimeInterval
+- (void)datePickerCell:(NSDatePickerCell *)cell validateProposedDateValue:(NSDate **)proposedDateValue timeInterval:(NSTimeInterval *)proposedTimeInterval
{
uiDateTimePicker *d;
- d = (uiDateTimePicker *) uiprivMapGet(self->pickers, aDatePickerCell);
+ d = (uiDateTimePicker *) uiprivMapGet(self->pickers, cell);
[NSTimer scheduledTimerWithTimeInterval:0
target:self
selector:@selector(doTimer:)
@@ -49,9 +49,11 @@ struct uiDateTimePicker {
- (void)doTimer:(NSTimer *)timer
{
+ NSValue *v;
uiDateTimePicker *d;
- d = (uiDateTimePicker *) [((NSValue *)[timer userInfo]) pointerValue];
+ v = (NSValue *) [timer userInfo];
+ d = (uiDateTimePicker *) [v pointerValue];
(*(d->onChanged))(d, d->onChangedData);
}
@@ -78,6 +80,7 @@ static void defaultOnChanged(uiDateTimePicker *d, void *data)
// do nothing
}
+// TODO consider using NSDateComponents iff we ever need the extra accuracy of not using NSTimeInterval
void uiDateTimePickerTime(uiDateTimePicker *d, struct tm *time)
{
time_t t;
@@ -90,7 +93,7 @@ void uiDateTimePickerTime(uiDateTimePicker *d, struct tm *time)
// Copy time to minimize a race condition
// time.h functions use global non-thread-safe data
tmbuf = *localtime(&t);
- memcpy(time, &tmbuf, sizeof(struct tm));
+ memcpy(time, &tmbuf, sizeof (struct tm));
}
void uiDateTimePickerSetTime(uiDateTimePicker *d, const struct tm *time)
@@ -99,7 +102,7 @@ void uiDateTimePickerSetTime(uiDateTimePicker *d, const struct tm *time)
struct tm tmbuf;
// Copy time because mktime() modifies its argument
- memcpy(&tmbuf, time, sizeof(struct tm));
+ memcpy(&tmbuf, time, sizeof (struct tm));
t = mktime(&tmbuf);
[d->dp setDateValue:[NSDate dateWithTimeIntervalSince1970:t]];
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 4c049b9a..b68f9706 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -23,11 +23,6 @@ _add_example(histogram
${_EXAMPLE_RESOURCES_RC}
)
-_add_example(datetime
- datetime/main.c
- ${_EXAMPLE_RESOURCES_RC}
-)
-
_add_example(cpp-multithread
cpp-multithread/main.cpp
${_EXAMPLE_RESOURCES_RC}
@@ -52,11 +47,16 @@ _add_example(timer
${_EXAMPLE_RESOURCES_RC}
)
+_add_example(datetime
+ datetime/main.c
+ ${_EXAMPLE_RESOURCES_RC}
+)
+
add_custom_target(examples
DEPENDS
controlgallery
histogram
cpp-multithread
drawtext
- datetime
- timer)
+ timer
+ datetime)
diff --git a/examples/datetime/main.c b/examples/datetime/main.c
index e71b54a6..faf2c2f4 100644
--- a/examples/datetime/main.c
+++ b/examples/datetime/main.c
@@ -17,7 +17,6 @@ const char *timeFormat(uiDateTimePicker *d)
fmt = "%X";
else
fmt = "";
-
return fmt;
}
@@ -59,14 +58,19 @@ int onClosing(uiWindow *w, void *data)
int main(void)
{
uiInitOptions o;
+ const char *err;
uiWindow *w;
uiGrid *g;
uiLabel *l;
uiButton *b;
memset(&o, 0, sizeof (uiInitOptions));
- if (uiInit(&o) != NULL)
- abort();
+ err = uiInit(&o);
+ if (err != NULL) {
+ fprintf(stderr, "error initializing ui: %s\n", err);
+ uiFreeInitError(err);
+ return 1;
+ }
w = uiNewWindow("Date / Time", 320, 240, 0);
uiWindowSetMargined(w, 1);
diff --git a/unix/datetimepicker.c b/unix/datetimepicker.c
index 5f052dca..0f57b721 100644
--- a/unix/datetimepicker.c
+++ b/unix/datetimepicker.c
@@ -116,6 +116,7 @@ static void dateTimeChanged(uiprivDateTimePickerWidget *d)
{
g_signal_emit(d, changedSignal, 0);
setLabel(d);
+ // TODO fire event here instead?
}
// we don't want ::toggled to be sent again
@@ -579,7 +580,7 @@ void uiDateTimePickerTime(uiDateTimePicker *d, struct tm *time)
// Copy time to minimize a race condition
// time.h functions use global non-thread-safe data
tmbuf = *localtime(&t);
- memcpy(time, &tmbuf, sizeof(struct tm));
+ memcpy(time, &tmbuf, sizeof (struct tm));
}
void uiDateTimePickerSetTime(uiDateTimePicker *d, const struct tm *time)
@@ -588,7 +589,7 @@ void uiDateTimePickerSetTime(uiDateTimePicker *d, const struct tm *time)
struct tm tmbuf;
// Copy time because mktime() modifies its argument
- memcpy(&tmbuf, time, sizeof(struct tm));
+ memcpy(&tmbuf, time, sizeof (struct tm));
t = mktime(&tmbuf);
uiprivDateTimePickerWidget_setTime(d->d, g_date_time_new_from_unix_local(t));
diff --git a/windows/datetimepicker.cpp b/windows/datetimepicker.cpp
index 26841dae..32546cf8 100644
--- a/windows/datetimepicker.cpp
+++ b/windows/datetimepicker.cpp
@@ -4,7 +4,7 @@
struct uiDateTimePicker {
uiWindowsControl c;
HWND hwnd;
- void(*onChanged)(uiDateTimePicker *, void *);
+ void (*onChanged)(uiDateTimePicker *, void *);
void *onChangedData;
};
@@ -191,10 +191,9 @@ void uiDateTimePickerSetTime(uiDateTimePicker *d, const struct tm *time)
toSystemTime(time, &systime);
if (SendMessageW(d->hwnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM) (&systime)) == 0)
logLastError(L"error setting date and time");
- (*(d->onChanged))(d, d->onChangedData);
}
-void uiDateTimePickerOnChanged(uiDateTimePicker *d, void(*f)(uiDateTimePicker *, void *), void *data)
+void uiDateTimePickerOnChanged(uiDateTimePicker *d, void (*f)(uiDateTimePicker *, void *), void *data)
{
d->onChanged = f;
d->onChangedData = data;