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