/* LPA Prolog
4.1 "gfx-graphics-based text menus"
-(c) George A. Stathis 2001/2002
*/
:- dynamic tx/2.
:- dynamic prevw/2.
/* DESCRIPTION:
These menus are more flexible than "usual"
Windows-menus, in the sense that they can be freely and easily mixed with
any other graphics (gfx- or other), while both mouse buttons
can control (user-specified) events and colours. The menu's options change
colours every time the mouse-cursor enters their area, etc. - and all
this with an astonishingly small number of code lines! Note
that this file is only a small, trivial example of the beauty and simplicity
of gfx_grafics-based text menus. My commercial
application "HyperLEX 2002" (a multi-language "intelligent software dictionary")
uses advanced forms of such graphic menus that are full-blown hypertext
browsers as well as menus at the same time. The source-code for advanced
gfx-based text menus and hypertext browsers can be made available on special
request, at a high price. But the simple code that follows in this page
also does wonders, compared to existing techniques, and you can use it
in your own programs freely, provided you acknowledge its source.
*/
test:- SL = [`first`,`second`,`third`,`fourth`,`fifth`,`sixth`,`end`],
repeat, Row is int(rand(200)), Col=Row,
gfxmenu(0,Col,Row,`VERTICAL gfx_menu`,SL,SELx,RESPx),
write(selected(SELx,RESPx)), nl,
gfxmenu(1,Col,Row,`HORIZONTAL gfx_menu`,SL,SELy,RESPy),
writeq(selected(SELy,RESPy)), nl,nl,
(RESPy=close;RESPx=close), !.
%% main predicate is gfxmenu/7,
where 1st argument is "type"
%% (0=vertical, 1=horizontal), 2nd and
3rd arguments are column
%% and row of top-left-corner on the screen,
4th arg. is TITLE,
%% 5th argument is a list of strings for
the menu-contents,
%% 6th arg. is the selected string, and
7th argument is the menu-
%% response ( one of [more,close,leftdown(choice_string)]
):
gfxmenu(TYPE,Col,Row,Title,SL,SELECTED,Resp):-
_S1 = [dlg_ownedbyprolog,ws_sysmenu,ws_caption],
_S2 = [ws_child,ws_border,ws_visible],
get_size(VGAwid,VGAhei), retractall(tx(_,_)),
wdcreate('X',Title,0,0,VGAwid,VGAhei,_S1),
gfx_font_create(gfxfont,courier,20,bold),
gfx_font_create(gfxfont2,courier,23,bold),
gfx_brush_create(eraser,255,255,255,solid),
gfx_brush_create(marker,170,170,170,solid),
gfx_brush_create(bblue,0,0,255,solid),
gfx_brush_create(bgreen,0,255,0,solid),
gfx_brush_create(bblack,127,127,127,solid),
gfx_back_create(whitebk,255,255,255),
gfx_pen_create(whitef,255,255,255,solid),
wfsizelist(gfxfont2,SL,0,0,WW,HH),
window_handler('X',phandler), show_dialog('X'),
len(SL,Max), initgfx_hbuttons(TYPE,1,Max,Col,Row,WW,HH),
fillgfx_hbuttons(1,eraser,SL), retractall(prevw(_,_)),
wait_dialog(Resp), prevw(_,SELECTED), xx, !.
% initgfx_hbuttons/6 initialises the menu's "virtual buttons"
(rectangles):
initgfx_hbuttons(_,N,Max,_,_,_,_):- N > Max, !.
initgfx_hbuttons(TYP,N,Max,C,R,W,H):- Wn is 9000+N,
wccreate(('X',Wn),grafix,``,C,R,W,H,
[ws_child,ws_border,ws_visible]),
(TYP=0 -> (R2 is R+H+3,C2=C);(R2 = R,C2 is C+W+3)),
NN is N+1, !, initgfx_hbuttons(TYP,NN,Max,C2,R2,W,H).
% fillgfx_hbuttons/4 displays the captions in the menu's (gfx-based)
rectangles
fillgfx_hbuttons(_,_,[]):- !.
fillgfx_hbuttons(N,Color,[Text|TL]):- Wn is 9000+N,
retractall(tx(('X',Wn),_)),
assert(tx(('X',Wn),Text)), showgfx_text(('X',Wn),Color,Text),
NN is N+1, !, fillgfx_hbuttons(NN,Color,TL).
% showgfx_text/3 draws rectangles-with-text for the menu's "gfx_objects",
% and avoids the use of buttons. These rectangles are more efficient
buttons!
showgfx_text(Win,Colour,Text):- wshow(Win,1),
warea(Win,Ci,Ri,Wi,Hi), gfx_begin(Win),
gfx(( back=whitebk,pen=whitef,brush=Colour
-> rectangle(0,0,Wi,Hi) )),
gfx(( brush=bblack,font=gfxfont -> text(0,0,Text) )),
gfx_end(Win), !.
% get_size/2 finds the size of the current VGA screen:
get_size(Xw,Yw):- gfx_begin(0),gfx_resolution(Xw,Yw,_,_),gfx_end(0),!.
% wait_dialog/1 is a "classic" event-handler recommended by LPA's
documentation:
wait_dialog(V):- wait((1,V)).
% wfsizelist/6 is an "extension" of LPA-predicate wfsize/4 to
lists of strings:
wfsizelist(_,[],WW,HH,WW,HH):- !.
wfsizelist(Font,[S|SL],W1,H1,WW,HH):- wfsize(Font,S,W,H),
W2 is max(W1,W), H2 is max(H1,H),
!, wfsizelist(Font,SL,W2,H2,WW,HH).
% phandler/4 is a "classic" window_handler predicate (consult
LPA Prolog HELP)
phandler(WND,msg_close,_,close):- retractall(prevw(_,_)),
assert(prevw(WND,``)), !.
phandler((WND,W9),msg_leftdown,_,leftdown(TX)):- tx((WND,W9),TX),
showgfx_text((WND,W9),bgreen,TX), !.
phandler((WND,W9),msg_leftup,_,leftup(TX)):- tx((WND,W9),TX),
showgfx_text((WND,W9),marker,TX),
retractall(prevw(_,_)), assert(prevw((WND,W9),TX)), !.
phandler((WND,W9),msg_rightdown,_,rightdown(TX)):- tx((WND,W9),TX),
showgfx_text((WND,W9),bgreen,TX), !.
phandler((WND,W9),msg_rightup,_,rightup(TX)):- tx((WND,W9),TX),
showgfx_text((WND,W9),marker,TX), !.
phandler((WND,W9),msg_mousemove,_,more):- tx((WND,W9),TX),
\+prevw((WND,W9),_),
(prevw(W1,TX0) -> showgfx_text(W1,eraser,TX0); true),
retractall(prevw(_,_)), assert(prevw((WND,W9),TX)),
showgfx_text((WND,W9),marker,TX), !, fail.
% xx/0 shuts down the gfx objects used by this program -and windows
created:
xx:- gfx_back_dict(WL), member(F,WL), gfx_back_close(F),
fail.
xx:- gfx_pen_dict(WL), member(F,WL), gfx_pen_close(F), fail.
xx:- gfx_brush_dict(WL), member(F,WL), gfx_brush_close(F),
fail.
%%% the following clause has some unpleasant
side-effects when
%%% running within the LPA 4.1 development
environment, but is free
%%% of such side-effects in a stand-alone
appication:
%xx:- gfx_font_dict(WL), member(F,WL), gfx_font_close(F),
fail.
xx:- wdict(WL), member('X',WL), wclose('X'), fail.
xx.
/* TERMS: This code can be used freely in your
own (LPA Prolog-) applications, but requires
acknowledgement of its
source */
|