%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2011-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
%%
%% %CopyrightEnd%
-module(cdv_multi_panel).
-behaviour(wx_object).
-export([start_link/2]).
%% wx_object callbacks
-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3,
handle_event/2, handle_cast/2]).
-include_lib("wx/include/wx.hrl").
-include("observer_defs.hrl").
%% Records
-record(state,
{main_panel,
main_sizer,
menu,
menu_sizer,
callback,
pages,
dyn_panel,
dyn_sizer,
dyn_page
}).
start_link(Notebook, Info) ->
wx_object:start_link(?MODULE, [Notebook, Info], []).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
init([Notebook, Callback]) when is_atom(Callback) ->
Pages = Callback:get_info(),
{MainPanel,State0} = init([Notebook, Pages]),
{MainPanel,State0#state{callback=Callback}};
init([Notebook, Pages]) ->
MainPanel = wxPanel:new(Notebook),
Sizer = wxBoxSizer:new(?wxHORIZONTAL),
LeftMenuSizer = wxStaticBoxSizer:new(?wxVERTICAL,MainPanel,
[{label,"Please select"}]),
LeftMenu = wxListBox:new(MainPanel,?wxID_ANY,
[{style,?wxLB_SINGLE},
{choices,[T || {T,_,_} <- Pages]}]),
wxListBox:setSelection(LeftMenu,0),
wxListBox:connect(LeftMenu, command_listbox_selected),
wxSizer:add(LeftMenuSizer,LeftMenu,[{flag,?wxEXPAND},{proportion,2}]),
DynPanel = wxScrolledWindow:new(MainPanel),
wxScrolledWindow:enableScrolling(DynPanel,true,true),
wxScrolledWindow:setScrollbars(DynPanel,1,1,0,0),
BorderFlags = ?wxLEFT bor ?wxRIGHT,
wxSizer:add(Sizer, LeftMenuSizer,
[{flag, ?wxEXPAND bor BorderFlags bor ?wxTOP},
{proportion, 0}, {border, 5}]),
wxSizer:add(Sizer, DynPanel, [{flag, ?wxEXPAND bor BorderFlags bor ?wxTOP},
{proportion, 1}, {border, 5}]),
wxPanel:setSizer(MainPanel, Sizer),
State = load_dyn_page(#state{main_panel=MainPanel,
main_sizer=Sizer,
menu=LeftMenu,
menu_sizer=LeftMenuSizer,
pages=Pages,
dyn_panel=DynPanel
}),
{MainPanel, State}.
%%%%%%%%%%%%%%%%%%%%%%% Callbacks %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
handle_info(active, State) ->
NewState =
wx:batch(
fun() ->
update_dyn_page(State)
end),
{noreply, NewState};
handle_info(Info, State) ->
io:format("~p:~p: Unhandled info: ~p~n", [?MODULE, ?LINE, Info]),
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_, _, State) ->
{ok, State}.
handle_call(new_dump, _From, State) ->
NewState =
wx:batch(
fun() ->
update_left_menu(State)
end),
{reply, ok, NewState};
handle_call(Msg, _From, State) ->
io:format("~p:~p: Unhandled Call ~p~n",[?MODULE, ?LINE, Msg]),
{reply, ok, State}.
handle_cast(Msg, State) ->
io:format("~p:~p: Unhandled cast ~p~n",[?MODULE, ?LINE, Msg]),
{noreply, State}.
handle_event(#wx{event=#wxCommand{type=command_listbox_selected,
cmdString=[]}},
State) ->
%% For some reason, the listbox sometimes gets an "unselect"
%% command like this during termination. Ignore!
{noreply, State};
handle_event(#wx{event=#wxCommand{type=command_listbox_selected,
cmdString=_DynName}},
State) ->
NewState =
wx:batch(fun() ->
update_dyn_page(State)
end),
{noreply,NewState};
handle_event(Event, State) ->
io:format("~p:~p: Unhandled event ~p\n", [?MODULE,?LINE,Event]),
{noreply, State}.
%%%%%%%%%%%%%%%%%%%%%%% Internal %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
update_left_menu(#state{main_panel=Panel,
callback=Callback,
menu=OldMenu,
menu_sizer=MenuSizer} = State) ->
Pages = Callback:get_info(),
wxListBox:disconnect(OldMenu),
wxWindow:destroy(OldMenu),
NewMenu = wxListBox:new(Panel,?wxID_ANY,
[{style,?wxLB_SINGLE},
{choices,[T || {T,_,_} <- Pages]}]),
wxListBox:setSelection(NewMenu,0),
wxListBox:connect(NewMenu, command_listbox_selected),
wxSizer:add(MenuSizer,NewMenu,[{flag,?wxEXPAND},{proportion,2}]),
wxSizer:layout(MenuSizer),
State#state{pages=Pages,menu=NewMenu}.
update_dyn_page(#state{dyn_page=undefined} = State) ->
load_dyn_page(State);
update_dyn_page(#state{dyn_page=OldDynPage,
dyn_sizer=OldDynSizer} = State) ->
wxSizer:detach(OldDynSizer,OldDynPage),
wxWindow:destroy(OldDynPage),
load_dyn_page(State).
load_dyn_page(#state{main_sizer=MainSizer,
dyn_panel=DynPanel,
menu=Menu,
pages=Pages} = State) ->
%% Freeze and thaw causes a hang (and is not needed) on 2.9 and higher
DoFreeze = [?wxMAJOR_VERSION,?wxMINOR_VERSION] < [2,9],
DoFreeze andalso wxWindow:freeze(DynPanel),
Name = wxListBox:getStringSelection(Menu),
{Page,Sizer} = load_dyn_page(DynPanel,Name,Pages),
wxSizer:layout(MainSizer),
DoFreeze andalso wxWindow:thaw(DynPanel),
wx_object:get_pid(Page) ! active,
State#state{dyn_page=Page,dyn_sizer=Sizer}.
load_dyn_page(Panel,Name,Pages) ->
Sizer = wxStaticBoxSizer:new(?wxVERTICAL, Panel, [{label,Name}]),
{_,Callback,Info} = lists:keyfind(Name,1,Pages),
DynPage = Callback:start_link(Panel,Info),
wxSizer:add(Sizer,DynPage,[{flag, ?wxEXPAND}, {proportion, 1}]),
wxPanel:setSizerAndFit(Panel,Sizer,[{deleteOld,true}]),
{DynPage,Sizer}.