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 + -
显示快捷键?