[erlang-questions] wxDatePickerCtrl and invalid value
Joakim Hirsch
joakim@REDACTED
Wed Dec 3 00:32:22 CET 2014
Hi,
I've run into a problem with the wxDatePickerCtrl when creating it with
flag ?wxDP_ALLOWNONE. This flag allows the control to have an
undefined/invalid value. The control is adorned with a checkbox, which
is checked if the value is defined/valid. When the control is created,
the checkbox is unchecked (invalid). Retrieving the value renders "the
invalid value" {{1970, 1, 1}, {0, 59, 59}}. I need to be able to reset
the value of the control to invalid sometimes, but the interface of
wxDatePickerCtrl doesn't offer a reset or any way to affect the checkbox.
One idea is to set the control value to the invalid value, but that
doesn't do it. The control will return {{1970, 1, 1}, {0, 0, 0}} and the
checkbox is checked (valid).
It would perhaps have been possible to work around this by replacing the
control with a new one. It would be necessary to get the parent and
containing sizer and to copy name, size, style (and id but I'm not using
it), and range -- all quite possible, except for the range. The function
wxDatePickerCtrl:getRange(This, Dt1, Dt2) -> boolean()
does not return the range. The wxWidgets method is defined as
boolean GetRange(wxDateTime*dt1, wxDateTime* dt2) const
and will fill the supplied parameters with the range values in a C way.
So my next idea is to combine a checkbox and a date picker (without the
allow-none style) myself. Maybe someone has a better suggestion, or can
teach me how to work the date picker?
I'm running Erlang/OTP 17
Here's a sample. All the interesting stuff is in do_init/1. Any help
would be much appreciated.
BR
Joakim Hirsch
-module(test_gui).
-behaviour(wx_object).
%% Client API
-export([start/0]).
%% wx_object callbacks
-export([init/1, terminate/2, code_change/3,
handle_info/2, handle_call/3, handle_cast/2, handle_event/2,
handle_sync_event/3]).
-include_lib("wx/include/wx.hrl").
-record(state,
{
parent
}).
start() ->
Wx = wx:new(),
Size = {size, {500, 500}},
Frame = wxFrame:new(Wx, ?wxID_ANY, "Title", [Size]),
Config = [{parent, Frame}],
wx_object:start_link(?MODULE, Config, []).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
init(Config) ->
wx:batch(fun() -> do_init(Config) end).
do_init(Config) ->
Frame = proplists:get_value(parent, Config),
Panel = wxPanel:new(Frame),
Style = ?wxDP_DROPDOWN bor ?wxDP_ALLOWNONE,
Ctrl = wxDatePickerCtrl:new(Panel, ?wxID_ANY, [{style, Style},
{size, {200, -1}}]),
wxFrame:show(Frame),
%% Ctrl displays todays date but the
%% checkbox is unchecked <=> invalid value
timer:sleep(5000),
%% Value is "the invalid value".
Invalid = {{1970, 1, 1}, {0, 59, 59}},
Invalid = wxDatePickerCtrl:getValue(Ctrl),
wxDatePickerCtrl:setValue(Ctrl, Invalid),
%% Ctrl displays {1970, 1, 1}
%% Checkbox is now checked <=> valid value
%% Value is not invalid anymore.
Valid = {{1970, 1, 1}, {0, 0, 0}},
Valid = wxDatePickerCtrl:getValue(Ctrl),
{Frame, #state{parent = Frame}}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Sync events i.e. from callbacks must return ok, it can not return a
%% new state. Do the redrawing here.
handle_sync_event(#wx{event = #wxPaint{}},_,
#state{}) ->
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Callbacks handled as normal gen_server callbacks
%%
%% Unknown event.
%%
handle_event(Ev = #wx{}, State) ->
io:format("Got event:~p\n", [Ev]),
{noreply, State}.
handle_info(Msg, State) ->
io:format("Got Info ~p\n", [Msg]),
{noreply, State}.
handle_call(shutdown, _From, State=#state{parent=Frame}) ->
io:format("Shutdown~n", []),
wxFrame:destroy(Frame),
{stop, normal, ok, State};
handle_call(Msg, _From, State) ->
io:format("Got Call ~p\n", [Msg]),
{reply, {error, unknown_call}, State}.
handle_cast(Msg, State) ->
io:format("Got cast ~p~n",[Msg]),
{noreply, State}.
code_change(_, _, State) ->
{stop, ignore, State}.
terminate(_Reason, _State) ->
io:format("Stopping~n", []),
wx:destroy(),
ok.
More information about the erlang-questions
mailing list