📄 toolbar_graphics.erl
字号:
%% ``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(toolbar_graphics).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Erlang Toolbar%%%% Description %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Toolbar graphics.% The Toolbar window looks something like this:%% |-----------------------------|% | File Tools Help |% |-----------------------------|% | |-----| |-----| |-----| |% | | | | | | | |% | |Icon1| |Icon2|...|IconN| |% | |-----| |-----| |-----| |% |-----------------------------|% | Help text area |% |-----------------------------|%%%% Includes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%-include("toolbar.hrl").%%%% Internal data structures %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Toolbar window record-record(tbwindow, {window,menubar,canvas,labelframe, label,helpmenu, no_of_buttons, min_height,min_width,cur_height,icons}).%%%% Constants %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Window width-define(width,215).%% Icon width and height-define(icon,34).%% Margin around icons-define(pad,0).%% Default label width and height-define(wlabel,50).-define(hlabel,15).%% Default button width and height-define(wbutton,50).-define(hbutton,30).%%%% Exports %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%-export([event/4]).-export([draw_window/1,redraw_window/2,already_added/2,add_icon/2]).-export([get_window/1]).-export([cursor/2]).-export([listen_configure/1]).-export([display_show/2,display_clear/1]).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Exported functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%----------------------------------------% event(Data,GsEvent,Data,Args) => Event% Data - term()% GsEvent - GS event% Data, Args - Data and Arg fields associated with the GS event% Event - {display,String} | display_clear | noevent | {start,{M,F,A}} |% update_toolbar | create_tool_file | add_gs_contribs |% {help,Html} | about_help | {redraw,{Width,Height}} | quit |% {newData,NewData}% String - string()% M, F - atom() Module and function name% A - [term()] Function argument% Html - string() HTML file | nofile% Width, Height - integer()% NewData - term()% Tries to convert a GS event to an internal toolbar event. The separation% is intented to keep the implementation details of the graphics hidden% for toolbar.erl. Pure graphical events triggered by the GS event will% be executed by this function.% The Data field is used for saving information between different events% (without having to use put/get or ets). Right now it is only used to save% the coordinates of the last canvasbutton pressed, making it possible to% check if the canvasbutton is released with the mouse moved outside the% button (= no action) or with the mouse still inside the button (= action).%----------------------------------------%%% Mouse enters a icon, display short help messageevent(_LoopData,enter,{canvasbutton,_Cbtn,{_Start,{message,String}}},_Args) -> {display,String};%% Mouse leaves a icon, clear display areaevent(_LoopData,leave,{canvasbutton,_Cbtn,_Data},_Args) -> display_clear;%% An icon is pressed, create graphical illusion of thisevent(_LoopData,buttonpress,{canvasbutton,Canvasbutton,_},_Args) -> canvasbutton:press(Canvasbutton), {newData,canvasbutton:read(Canvasbutton,coords)};%% An icon is released, create graphical illusion of thisevent(LoopData,buttonrelease,{canvasbutton,Cbtn,{{start,Start},_Msg}}, [_,X,Y|_]) -> canvasbutton:release(Cbtn), case within(X,Y,LoopData) of true -> {start,Start}; false -> noevent end;%%% Update Toolbar button pressedevent(_LoopData,click,_Data,["Update Toolbar"|_]) -> update_toolbar;%%% Tool configuration button pressedevent(_LoopData,click,_Data,["Create Tool File..."|_]) -> create_tool_file;%%% Add GS contribution button pressedevent(_LoopData,click,_Data,["Add GS Contributions"|_]) -> add_gs_contribs;%%% Help menu button selectedevent(_LoopData,click,{help,Html},_Args) -> {help,Html};%%% About Help menu button selectedevent(_LoopData,click,about_help,_Args) -> about_help;%% Window resized, redraw itevent(_LoopData,configure,_Data,[Width,Height|_]) -> {redraw,{Width,Height}}; %%% Quit button pressedevent(_LoopData,click,_Data,["Quit"|_]) -> quit;%%% Window closedevent(_LoopData,destroy,_Data,_Args) -> quit;event(_LoopData,_GsEvent,_Data,_Args) -> noevent.%=============================================================================% Main window functions%=============================================================================%----------------------------------------% draw_window(S) => Window% S - pid() GS% Window - tbwindow record% This functions create the main window, initially without any tool icons%----------------------------------------draw_window(S) -> Norm = ?icon + 2*?pad, %% Main window Win = gs:create(window,S,[{title,"Erlang Tools"},{width,?width}]), %% Menu bar with menu buttons Menubar = gs:create(menubar,Win,[]), %% File menu File = gs:create(menubutton,Menubar,[{label,{text,"File"}},{side,left}]), FileM = gs:create(menu,File,[]), gs:create(menuitem,FileM,[{label,{text,"Update Toolbar"}}]), gs:create(menuitem,FileM,[{label,{text,"Quit"}}]), %% Tools menu Tool = gs:create(menubutton,Menubar,[{label,{text,"Tools"}},{side,left}]), ToolM = gs:create(menu,Tool,[]), gs:create(menuitem,ToolM,[{label,{text,"Create Tool File..."}}]), gs:create(menuitem,ToolM,[{label,{text,"Add GS Contributions"}}]), %% Help menu Help = gs:create(menubutton,Menubar,[{label,{text,"Help"}},{side,right}]), HelpM = gs:create(menu,Help,[]), gs:create(menuitem,HelpM,[{label,{text,"About..."}}, {data,about_help}]), gs:create(menuitem,HelpM,[{label,{text,"Toolbar"}}, {data,{help,toolbar_lib:help_file()}}]), gs:create(menuitem,HelpM,[{label,{text,"OTP"}}, {data,{help,toolbar_lib:otp_file()}}]), gs:create(menuitem,HelpM,[{itemtype,separator}]), %% Check height of menu bar H = gs:read(Menubar,height), %% Now the height of the window can be computed Height = H+Norm+?hlabel+2*?pad, gs:config(Win,{height,Height}), %% Canvas, here will the Tool canvasbuttons be inserted Canvas = gs:create(canvas,Win,[{width,?width},{height,Norm},{x,0},{y,H}]), %% Label for displaying help messages and the frame containing it LabelF = gs:create(frame,Win,[{bg,green},{bw,1}, {width,?width},{height,?hlabel+2*?pad}, {x,0},{y,H+Norm}]), Label = gs:create(label,LabelF,[{align,w},{height,?hlabel}, {width,?width},{x,?pad},{y,?pad}, {label,{text,string:copies(" ",30)}}]), gs:config(Win,{map,true}), #tbwindow{window=Win, menubar=Menubar,canvas=Canvas,labelframe=LabelF, label=Label,helpmenu=HelpM, no_of_buttons=0, min_height=Height,min_width=?width,cur_height=Height, icons=[]}.%----------------------------------------% redraw_window(Window,{NewWidth,NewHeight}) => NewWindow% Window, NewWindow - tbwindow record% NewWidth, NewHeight - integer()% Redraw main window contents according to a new size%----------------------------------------redraw_window(Window,{NewWidth,NewHeight}) -> MinWidth = Window#tbwindow.min_width, if NewWidth=<MinWidth -> true; true -> gs:config(Window#tbwindow.canvas,{width,NewWidth}), gs:config(Window#tbwindow.labelframe,{width,NewWidth}), gs:config(Window#tbwindow.label,{width,NewWidth-2*?pad}) end, MinHeight = Window#tbwindow.min_height, if NewHeight=<MinHeight -> Window; true -> %% Compute size difference Diff = NewHeight - Window#tbwindow.cur_height, %% Resize button frame Canvas = Window#tbwindow.canvas, gs:config(Canvas,{height,gs:read(Canvas,height)+Diff}), %% Move label frame accordingly LabelF = Window#tbwindow.labelframe, gs:config(LabelF,{y,gs:read(LabelF,y)+Diff}), %% Return updated tbwindow record Window#tbwindow{cur_height=NewHeight} end.%----------------------------------------% already_added(Window,ToolInfo) => true | false% Window - tbwindow record% ToolInfo - toolinfo record% Returns true if ToolInfo contains information about a tool that% is already included in Window%----------------------------------------already_added(Window,ToolInfo) -> already_added2(Window#tbwindow.icons,ToolInfo#toolinfo.tool).%----------------------------------------% already_added2(ToolInfos,Tool) => true | false% ToolInfos - [toolinfo record]% Tool - atom() Tool name%----------------------------------------already_added2([#toolinfo{tool=Tool}|_Rest],Tool) -> true;already_added2([_|Rest],Tool) -> already_added2(Rest,Tool);already_added2([],_ToolInfo) -> false.%----------------------------------------% add_icon(Window,ToolInfo) => NewWindow% Window, NewWindow - tbwindow record% ToolInfo - toolinfo record% Add an icon to the main window%----------------------------------------add_icon(Window,ToolInfo) -> Norm = ?icon + 2*?pad, %% Extend window if necessary N = Window#tbwindow.no_of_buttons, ReqWidth = N*Norm+Norm, CurWidth = gs:read(Window#tbwindow.window,width), if ReqWidth>CurWidth -> gs:config(Window#tbwindow.window,{width,ReqWidth}), gs:config(Window#tbwindow.canvas,{width,ReqWidth}), gs:config(Window#tbwindow.labelframe,{width,ReqWidth}), gs:config(Window#tbwindow.label,{width,ReqWidth-2*?pad}); true -> true end, %% Insert icon into button frame canvasbutton:create(Window#tbwindow.canvas, [{image,ToolInfo#toolinfo.icon}, {x,N*Norm+?pad},{y,?pad}, {width,?icon},{height,?icon}, {data,{{start,ToolInfo#toolinfo.start}, {message,ToolInfo#toolinfo.message}}}]), %% Insert tool name into help menu (if there is any help available) case ToolInfo#toolinfo.html of nofile -> true; Html -> gs:create(menuitem,Window#tbwindow.helpmenu, [{label,{text,ToolInfo#toolinfo.tool}}, {data,{help,Html}}]) end, MinWidth = gs:read(Window#tbwindow.window,width), Window#tbwindow{no_of_buttons=N+1,min_width=MinWidth, icons=[ToolInfo|Window#tbwindow.icons]}.%----------------------------------------% get_window(Window) -> gs_obj()% Window - tbwindow record%----------------------------------------get_window(Window) -> Window#tbwindow.window.%----------------------------------------% cursor(Window,Cursor)% Window - tbwindow record% Cursor - arrow | busy%----------------------------------------cursor(Window,Cursor) -> gs:config(Window#tbwindow.window,{cursor,Cursor}).%----------------------------------------% listen_configure(Window)% Window - tbwindow record% Configure Window to listen for configure events%----------------------------------------listen_configure(Window) -> gs:config(Window#tbwindow.window,{configure,true}).%----------------------------------------% display_show(Window,Text)% Window - tbwindow record% Text - string()% Display text in the help text area%----------------------------------------display_show(Window,Text) -> gs:config(Window#tbwindow.label,{label,{text,Text}}).%----------------------------------------% display_clear(Window)% Window - tbwindow record% Clear the help text area%----------------------------------------display_clear(Window) -> display_show(Window,"").%%% Internal functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%----------------------------------------% within(X,Y,[{Left,Top},{Right,Bot}]) => true | false% Return true if {X,Y} is within the given rectangle.%----------------------------------------within(X,Y,[{L,T},{R,B}]) -> if X>=L, X=<R, Y>=T, Y=<B -> true; true -> false end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -