aboutsummaryrefslogtreecommitdiffstats
path: root/lib/toolbar/src/canvasbutton.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/toolbar/src/canvasbutton.erl')
-rw-r--r--lib/toolbar/src/canvasbutton.erl236
1 files changed, 236 insertions, 0 deletions
diff --git a/lib/toolbar/src/canvasbutton.erl b/lib/toolbar/src/canvasbutton.erl
new file mode 100644
index 0000000000..38fce537bb
--- /dev/null
+++ b/lib/toolbar/src/canvasbutton.erl
@@ -0,0 +1,236 @@
+%%
+%% %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.