aboutsummaryrefslogblamecommitdiffstats
path: root/lib/observer/src/cdv_multi_panel.erl
blob: 3744863710767a8f294913a9ddf3d5050a4a0b09 (plain) (tree)





























































































































































































                                                                                
%%
%% %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, Callback) ->
    wx_object:start_link(?MODULE, [Notebook, Callback], []).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

init([Notebook, Callback]) ->
    Pages = Callback:get_info(),
    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),

    {MainPanel, #state{main_panel=MainPanel,
		       main_sizer=Sizer,
		       menu=LeftMenu,
		       menu_sizer=LeftMenuSizer,
		       callback=Callback,
		       pages=Pages,
		       dyn_panel=DynPanel
		      }}.

%%%%%%%%%%%%%%%%%%%%%%% Callbacks %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

handle_info(active, State) ->
    NewState =
	wx:batch(
	  fun() ->
		  update_dyn_page(State)
	  end),
    {noreply, NewState};

handle_info(not_active, State) ->
    {noreply, State};

handle_info(new_dump, State) ->
    NewState =
	wx:batch(
	  fun() ->
		  update_left_menu(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(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) ->
    {Page,Sizer} = 
	wx:batch(fun() ->
			 wxWindow:freeze(DynPanel),
			 Name = wxListBox:getStringSelection(Menu),
			 Res = load_dyn_page(DynPanel,Name,Pages),
			 wxSizer:layout(MainSizer),
			 wxWindow:thaw(DynPanel),
			 Res
		 end),
    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}.