%% %% %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% %% %% %% ------------------------------------------------------------ %% Basic Frame Type. %% ------------------------------------------------------------ -module(gstk_frame). %%----------------------------------------------------------------------------- %% FRAME OPTIONS %% %% Attributes: %% anchor n,w,s,e,nw,se,ne,sw,center %% bg Color %% bw Int %% data Data %% height Int %% highlightbg Color %% highlightbw Int %% highlightfg Color %% relief Relief [flat|raised|sunken|ridge|groove] %% width Int %% x Int %% y Int %% cursor arrow|busy|cross|hand|help|resize|text %% %% Commands: %% setfocus Bool %% %% Events: %% buttonpress [Bool | {Bool, Data}] %% buttonrelease [Bool | {Bool, Data}] %% configure [Bool | {Bool, Data}] %% destroy [Bool | {Bool, Data}] %% enter [Bool | {Bool, Data}] %% focus [Bool | {Bool, Data}] %% keypress [Bool | {Bool, Data}] %% keyrelease [Bool | {Bool, Data}] %% leave [Bool | {Bool, Data}] %% motion [Bool | {Bool, Data}] %% %% Read Options: %% children %% id %% parent %% type %% -export([create/3,config/3,read/3,delete/2,event/5,option/5,read_option/5, mk_create_opts_for_child/4]). -include("gstk.hrl"). %%----------------------------------------------------------------------------- %% MANDATORY INTERFACE FUNCTIONS %%----------------------------------------------------------------------------- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Function : create/3 %% Purpose : Create a widget of the type defined in this module. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% create(DB, GstkId, Opts) -> TkW = gstk_generic:mk_tkw_child(DB,GstkId), NGstkid=GstkId#gstkid{widget=TkW}, PlacePreCmd = [";place ", TkW], case gstk_generic:make_command(Opts, NGstkid, TkW, "", PlacePreCmd, DB) of {error,Reason} -> {error,Reason}; Cmd when is_list(Cmd) -> gstk:exec(["frame ", TkW, " -relief raised -bo 0",Cmd]), NGstkid end. mk_create_opts_for_child(DB,Cgstkid, Pgstkid, Opts) -> gstk_generic:mk_create_opts_for_child(DB,Cgstkid,Pgstkid,Opts). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Function : config/3 %% Purpose : Configure a widget of the type defined in this module. %% Args : DB - The Database %% Gstkid - The gstkid of the widget %% Opts - A list of options for configuring the widget %% %% Return : [true | {bad_result, Reason}] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% config(DB, Gstkid, Opts) -> TkW = Gstkid#gstkid.widget, SimplePreCmd = [TkW, " conf"], PlacePreCmd = [";place ", TkW], Opts2 = atomic_width_height(false,false,Opts), gstk_generic:mk_cmd_and_exec(Opts2,Gstkid,TkW,SimplePreCmd,PlacePreCmd,DB). atomic_width_height(false,false,[]) -> []; atomic_width_height(false,Width,[]) -> [{width,Width}]; atomic_width_height(Height,false,[]) -> [{height,Height}]; atomic_width_height(H,W,[]) -> [{width_height,{W,H}}]; atomic_width_height(_,W,[{height,H}|Opts]) -> atomic_width_height(H,W,Opts); atomic_width_height(H,_,[{width,W}|Opts]) -> atomic_width_height(H,W,Opts); atomic_width_height(H,W,[Opt|Opts]) -> [Opt|atomic_width_height(H,W,Opts)]. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Function : read/3 %% Purpose : Read one option from a widget %% Args : DB - The Database %% Gstkid - The gstkid of the widget %% Opt - An option to read %% %% Return : [OptionValue | {bad_result, Reason}] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% read(DB, Gstkid, Opt) -> gstk_generic:read_option(DB, Gstkid, Opt). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Function : delete/2 %% Purpose : Delete widget from databas and return tkwidget to destroy %% Args : DB - The Database %% Gstkid - The gstkid of the widget %% %% Return : TkWidget to destroy %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% delete(DB, Gstkid) -> gstk_db:delete_widget(DB, Gstkid), Gstkid#gstkid.widget. event(DB, Gstkid, Etype, Edata, Args) -> gstk_generic:event(DB, Gstkid, Etype, Edata, Args). %%----------------------------------------------------------------------------- %% MANDATORY FUNCTIONS %%----------------------------------------------------------------------------- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Function : option/4 %% Purpose : Take care of options %% Args : Option - An option tuple %% Gstkid - The gstkid of the widget %% TkW - The tk-widget %% DB - The Database %% %% Return : A tuple {OptionType, OptionCmd} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% option(Option, Gstkid, _TkW, DB,_) -> case Option of {bg, Color} -> {s, [" -bg ", gstk:to_color(Color)]}; {packer_x, _Pack} -> gstk_db:insert_opt(DB,Gstkid,Option), none; {packer_y, _Pack} -> gstk_db:insert_opt(DB,Gstkid,Option), none; {width, W} -> execute_pack_cmds(DB,xpack(W,DB,Gstkid)), {s,[" -wi ", gstk:to_ascii(W)]}; {height, H} -> execute_pack_cmds(DB,ypack(H,DB,Gstkid)), {s,[" -he ", gstk:to_ascii(H)]}; {width_height,{W,H}} -> execute_pack_cmds(DB, merge_pack_cmds(xpack(W,DB,Gstkid), ypack(H,DB,Gstkid))), {s,[" -he ", gstk:to_ascii(H)," -wi ", gstk:to_ascii(W)]}; _ -> invalid_option end. xpack(W,DB,Gstkid) -> gstk_db:insert_opt(DB,Gstkid,{width,W}), case gstk_db:opt_or_not(DB,Gstkid,packer_x) of {value,Pack} when is_list(Pack) -> ColSiz = gs_packer:pack(W,Pack), pack_children(pack_x,x,width,DB, gstk_db:lookup_kids(DB,Gstkid#gstkid.id), ColSiz); _Else -> [] end. ypack(H,DB,Gstkid) -> gstk_db:insert_opt(DB,Gstkid,{height,H}), case gstk_db:opt_or_not(DB,Gstkid,packer_y) of {value,Pack} when is_list(Pack) -> ColSiz = gs_packer:pack(H,Pack), pack_children(pack_y,y,height,DB, gstk_db:lookup_kids(DB,Gstkid#gstkid.id), ColSiz); _Else -> [] end. merge_pack_cmds([{Id,Opts1}|Cmds1],[{Id,Opts2}|Cmds2]) -> [{Id,Opts1++Opts2}|merge_pack_cmds(Cmds1,Cmds2)]; merge_pack_cmds(L1,L2) -> L1++L2. execute_pack_cmds(DB,[{Id,Opts}|Cmds]) -> gstk:config_impl(DB,Id,Opts), execute_pack_cmds(DB,Cmds); execute_pack_cmds(_,[]) -> ok. %%---------------------------------------------------------------------- %% Returns: list of {Id,Opts} to be executed (or merged with other first) %%---------------------------------------------------------------------- pack_children(PackOpt,PosOpt,SizOpt,DB,Kids,Sizes) -> Schildren = keep_packed(Kids,PackOpt,DB), pack_children2(PackOpt,PosOpt,SizOpt,Schildren,Sizes). pack_children2(PackOpt,PosOpt,SizOpt,[{StartStop,Id}|Childs],Sizes) -> [pack_child(Id,StartStop,SizOpt,PosOpt,Sizes) | pack_children2(PackOpt,PosOpt,SizOpt,Childs,Sizes)]; pack_children2(_,_,_,[],_) -> []. pack_child(Id,{StartPos,StopPos},SizOpt,PosOpt,Sizes) -> {Pos,Size} = find_pos(StartPos,StopPos,1,0,0,Sizes), {Id,[{PosOpt,Pos},{SizOpt,Size}]}. %%---------------------------------------------------------------------- %% Returns: {PixelPos,PixelSize} %%---------------------------------------------------------------------- find_pos(_StartPos,Pos,Pos,AccPixelPos,AccPixelSize,[Size|_]) -> {AccPixelPos,Size+AccPixelSize}; find_pos(StartPos,StopPos,Pos,AccPixelPos,0,[Size|Sizes]) when Pos < StartPos -> find_pos(StartPos,StopPos,Pos+1,Size+AccPixelPos,0,Sizes); find_pos(_StartPos,StopPos,Pos,AccPixelPos,AccPixelSize,[Size|Sizes]) when Pos < StopPos -> find_pos(Pos,StopPos,Pos+1,AccPixelPos,Size+AccPixelSize,Sizes). keep_packed([Id|Ids],PackOpt,DB) -> case gstk:read_impl(DB,Id,PackOpt) of undefined -> keep_packed(Ids,PackOpt,DB); StartStop -> [{StartStop,Id} | keep_packed(Ids,PackOpt,DB)] end; keep_packed([],_,_) -> []. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Function : read_option/3 %% Purpose : Take care of a read option %% Args : DB - The Database %% Gstkid - The gstkid of the widget %% Option - An option %% %% Return : The value of the option or invalid_option %% [OptionValue | {bad_result, Reason}] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% read_option(Option,Gstkid,TkW,_DB,_) -> case Option of bg -> tcl2erl:ret_color([TkW," cg -bg"]); _ -> {bad_result, {Gstkid#gstkid.objtype, invalid_option, Option}} end. %% ----- Done -----