%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 1996-2009. All Rights Reserved. %% %% 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 online 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. %% %% %CopyrightEnd% %% -module(canvasbutton). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Erlang Toolbar % %%% Description %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Extension to GS used to imitate buttons but instead using images drawn % on a canvas. Enables usage of .gif files as button images and not only % .xbm (bitmap) files. % %%% Constants %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -define(gray,{87,87,87}). % %%% Internal data structures %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % canvasbutton() -record(canvasbutton,{image,rect,ul,ll}). % % cboptions() -record(cboptions, {imagefile=nofile, % nofile | % string() Name of image file x=0, % integer() X coordinate relative the canvas y=0, % integer() Y coordinate relative the canvas width=10, % integer() Button width height=10, % integer() Button heigth fg=black, % atom() Foreground color data=[]}). % term() Data associated with button events % %%% Exports %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -export([create/1,create/2,read/2,press/1,release/1]). % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Exported functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %---------------------------------------- % create(Canvas) => create(Canvas,[]) % create(Canvas,OptionList) => canvasbutton() % Canvas - GS canvas object % OptionList - [{Option,Value}] % Option, Value - see below % Create a canvasbutton with the given image on Canvas % % Option Value Default Comment % ---------------------------------------------------------------- % image nofile | nofile Name of image file. Must be a bitmap % string() file (.xbm) or a GIF file (.gif). % x integer() 0 X coordinate relative to Canvas % y integer() 0 Y coordinate relative to Canvas % width integer() 10 Button width % height integer() 10 Button height % fg atom() black Foreground color, bitmaps only % data term() [] Data associated with button events % % The process calling this function will receive the following events: % {gs,GsObj,enter,{canvasbutton,Canvasbutton,Data},Args} % {gs,GsObj,leave,{canvasbutton,Canvasbutton,Data},Args} % {gs,GsObj,buttonpress,{canvasbutton,Canvasbutton,Data},Args} % {gs,GsObj,buttonrelease,{canvasbutton,Canvasbutton,Data},Args} % where GsObj and Args are a GS object and its Args field, respectively. % % Note that press/1 and release/1 has to be called explicitly to create % the illusion of the button being pressed or released. %---------------------------------------- create(Canvas) -> create(Canvas,[]). create(Canvas,OptionList) -> Options = sort_out_options(OptionList), X = Options#cboptions.x, Y = Options#cboptions.y, W = Options#cboptions.width, H = Options#cboptions.height, %% Buttons should have the same background color as the canvas Bg = gs:read(Canvas,bc), %% Draw image Image = create_image(Options#cboptions.imagefile,Canvas,Bg, Options#cboptions.fg,X,Y,W,H), %% Draw upper left corner line Ul = gs:create(line,Canvas,[{coords,[{X,Y+H},{X,Y},{X+W,Y}]}, {fg,white},{width,2}]), %% Draw lower right corner line Ll = gs:create(line,Canvas,[{coords,[{X,Y+H},{X+W,Y+H},{X+W,Y}]}, {fg,?gray},{width,2}]), %% Draw a rectangle around all (for event catching when width and %% height of button is larger than image) Rect = gs:create(rectangle,Canvas,[{coords,[{X,Y},{X+W,Y+H}]}, {fill,Bg}, {buttonpress,true}, {buttonrelease,true}, {enter,true},{leave,true}]), %% Now the canvas button is created Canvasbutton = #canvasbutton{image=Image,rect=Rect,ul=Ul,ll=Ll}, Data = Options#cboptions.data, gs:config(Rect,{data,{canvasbutton,Canvasbutton,Data}}), gs:config(Image,{data,{canvasbutton,Canvasbutton,Data}}), gs:config(Rect,lower), gs:config(Image,raise), Canvasbutton. %---------------------------------------- % read(Canvasbutton,coords) => [{L,T},{R,B}] % Canvasbutton - canvasbutton() % Read a Canvasbutton's coordinates %---------------------------------------- read(Canvasbutton,coords) -> gs:read(Canvasbutton#canvasbutton.rect,coords). %---------------------------------------- % press(Canvasbutton) % Canvasbutton - canvasbutton() % Create the illusion that Canvasbutton is pressed %---------------------------------------- press(Canvasbutton) -> gs:config(Canvasbutton#canvasbutton.ul,{fg,?gray}), gs:config(Canvasbutton#canvasbutton.ll,{fg,white}), case Canvasbutton#canvasbutton.image of noimage -> ignore; Image -> gs:config(Image,{move,{-1,-1}}) end. %---------------------------------------- % release(Canvasbutton) % Canvasbutton - canvasbutton() % Create the illusion that Canvasbutton is released %---------------------------------------- release(Canvasbutton) -> gs:config(Canvasbutton#canvasbutton.ul,{fg,white}), gs:config(Canvasbutton#canvasbutton.ll,{fg,?gray}), case Canvasbutton#canvasbutton.image of noimage -> ignore; Image -> gs:config(Image,{move,{1,1}}) end. %%% Internal functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %---------------------------------------- % create_image(ImageFile,Canvas,Bg,Fg,X,Y,W,H) => Image % ImageFile - string() Image file, must exist and be a bitmap file ending % with .xbm or a GIF file ending with .gif. % Canvas - GS canvas object % Bg - atom() Background color (bitmaps only) % Fg - atom() Foreground color (bitmaps only) % X, Y - int() X and Y coordinates for Image relative to Canvas % W, H - int() Width and height of Image % Image - GS canvas image object %---------------------------------------- create_image(nofile,_,_,_,_,_,_,_) -> noimage; create_image(ImageFile,Canvas,Bg,Fg,X,Y,W,H) -> case lists:last(string:tokens(ImageFile,".")) of "xbm" -> gs:create(image,Canvas, [{bitmap,ImageFile}, {bg,Bg},{fg,Fg}, {anchor,c}, {coords,[{X+1+W/2,Y+1+H/2}]}, {buttonpress,true}, {buttonrelease,true}, {enter,true},{leave,true}]); "gif" -> gs:create(image,Canvas, [{load_gif,ImageFile}, {anchor,c}, {coords,[{X+W/2,Y+H/2}]}, {buttonpress,true}, {buttonrelease,true}, {enter,true},{leave,true}]) end. %---------------------------------------- % sort_out_options(OptionList) => cboptions() % OptionList - see create/2 % Insert members of option list into a cboptions record. %---------------------------------------- sort_out_options(OptionList) -> sort_out_options(OptionList,#cboptions{}). %---------------------------------------- % sort_out_options(OptionList,Options) => cboptions() % OptionList - see create/2 % Options - cboptions() % Called by sort_out_options/1. %---------------------------------------- sort_out_options([{image,Image}|Rest],Options) -> sort_out_options(Rest,Options#cboptions{imagefile=Image}); sort_out_options([{x,X}|Rest],Options) -> sort_out_options(Rest,Options#cboptions{x=X}); sort_out_options([{y,Y}|Rest],Options) -> sort_out_options(Rest,Options#cboptions{y=Y}); sort_out_options([{width,Width}|Rest],Options) -> sort_out_options(Rest,Options#cboptions{width=Width}); sort_out_options([{height,Height}|Rest],Options) -> sort_out_options(Rest,Options#cboptions{height=Height}); sort_out_options([{fg,Fg}|Rest],Options) -> sort_out_options(Rest,Options#cboptions{fg=Fg}); sort_out_options([{data,Data}|Rest],Options) -> sort_out_options(Rest,Options#cboptions{data=Data}); sort_out_options([],Options) -> Options.