%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 1997-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(pman_tool). %% Listbox selection window -export([select/3]). -record(state, {topwin, frame, listbox}). %% Constants -define(WIN_WIDTH, 350). -define(WIN_HEIGHT, 350). select(Win, Title, Choices) -> Self = self(), Pid = spawn_link(fun() -> init(Self, Win, Title, Choices) end), receive {Pid, Result} -> Result end. init(Pid, Win, Title, Choices) -> %% Create window State = create_window(Win, Title, Choices), gse:map(State#state.topwin), %% enter event loop loop(Pid, Choices, State). loop(Pid, Choices, State) -> receive {gs, _, destroy, _Data, _Args} -> Pid ! {self(), cancelled}; {gs, _, configure, _Data, [W, H|_]} -> gse:resize(State#state.frame, W, H), loop(Pid, Choices, State); {gs, _, click, ok, _Args} -> case gs:read(State#state.listbox, selection) of [] -> Pid ! {self(), cancelled}; Indices -> Selection = selection(Indices, Choices), Pid ! {self(), Selection} end; {gs, _, click, cancel, _Args} -> Pid ! {self(), cancelled}; {gs, Obj, doubleclick, _Data, _Args} -> self() ! {gs, Obj, click, ok, []}, loop(Pid, Choices, State); _GSEvent -> loop(Pid, Choices, State) end. selection(Indices, Choices) -> selection(0, Indices, Choices). selection(I, [I|Is], [{Val,_Str}|Vals]) -> [Val | selection(I+1, Is, Vals)]; selection(I, [I|Is], [Val|Vals]) -> [Val | selection(I+1, Is, Vals)]; selection(_I, [], _Vals) -> []; selection(I, Is, [_Val|Vals]) -> selection(I+1, Is, Vals). create_window(Win, Title, Choices) -> Font = pman_win:font(Win), %% Top window and a frame that covers it entirely, to allow %% usage of the packer for geometry management. Topwin = gse:window(Win, [{width, ?WIN_WIDTH}, {height,?WIN_HEIGHT}, {configure, true}, {title, Title}]), Frame = gse:frame(Topwin, [{packer_x,[{stretch,1}, {stretch,1}]}, {packer_y,[{stretch,1}, {stretch,5}, {stretch,1}]}]), %% Caption above the list of items CaptionTxt = "Select one or more of the following:", gse:label(Frame, [{pack_x,{1,2}}, {pack_y,{1,1}}, {label,{text,CaptionTxt}}, {font,Font}]), %% List of selectable items Listbox = gse:listbox(Frame, [{pack_x,{1,2}}, {pack_y,{2,2}}, {selectmode,multiple}, {doubleclick, true}, {font,Font}, {items, str_choices(Choices)}]), %% OK and Cancel buttons in a separate frame. F13 = gse:frame(Frame, [{bw,1}, {pack_xy,{{1,2},3}}, {packer_x,[{stretch,1}, {fixed, 60}, {stretch,1}, {fixed, 60}, {stretch,1}]}, {packer_y,[{stretch,1}, {fixed, 30}, {stretch,1}]}]), gse:button(F13, [{pack_xy,{2,2}}, {label,{text,"OK"}}, {font,Font}, {data,ok}]), gse:button(F13, [{pack_xy,{4,2}}, {label,{text,"Cancel"}}, {font,Font}, {data,cancel}]), gse:resize(Frame, ?WIN_WIDTH, ?WIN_HEIGHT), #state{topwin=Topwin, frame=Frame, listbox=Listbox}. str_choices(Choices) -> lists:map( fun({Val, Str}) -> lists:flatten(io_lib:format("~p: ~s", [Val, Str])); (Term) -> lists:flatten(io_lib:format("~p", [Term])) end, Choices).