dbg_ui_trace_win.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 401 行

ERL
401
字号
%% ``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 via the world wide web 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.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %%     $Id$%%-module(dbg_ui_trace_win).%% External exports-export([init/0]).-export([create_win/4, get_window/1,	 configure/2,	 enable/2, is_enabled/1, select/2,	 add_break/3, update_break/2, delete_break/2,	 clear_breaks/1, clear_breaks/2,	 display/1,                                   % Help messages	 is_shown/2,                                  % Code area	 show_code/3, show_no_code/1, remove_code/2,      	 mark_line/3, unmark_line/1,	 select_line/2, selected_line/1,	 eval_output/2,                               % Evaluator area	 update_bindings/1,                           % Bindings area	 trace_output/1,                              % Trace area	 handle_event/2	]).-export([helpwin/4,                                   % Help windows	 helpwin/5]).-record(breakInfo, {point, status, break}).-record(winInfo, {window,          % gsobj()		  size,            % {W, H}		  flags,           % {F,F,F,F} F = open|close		  marked_line=0,   % integer() Current line		  selected_line=0, % integer() Selected line		  breaks=[],       % [#breakInfo{}] Known breakpoints		  editor,          % {Mod, Editor}  Visible code editor		  editors=[]       % [{Mod,Editor}] Code editors		 }).%%====================================================================%% External exports%%====================================================================%%--------------------------------------------------------------------%% init() -> GS%%   GS = term()%%--------------------------------------------------------------------init() ->    dbg_ui_win:init().%%--------------------------------------------------------------------%% create_win(GS, Title, TraceWin, Menus) -> #winInfo{}%%  GS = gsobj()%%  Title = string()%%  TraceWin = [WinArea]%%    WinArea = 'Button|Evaluator|Bindings|Trace Area'%%  Menus = [menu()]  See dbg_ui_win.erl%%--------------------------------------------------------------------create_win(GS, Title, TraceWin, Menus) ->    Bu = flip(lists:member('Button Area', TraceWin)),    Ev = flip(lists:member('Evaluator Area', TraceWin)),    Bi = flip(lists:member('Bindings Area', TraceWin)),    Tr = flip(lists:member('Trace Area', TraceWin)),        Win = gs:window(trace_window, GS, [{title, Title},				       {width, 550},				       {configure,true}, {destroy,true},				       {keypress,true}, {motion,true}]),    MenuBar = gs:menubar(Win, []),    dbg_ui_win:create_menus(MenuBar, Menus),    dbg_ui_winman:windows_menu(MenuBar),    FrameOpts = [{anchor,nw}, {relief,raised}, {bw,2}, {keypress,true}],    Editor = code_area(2, 25, FrameOpts, Win),    button_area(Bu, 2, 235, FrameOpts, Win),    eval_area({Ev,Bi}, 2, 265, FrameOpts, Win),    bind_area({Ev,Bi}, 300, 265, FrameOpts, Win),    trace_area(Tr, 2, 475, FrameOpts, Win),    Flags = {Bu, Ev, Bi, Tr},    resizebar(rb1(Flags), 'RB1',   2, 225, 710,  10, Win),    resizebar(rb2(Flags), 'RB2',   2, 465, 710,  10, Win),    resizebar(rb3(Flags), 'RB3', 290, 265,  10, 200, Win),    config_v(),    config_h(),        gs:config(Win,{height,		   25 +		   gs:read('CodeArea', height) +		   gs:read('RB1', height) +		   gs:read('ButtonArea', height) +		   max(gs:read('EvalArea', height),		       gs:read('BindArea', height)) +		   gs:read('RB2', height) +		   gs:read('TraceArea', height)}),        gs:config(Win, {map, true}),    #winInfo{window=Win, size={gs:read(Win,width), gs:read(Win,height)},	     flags=Flags,	     editor={'$top', Editor}, editors=[{'$top', Editor}]}.flip(true) -> open;flip(false) -> close.    %%--------------------------------------------------------------------%% get_window(WinInfo) -> Window%%   WinInfo = #winInfo{}%%   Window = gsobj()%%--------------------------------------------------------------------get_window(WinInfo) ->    WinInfo#winInfo.window.%%--------------------------------------------------------------------%% configure(WinInfo, TraceWin) -> WinInfo%%   WinInfo = #winInfo{}%%  TraceWin = [WinArea]%%    WinArea = 'Button|Evaluator|Bindings|Trace Area'%% Window areas should be opened or closed.%%--------------------------------------------------------------------configure(WinInfo, TraceWin) ->    {Bu1, Ev1, Bi1, Tr1} = OldFlags = WinInfo#winInfo.flags,    Bu2 = flip(lists:member('Button Area', TraceWin)),    Ev2 = flip(lists:member('Evaluator Area', TraceWin)),    Bi2 = flip(lists:member('Bindings Area', TraceWin)),    Tr2 = flip(lists:member('Trace Area', TraceWin)),    NewFlags = {Bu2, Ev2, Bi2, Tr2},    Win = WinInfo#winInfo.window,    W = gs:read(Win, width),    H = gs:read(Win, height),    H2 = if	     Bu1==close, Bu2==open ->		 resize_button_area(open, width, W-4),		 gs:config('ButtonArea', {height, 30}),		 H+30;	     Bu1==open, Bu2==close ->		 gs:config('ButtonArea', [{width, 0}, {height, 0}]),		 H-30;	     true -> H	 end,    H3 = if	     Ev1==close, Ev2==open, Bi1==open ->		 Wnew1 = round((W-10-4)/2), % W = window/2 - rb - pads		 Hbi1 = gs:read('BindArea', height), % H = bind area h		 resize_eval_area(open, width, Wnew1),		 resize_eval_area(open, height, Hbi1),		 gs:config('RB3', {width, 10}),		 gs:config('RB3', {height, Hbi1}),		 resize_bind_area(open, width,				  Wnew1-gs:read('BindArea', width)),		 H2;	     Ev1==close, Ev2==open, Bi1==close ->		 resize_eval_area(open, width, W-4),		 resize_eval_area(open, height, 200),		 H2+200;	     Ev1==open, Ev2==close, Bi1==open ->		 gs:config('EvalArea', [{width,0}, {height,0}]),		 gs:config('RB3', [{width, 0}, {height, 0}]),		 Wnew2 = W-4,		 resize_bind_area(open, width,				  Wnew2-gs:read('BindArea', width)),		 H2;	     Ev1==open, Ev2==close, Bi1==close ->		 Hs1 = gs:read('EvalArea', height),		 gs:config('EvalArea', [{width, 0}, {height, 0}]),		 H2-Hs1;	     true -> H2	 end,    H4 = if	     Bi1==close, Bi2==open, Ev2==open ->		 Wnew3 = round((W-10-4)/2), % W = window/2 - rb - pads		 Hs2 = gs:read('EvalArea', height), % H = eval area h		 resize_bind_area(open, width, Wnew3),		 resize_bind_area(open, height, Hs2),		 gs:config('RB3', [{width,10},{height,Hs2}]),		 resize_eval_area(open, width,				  Wnew3-gs:read('EvalArea', width)),		 H3;	     Bi1==close, Bi2==open, Ev2==close ->		 resize_bind_area(open, width, W-4),		 resize_bind_area(open, height, 200),		 H3+200;	     Bi1==open, Bi2==close, Ev2==open ->		 gs:config('BindArea', [{width, 0}, {height, 0}]),		 gs:config('RB3', [{width, 0}, {height, 0}]),		 Wnew4 = W-4,		 resize_eval_area(open, width,				  Wnew4-gs:read('EvalArea', width)),		 H3;	     Bi1==open, Bi2==close, Ev2==close ->		 Hbi2 = gs:read('BindArea', height),		 gs:config('BindArea', [{width, 0}, {height, 0}]),		 H3-Hbi2;	     true -> H3	 end,    H5 = if	     Tr1==close, Tr2==open ->		 resize_trace_area(open, width, W-4),		 resize_trace_area(open, height, 200),		 H4+200;	     Tr1==open, Tr2==close ->		 Hf = gs:read('TraceArea', height),		 gs:config('TraceArea', [{width, 0}, {height, 0}]),		 H4-Hf;	     true -> H4	 end,    gs:config(Win, {height, H5}),    RB1old = rb1(OldFlags), RB1new = rb1(NewFlags),    if	RB1old==close, RB1new==open ->	    gs:config('RB1', [{width, W-4}, {height, 10}]),	    gs:config(Win, {height, gs:read(Win, height)+10});	RB1old==open, RB1new==close ->	    gs:config('RB1', [{width, 0}, {height, 0}, lower]),	    gs:config(Win, {height, gs:read(Win, height)-10});	true -> ignore    end,    RB2old = rb2(OldFlags), RB2new = rb2(NewFlags),    if	RB2old==close, RB2new==open ->	    gs:config('RB2', [{width, W-4}, {height, 10}]),	    gs:config(Win, {height,gs:read(Win, height)+10});	RB2old==open, RB2new==close ->			    gs:config('RB2', [{width, 0}, {height, 0}, lower]),	    gs:config(Win, {height, gs:read(Win, height)-10});	true -> ignore    end,    config_v(),    config_h(),    flush_configure(),        WinInfo#winInfo{size={gs:read(Win, width), gs:read(Win, height)},		    flags=NewFlags}.flush_configure() ->    receive	{gs, _Id, configure, _Data, _Arg} ->	    flush_configure()    after 100 ->	    true    end.%%--------------------------------------------------------------------%% enable([MenuItem], Bool)%% is_enabled(MenuItem) -> Bool%%   MenuItem = atom()%%   Bool = boolean()%%--------------------------------------------------------------------enable(MenuItems, Bool) ->    lists:foreach(fun(MenuItem) ->			  gs:config(MenuItem, {enable, Bool}),			  case is_button(MenuItem) of			      {true, Button} ->				  gs:config(Button, {enable, Bool});			      false -> ignore			  end		  end,		  MenuItems).is_enabled(MenuItem) ->    gs:read(MenuItem, enable).%%--------------------------------------------------------------------%% select(MenuItem, Bool)%%   MenuItem = atom()%%   Bool = boolean()%%--------------------------------------------------------------------select(MenuItem, Bool) ->    dbg_ui_win:select(MenuItem, Bool).%%--------------------------------------------------------------------%% add_break(WinInfo, Name, {Point, Options}) -> WinInfo%%   WinInfo = #winInfo{}%%   Name = atom() Menu name%%   Point = {Mod, Line}%%   Options = [Status, Action, Mods, Cond]%%     Status = active | inactive%%     Action = enable | disable | delete%%     Mods = null (not used)%%     Cond = null | {Mod, Func}%%--------------------------------------------------------------------add_break(WinInfo, Menu, {{Mod,Line},[Status|_Options]}=Break) ->    case lists:keysearch(Mod, 1, WinInfo#winInfo.editors) of	{value, {Mod, Editor}} ->	    add_break_to_code(Editor, Line, Status);	false -> ignore    end,    add_break_to_menu(WinInfo, Menu, Break).add_break_to_code(Editor, Line, Status) ->    Color = if Status==active -> red; Status==inactive -> blue end,    config_editor(Editor, [{overwrite,{{Line,0},"-@-  "}},			   {fg,{{{Line,0},{Line,lineend}}, Color}}]).add_break_to_menu(WinInfo, Menu, {Point, [Status|_Options]=Options}) ->    Break = dbg_ui_win:add_break(Menu, Point),    dbg_ui_win:update_break(Break, Options),    BreakInfo = #breakInfo{point=Point, status=Status, break=Break},    WinInfo#winInfo{breaks=[BreakInfo|WinInfo#winInfo.breaks]}.%%--------------------------------------------------------------------%% update_break(WinInfo, {Point, Options}) -> WinInfo%%   WinInfo = #winInfo{}%%   Point = {Mod, Line}%%   Options = [Status, Action, Mods, Cond]%%     Status = active | inactive%%     Action = enable | disable | delete%%     Mods = null (not used)%%     Cond = null | {Mod, Func}%%--------------------------------------------------------------------update_break(WinInfo, {{Mod,Line},[Status|_Options]}=Break) ->    case lists:keysearch(Mod, 1, WinInfo#winInfo.editors) of	{value, {Mod, Editor}} ->	    add_break_to_code(Editor, Line, Status);	false -> ignore    end,    update_break_in_menu(WinInfo, Break).update_break_in_menu(WinInfo, {Point, [Status|_Options]=Options}) ->    {value, BreakInfo} = lists:keysearch(Point, #breakInfo.point,					 WinInfo#winInfo.breaks),    dbg_ui_win:update_break(BreakInfo#breakInfo.break, Options),    BreakInfo2 = BreakInfo#breakInfo{status=Status},    WinInfo#winInfo{breaks=lists:keyreplace(Point, #breakInfo.point,					    WinInfo#winInfo.breaks,					    BreakInfo2)}.%%--------------------------------------------------------------------%% delete_break(WinInfo, Point) -> WinInfo%%   WinInfo = #winInfo{}%%   Point = {Mod, Line}%%--------------------------------------------------------------------delete_break(WinInfo, {Mod,Line}=Point) ->    case lists:keysearch(Mod, 1, WinInfo#winInfo.editors) of	{value, {Mod, Editor}} -> delete_break_from_code(Editor, Line);	false -> ignore    end,    delete_break_from_menu(WinInfo, Point).delete_break_from_code(Editor, Line) ->    Prefix = string:substr(integer_to_list(Line)++":   ", 1, 5),    config_editor(Editor, [{overwrite,{{Line,0},Prefix}},			   {fg,{{{Line,0},{Line,lineend}}, black}}]).delete_break_from_menu(WinInfo, Point) ->    {value, BreakInfo} = lists:keysearch(Point, #breakInfo.point,					 WinInfo#winInfo.breaks),    dbg_ui_win:delete_break(BreakInfo#breakInfo.break),    WinInfo#winInfo{breaks=lists:keydelete(Point, #breakInfo.point,					   WinInfo#winInfo.breaks)}.%%--------------------------------------------------------------------%% clear_breaks(WinInfo) -> WinInfo%% clear_breaks(WinInfo, Mod) -> WinInfo%%   WinInfo = #winInfo{}%%--------------------------------------------------------------------clear_breaks(WinInfo) ->    clear_breaks(WinInfo, all).clear_breaks(WinInfo, Mod) ->    Remove = if		 Mod==all -> WinInfo#winInfo.breaks;		 true ->		     lists:filter(fun(#breakInfo{point={Mod2,_L}}) ->					  if					      Mod2==Mod -> true;					      true -> false					  end				  end,				  WinInfo#winInfo.breaks)	     end,    lists:foreach(fun(#breakInfo{point=Point}) ->			  delete_break(WinInfo, Point)		  end,		  Remove),    Remain = WinInfo#winInfo.breaks -- Remove,    WinInfo#winInfo{breaks=Remain}.%%--------------------------------------------------------------------%% display(Arg)%%   Arg = idle | {Status,Mod,Line} | {running,Mod}%%       

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?