diff options
Diffstat (limited to 'lib/observer/src/cdv_multi_wx.erl')
-rw-r--r-- | lib/observer/src/cdv_multi_wx.erl | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/lib/observer/src/cdv_multi_wx.erl b/lib/observer/src/cdv_multi_wx.erl new file mode 100644 index 0000000000..75c7f48fc2 --- /dev/null +++ b/lib/observer/src/cdv_multi_wx.erl @@ -0,0 +1,188 @@ +%% +%% %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_wx). + +-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}. |