1%% This module is actually handwritten see ../api_gen/wx_extra/wxEvtHandler.erl 2%% 3%% @doc The Event handler. 4%% 5%% To get events from wxwidgets objects you subscribe to them by 6%% calling connect/[2-3]. Events are sent as messages, if no callback 7%% was supplied These messages will be {@link wx(). #wx{}} where 8%% EventRecord is a record that depends on the {@link 9%% wxEventType(). event type}. The records are defined in: 10%% wx/include/wx.hrl. 11%% 12%% If a callback was supplied to connect, the callback will be invoked 13%% (in another process) to handle the event. The callback should be of 14%% arity 2. fun(EventRecord::wx(), EventObject::wxObject()). 15%% 16%% Beware that the callback will be in executed in new process each time. 17%% 18%% <a href="http://www.wxwidgets.org/manuals/stable/wx_wxevthandler.html"> 19%% The orginal documentation</a>. 20%% 21%% 22-module(wxEvtHandler). 23-include("wxe.hrl"). 24-include("../include/wx.hrl"). 25 26%% API 27-export([connect/2, connect/3, disconnect/1, disconnect/2, disconnect/3]). 28 29%% internal exports 30-export([connect_impl/2, disconnect_impl/2]). 31 32-export_type([wxEvtHandler/0, wx/0, event/0]). 33-type wxEvtHandler() :: wx:wx_object(). 34 35%% @doc Equivalent to {@link connect/3. connect(This, EventType, [])} 36-spec connect(This::wxEvtHandler(), EventType::wxEventType()) -> 'ok'. 37connect(This, EventType) -> 38 connect(This, EventType, []). 39 40%% @doc This function subscribes the to events of EventType, 41%% in the range id, lastId. The events will be received as messages 42%% if no callback is supplied. 43%% 44%% Options: 45%% {id, integer()}, The identifier (or first of the identifier range) to be 46%% associated with this event handler. 47%% Default ?wxID_ANY 48%% {lastId, integer()}, The second part of the identifier range. 49%% If used 'id' must be set as the starting identifier range. 50%% Default ?wxID_ANY 51%% {skip, boolean()}, If skip is true further event_handlers will be called. 52%% This is not used if the 'callback' option is used. 53%% Default false. 54%% {callback, function()} Use a callback fun(EventRecord::wx(), EventObject::wxObject()) 55%% to process the event. Default not specfied i.e. a message will 56%% be delivered to the process calling this function. 57%% {userData, term()} An erlang term that will be sent with the event. Default: []. 58-spec connect(This::wxEvtHandler(), EventType::wxEventType(), [Option]) -> 'ok' when 59 Option :: {'id', integer()} | {'lastId', integer()} | {'skip', boolean()} | 60 'callback' | {'callback', function()} | {'userData', term()}. 61connect(This=#wx_ref{type=ThisT}, EventType, Options) -> 62 EvH = parse_opts(Options, #evh{et=EventType}), 63 ?CLASS(ThisT,wxEvtHandler), 64 case wxe_util:connect_cb(This, EvH) of 65 ok -> ok; 66 {badarg, event_type} -> 67 erlang:error({badarg,EventType}) 68 end. 69 70parse_opts([{callback,Fun}|R], Opts) when is_function(Fun) -> 71 %% Check Fun Arity? 72 parse_opts(R, Opts#evh{cb=Fun}); 73parse_opts([{callback,CB={nospawn, Fun}}|R], Opts) when is_function(Fun) -> 74 parse_opts(R, Opts#evh{cb=CB}); 75parse_opts([callback|R], Opts) -> 76 parse_opts(R, Opts#evh{cb=self()}); 77parse_opts([{userData, UserData}|R],Opts) -> 78 parse_opts(R, Opts#evh{userdata=UserData}); 79parse_opts([{skip, Skip}|R],Opts) when is_boolean(Skip) -> 80 parse_opts(R, Opts#evh{skip=Skip}); 81parse_opts([{id, Id}|R],Opts) when is_integer(Id) -> 82 parse_opts(R, Opts#evh{id=Id}); 83parse_opts([{lastId, Id}|R],Opts) when is_integer(Id) -> 84 parse_opts(R, Opts#evh{lastId=Id}); 85parse_opts([_BadArg|R], Opts) -> 86 parse_opts(R, Opts); 87parse_opts([], Opts = #evh{id=Id,lastId=Lid,skip=Skip, cb=CB}) -> 88 if 89 Skip =/= undefined andalso CB =/= 0 -> 90 erlang:error({badarg, {combined, skip, callback}}); 91 Lid =/= ?wxID_ANY andalso Id =:= ?wxID_ANY -> 92 erlang:error({badarg, no_start_identifier_range}); 93 Skip =:= undefined -> %% Default 94 Opts#evh{skip=false}; 95 true -> 96 Opts 97 end. 98 99 100%% @doc Equivalent to {@link disconnect/3. disconnect(This, null, [])} 101%% Can also have an optional callback Fun() as an additional last argument. 102-spec disconnect(This::wxEvtHandler()) -> boolean(). 103disconnect(This=#wx_ref{type=ThisT,ref=_ThisRef}) -> 104 ?CLASS(ThisT,wxEvtHandler), 105 disconnect(This, null, []). 106 107%% @doc Equivalent to {@link disconnect/3. disconnect(This, EventType, [])} 108-spec disconnect(This::wxEvtHandler(), EventType::wxEventType()) -> boolean(). 109disconnect(This=#wx_ref{type=ThisT,ref=_ThisRef}, EventType) when is_atom(EventType) -> 110 ?CLASS(ThisT,wxEvtHandler), 111 disconnect(This, EventType, []). 112 113%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxevthandler.html#wxevthandlerdisconnect">external documentation</a> 114%% This function unsubscribes the process or callback fun from the event handler. 115%% EventType may be the atom 'null' to match any eventtype. 116%% Notice that the options skip and userdata is not used to match the eventhandler. 117-spec disconnect(This::wxEvtHandler(), EventType::wxEventType(), [Option]) -> boolean() when 118 Option :: {'id', integer()} | {'lastId', integer()} | {'callback', function()}. 119disconnect(This=#wx_ref{type=ThisT,ref=_ThisRef}, EventType, Opts) -> 120 ?CLASS(ThisT,wxEvtHandler), 121 EvH = parse_opts(Opts, #evh{et=EventType}), 122 case wxe_util:disconnect_cb(This, EvH) of 123 {badarg, event_type} -> 124 erlang:error({badarg,EventType}); 125 Bool -> 126 Bool 127 end. 128 129 130%% @hidden 131connect_impl(#wx_ref{type=ThisT,ref=ThisRef}, 132 #evh{id=Winid, lastId=LastId, et=EventType, 133 skip=Skip, userdata=Userdata, cb=FunID}) 134 when is_integer(FunID)-> 135 EventTypeBin = list_to_binary([atom_to_list(EventType)|[0]]), 136 ThisTypeBin = list_to_binary([atom_to_list(ThisT)|[0]]), 137 UD = if Userdata =:= [] -> 0; 138 true -> 139 wxe_util:send_bin(term_to_binary(Userdata)), 140 1 141 end, 142 wxe_util:call(100, <<ThisRef:32/?UI, 143 Winid:32/?UI,LastId:32/?UI, 144 (wxe_util:from_bool(Skip)):32/?UI, 145 UD:32/?UI, 146 FunID:32/?UI, 147 (size(EventTypeBin)):32/?UI, 148 (size(ThisTypeBin)):32/?UI, 149 %% Note no alignment 150 EventTypeBin/binary,ThisTypeBin/binary>>). 151 152%% @hidden 153disconnect_impl(#wx_ref{type=_ThisT,ref=ThisRef}, 154 #evh{id=Winid, lastId=LastId, et=EventType, 155 handler=#wx_ref{type=wxeEvtListener,ref=EvtList}}) -> 156 EventTypeBin = list_to_binary([atom_to_list(EventType)|[0]]), 157 wxe_util:call(101, <<EvtList:32/?UI, 158 ThisRef:32/?UI,Winid:32/?UI,LastId:32/?UI, 159 (size(EventTypeBin)):32/?UI, 160 %% Note no alignment 161 EventTypeBin/binary>>). 162