dbg_ui_break_win.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 307 行
ERL
307 行
%% ``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_break_win).%% External exports-export([create_win/5, update_functions/2, handle_event/2]).-record(winInfo, {type, % line | conditional | function win, % gsobj() packer, % gsobj() | undefined entries, % [{atom|integer, GSobj()}] trigger, % enable | disable | delete ok, % gsobj() cancel, % gsobj() listbox, % gsobj() funcs=[] % [[Name, Arity]] }).%%====================================================================%% External exports%%====================================================================%%--------------------------------------------------------------------%% create_win(GS, Pos, Type, Mod, Line) -> #winInfo{}%% GS = graphics system identifier%% Pos = {X, Y}%% X = Y = integer()%% Type = line | conditional | function%% Mod = atom() | ""%% Line = integer() | ""%%--------------------------------------------------------------------create_win(GS, {X, Y}, function, Mod, _Line) -> Pad = 8, W = 230, Font = dbg_ui_win:font(normal), %% Window Win = gs:window(GS, [{title, "Function Break"}, {x, X}, {y, Y}, {destroy, true}, {configure, true}, {keypress, true}, {data, window}]), %% Frame Frm = gs:frame(Win, [{x, 0}, {y, 0}, {width, W}, {height, 190}, {packer_x, [{fixed, 70}, {stretch, 1, W-80}, {fixed, 10}]}, {packer_y, [{fixed, 10}, {fixed, 30}, {stretch, 1, 100}, {fixed, 40}]}]), %% Create input field (label+entry) gs:label(Frm, [{label, {text,"Module:"}}, {font, Font}, {align, e}, {pack_x, 1}, {pack_y, 2}]), Ent = gs:entry(Frm, [{text, Mod}, {pack_x, 2}, {pack_y, 2}, {keypress, true}, {setfocus, true}, {buttonpress, true}]), Entries = [{Ent, atom}], %% Create a listbox containing the functions of the module gs:label(Frm, [{label, {text,"Function:"}}, {font, Font}, {align, ne}, {pack_x, 1}, {pack_y, 3}]), Lb = gs:listbox(Frm, [{bw, 2}, {relief, ridge}, {vscroll, right}, {pack_x, 2}, {pack_y, 3}, {selectmode, multiple}]), %% Add Ok and Cancel buttons {Wbtn, Hbtn} = dbg_ui_win:min_size(["Ok","Cancel"], 70, 30), Bot = gs:frame(Frm, [{pack_x, {1, 3}}, {pack_y, 4}]), Ok = gs:button(Bot, [{x, Pad}, {y, Pad}, {width, Wbtn}, {height, Hbtn}, {label, {text,"Ok"}}, {font, Font}]), Cancel = gs:button(Bot, [{x, W-Pad-Wbtn}, {y, Pad}, {width, Wbtn}, {height, Hbtn}, {label, {text,"Cancel"}}, {font, Font}]), Wfrm = gs:read(Frm, width), Hfrm = gs:read(Frm, height), gs:config(Win, [{width, Wfrm}, {height, Hfrm}, {map, true}]), #winInfo{type=function, win=Win, packer=Frm, entries=Entries, trigger=enable, ok=Ok, cancel=Cancel, listbox=Lb, funcs=[]};create_win(GS, {X, Y}, Type, Mod, Line) -> Pad = 8, W = 230, Font = dbg_ui_win:font(normal), %% Window Title = case Type of line -> "Line Break"; conditional -> "Conditional Break" end, Win = gs:window(GS, [{title, Title}, {x, X}, {y, Y}, {destroy, true}]), %% Create input fields (label+entry) {Wlbl, Hlbl} = dbg_ui_win:min_size(["C-Function:"], 10, 30), Went = W-Wlbl-2*Pad, Labels = case Type of line -> [{atom,"Module:",Mod}, {integer,"Line:",Line}]; conditional -> [{atom,"Module:",Mod}, {integer,"Line:",Line}, {atom,"C-Module:",""}, {atom,"C-Function:",""}] end, Fun = fun({DataType, Label, Default}, Yin) -> gs:create(label, Win, [{x, Pad}, {y, Yin}, {width,Wlbl}, {height,Hlbl}, {label, {text,Label}}, {font, Font}, {align, e}]), Ent = gs:create(entry, Win, [{x, Pad+Wlbl}, {y, Yin}, {width, Went}, {height, Hlbl}, {text, Default}, {keypress, true}]), {{Ent, DataType}, Yin+Hlbl} end, {Entries, Yacc} = lists:mapfoldl(Fun, Pad, Labels), {First, _DataType} = hd(Entries), gs:config(First, [{buttonpress, true}, {setfocus, true}]), %% Add 'trigger action' buttons {Wlbl2, Hlbl2} = dbg_ui_win:min_size(["Trigger Action"], 100, 20), Wfrm = Wlbl2+8, Hfrm = Hlbl2*4+4, Grp = erlang:now(), Frm = gs:frame(Win, [{x, W/2-Wfrm/2-2}, {y, Yacc+Pad-2}, {width, Wfrm}, {height, Hfrm}, {bw, 2}]), gs:label(Frm, [{label, {text, "Trigger Action"}}, {font, Font}, {x, 2}, {y, 0}, {width, Wlbl2}, {height, Hlbl2}]), gs:radiobutton(Frm, [{label, {text, "Enable"}}, {font, Font}, {x, 10}, {y, Hlbl2}, {width, Wlbl2-10}, {height, Hlbl2}, {align, w}, {group, Grp}, {data, {trigger, enable}}, {select, true}]), gs:radiobutton(Frm, [{label, {text, "Disable"}}, {font, Font}, {x, 10}, {y, Hlbl2*2}, {width, Wlbl2-10}, {height, Hlbl2}, {align, w}, {group, Grp}, {data, {trigger, disable}}]), gs:radiobutton(Frm, [{label, {text, "Delete"}}, {font, Font}, {x, 10}, {y, Hlbl2*3}, {width, Wlbl2-10}, {height, Hlbl2}, {align, w}, {group, Grp}, {data, {trigger, delete}}]), %% Add Ok and Cancel buttons {Wbtn, Hbtn} = dbg_ui_win:min_size(["Ok","Cancel"], 70, 30), Ybtn = Yacc + Pad + Hfrm + Pad, Ok = gs:button(Win, [{x, Pad}, {y, Ybtn}, {width, Wbtn}, {height, Hbtn}, {label, {text,"Ok"}}, {font, Font}]), gs:button(Win, [{x, W-Pad-Wbtn}, {y, Ybtn}, {width, Wbtn}, {height, Hbtn}, {label, {text,"Cancel"}}, {font, Font}]), Hwin = Ybtn + Hbtn + Pad, gs:config(Win, [{width, W}, {height, Hwin}, {map, true}]), #winInfo{type=Type, win=Win, entries=Entries, trigger=enable, ok=Ok}.%%--------------------------------------------------------------------%% update_functions(WinInfo, Funcs) -> WinInfo%% WinInfo = #winInfo{}%% Funcs = [{Name, Arity}]%% Name = atom()%% Arity = integer()%%--------------------------------------------------------------------update_functions(WinInfo, Funcs) -> Items = lists:map(fun([N, A]) -> io_lib:format("~p/~p", [N, A]) end, Funcs), gs:config(WinInfo#winInfo.listbox, [{items, Items}, {setfocus, true}]), WinInfo#winInfo{funcs=Funcs}.%%--------------------------------------------------------------------%% handle_event(GSEvent, WinInfo) -> Command%% GSEvent = {gs, Id, Event, Data, Arg}%% WinInfo = #winInfo{}%% Command = ignore%% | stopped%% | {win, WinInfo}%% | {module, Mod}%% | {break, [[Mod, Line]], Action}%% | {break, [[Mod, Line, CMod, CFunc]], Action}%% | {break, [[Mod, Func, Arity]], Action}%%--------------------------------------------------------------------handle_event({gs, _Id, destroy, _Data, _Arg}, _WinInfo) -> stopped;handle_event({gs, _Id, configure, _Data, [W, H|_]}, WinInfo) -> gs:config(WinInfo#winInfo.packer, [{width, W-10}, {height, H-10}]), gs:config(WinInfo#winInfo.cancel, [{x, W-80}]), ignore;handle_event({gs, Ent, buttonpress, _,[N,X0,Y0|_]}, WinInfo) when N>1 -> %% Right (middle) mouse button click in module entry, display a %% menu containing all interpreted modules Mods = int:interpreted(), X = gs:read(Ent, x) + X0, Y = gs:read(Ent, y) + Y0, Menu = gs:menu(WinInfo#winInfo.win, [{post_at,{X,Y}}]), lists:foreach(fun(Mod) -> gs:menuitem(Menu, [{label,{text,Mod}}, {data,{module,Mod}}]) end, Mods), ignore;handle_event({gs, LB, keypress, window, [Key|_]}, WinInfo) -> %% Used for functional break window, since listboxes for some %% reason doesn't generate keypress events if Key/='Tab', Key/='Return' -> ignore; true -> handle_event({gs, LB, click, listbox, ["Ok"]}, WinInfo) end;handle_event({gs, Ent, keypress, Data, [Key|_]}, WinInfo) -> case WinInfo#winInfo.type of function when Key/='Tab', Key/='Return' -> case gs:read(WinInfo#winInfo.listbox, items) of [] -> ignore; _Items -> gs:config(WinInfo#winInfo.listbox, clear), {win, WinInfo#winInfo{funcs=[]}} end; function -> % 'Return' | 'Tab' pressed in Module entry case check_input(WinInfo#winInfo.entries) of error -> ignore; [Mod] -> {module, Mod} end; _Type when Key=='Tab'; Key=='Return' -> case next_entry(Ent, WinInfo#winInfo.entries) of last -> gs:config(WinInfo#winInfo.ok, flash), handle_event({gs, Ent, click, Data, ["Ok"]}, WinInfo); Next -> gs:config(Next, {setfocus, true}), ignore end; _Type -> ignore end;handle_event({gs, _Id, click, _Data, ["Ok"|_]}, WinInfo) -> case check_input(WinInfo#winInfo.entries) of error -> ignore; Data when WinInfo#winInfo.type/=function -> {break, [Data], WinInfo#winInfo.trigger}; [Mod] -> % Function break window case gs:read(WinInfo#winInfo.listbox, selection) of [] -> {module, Mod}; IndexL -> Funcs = WinInfo#winInfo.funcs, Breaks = lists:map(fun(Index) -> Func = lists:nth(Index+1, Funcs), [Mod | Func] end, IndexL), {break, Breaks, enable} end end;handle_event({gs, _Id, click, _Data, ["Cancel"|_]}, _WinInfo) -> stopped;handle_event({gs, _Id, click, {trigger,Trigger}, _Arg}, WinInfo) -> {win, WinInfo#winInfo{trigger=Trigger}};handle_event({gs, _Id, click, {module, Mod}, _Arg}, WinInfo) -> {Ent, _DataType} = hd(WinInfo#winInfo.entries), gs:config(Ent, {insert,{0,Mod}}), ignore;handle_event(_GSEvent, _WinInfo) -> ignore.check_input(Entries) -> check_input(Entries, []).check_input([{Entry, Type} | Entries], Data) -> Str = gs:read(Entry, text), case erl_scan:string(Str) of {ok, [{Type, _Line, Val}], _EndLine} -> check_input(Entries, [Val|Data]); _Error -> error end;check_input([], Data) -> lists:reverse(Data).next_entry(Entry, [{Entry, _Type}]) -> last;next_entry(Entry, [{Entry, _Type1}, {Next, _Type2}|_]) -> Next;next_entry(Entry, [_|Entries]) -> next_entry(Entry, Entries).
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?