% Charles De Lean July 1995 : linechoice does not give any key. % Charles De Lean August 1995 : added more space for lines. !ListWindow is made to intercept double-clicks as a way of selection. inverting lines are made only on button click. Not on any movement of the pointer; ListWindow CLASS SelectionListWindow; BEGIN !reporter le double-click au parent; PROCEDURE handle_second_click(b); INTEGER b; BEGIN parent.handle_second_click(b); END; !Keep inverted line if the mouse gets out of the window; PROCEDURE handle_leave_window;; !Selection is made on button_click. No more on button_up or down; PROCEDURE handle_button_down(b); INTEGER b;; PROCEDURE handle_button_up(b); INTEGER b;; PROCEDURE handle_button_click(b); INTEGER b; BEGIN Line_last := min(info_top, Line_of(y_of_event)); InvertSelection; invert_line_nr := Line_last; InvertSelection; parent.LineChoice (Lines.get(Line_last)); parent.LineChoiceIn(Lines.get(Line_last), Line_Last, this ListWindow); END; !Do not change selection with pointer motion; PROCEDURE handle_pointer_motion(x, y); integer x, y;; !Simulate a click to choose default selection; PROCEDURE DefaultSel(ind);INTEGER ind; BEGIN invert_line_nr:=ind; IF indwnd_top THEN ScrollToLine(ind); InvertSelection; END; OffInput; setcursor("arrow"); END; !This window remembers the last selection made and reports it when double_click is done or whrn the ok button is pressed; ScrollWindow CLASS MenuScrollWindow; VIRTUAL: PROCEDURE SelectionMade IS PROCEDURE SelectionMade;; PROCEDURE CreateSelectionWindow IS PROCEDURE CreateSelectionWindow;; PROCEDURE CreateButtons IS PROCEDURE CreateButtons;; BEGIN TEXT choice; !selected text; INTEGER Line; !line number of selected text; TEXT array Cle (1:500); !keys returned; PROCEDURE Perform(t); TEXT t; BEGIN IF t==ok_button.heading AND line_chosen THEN SelectionMade; IF t==hide_button.heading THEN BEGIN Hide; Line:=0; button_choice_made := TRUE; END; END; PROCEDURE LineChoice(T);TEXT t;; !Remember last selection; PROCEDURE LineChoiceIn(T,l,w); TEXT T; INTEGER L; REF(subwindow) w; BEGIN choice :- (IF l>0 AND Cle(l) =/= NOTEXT THEN Cle(l) ELSE T); !CDL July 25 1995; Line := l; line_chosen := true; END; PROCEDURE FinalSelection; !Report selection to parent window and stop any waiting loop frop buttonchoice; BEGIN parent.LineChoice(choice); parent.LineChoiceIn(choice, line, this ScrollWindow); button_choice_made := TRUE; hide; END; PROCEDURE SelectionMade; FinalSelection; PROCEDURE handle_second_click(b); INTEGER b; SelectionMade; PROCEDURE Resize; IF ok_button =/= NONE THEN BEGIN list_wnd.SetSize(width - scroll_box_width - ok_button.width - 4*subwindow_spacing - 2*(scroll_bar.BorderWidth + ok_button.BorderWidth + list_wnd.BorderWidth) , height - top_height); head_wnd .PlaceUpLeft; up_box .PlaceLeftBelow(head_wnd) .SetSize(scroll_box_width, scroll_box_height); scroll_bar.PlaceLeftBelow(up_box) .SetWidth(scroll_box_width); list_wnd .PlaceRightof(up_box); head_wnd .SetWidth(width - 2*subwindow_spacing); ok_button .PlaceRightBelow(head_wnd); hide_button.PlaceBelow(ok_button); scroll_bar.NewHeight(list_wnd.height - 2*scroll_box_height -2*subwindow_spacing - 4*BorderWidth); down_box .PlaceLeftBelow(scroll_bar) .SetSize(scroll_box_width, scroll_box_height); end; PROCEDURE SetSizeSub; resize; !Initialization of selectwindow; PROCEDURE SetMenu(question,choix,default);TEXT question,choix,default; BEGIN text array CA (1:500); !CDL 15 Aug 1995; TEXT Etiq; character C; integer i, Np, iDefault; Boolean OK; Text T; SetHeading(question); IF head_wnd.head_width > head_wnd.width THEN setwidth(head_wnd.head_width+ 2*(subwindow_spacing+head_wnd.BorderWidth)); SetSizeSub; C := Choix.sub(1,1).getchar; Np := splitc(from(Choix,2), C, CA ); iDefault := 1; i := 0; for i := i+1 while i<=Np and then CA(i) =/= notext do BEGIN Cle (i) :- scanto(CA(i),':'); Etiq :- rest(CA(i)); if Etiq == notext then BEGIN TEXT tmp; Etiq :- Cle(i); ! Doit etre fait en 2 passes car le parametre text de getword ; !est en name et on ne veux pas passer le copy en name; tmp :- copy(cle(i)); cle(i) :- lowcase(getWord(tmp)); END; Initputline(Etiq); if Cle(i) = Default then iDefault := i; END; refreshlines; (list_wnd QUA SelectionListWindow).DefaultSel(iDefault); LineChoiceIn(list_wnd.GetLine(iDefault),iDefault,NONE); show; refresh; END; !Waiting loop after a choice from user; TEXT PROCEDURE WaitMenu; BEGIN ButtonChoice; IF Line>0 THEN WaitMenu :- (IF Cle(Line) =/= NOTEXT THEN Cle(Line) ELSE choice) ELSE Waitmenu :- NOTEXT; END; TEXT PROCEDURE menu(question,choix,default);TEXT question,choix,default; BEGIN SetMenu(question,choix,default); menu:- WaitMenu; END; PROCEDURE CreateSelectionWindow; BEGIN list_wnd :- new SelectionListWindow(this ScrollWindow) .Show; END; PROCEDURE CreateButtons; BEGIN ok_button :- NEW Button(THIS XWindow,"Ok") .placerightbelow(list_wnd) .show; hide_button :- NEW Button(THIS XWindow,"Cancel") .placebelow(ok_button).show; ok_button.SetWidth(hide_button.width); END; !Replacing default list_wnd by our own; list_wnd.Destroy; CreateSelectionWindow; allowchoice; SetHeading(" "); SetHeadFont(FontName("courier", default_font_points, false, false)); CreateButtons; SetSizeSub; END; element CLASS DirEntry(filename,isdir);TEXT filename;BOOLEAN isdir; BEGIN TEXT PROCEDURE key; key :- filename; END; !This window is a file select widget. DirName is the directory to start with. If notext is given, current directory is used; MenuScrollWindow CLASS DirectoryMenu(DirName);TEXT DirName; BEGIN REF(DirectoryFile) Dir; TEXT t; INTEGER i; PROCEDURE SelectionMade; BEGIN TEXT t; choice.Setpos(choice.Length); IF choice.GetChar='/' THEN BEGIN IF DirName<>"/" THEN t:-DirName; t:-t&"/"&choice.Sub(1,choice.Length-1); % readdir((IF DirName<>"/" THEN DirName ELSE NOTEXT)&"/" % &choice.Sub(1,choice.Length-1)) readdir(t); END ELSE BEGIN choice:-(IF DirName<>"/" THEN DirName ELSE NOTEXT)&"/"&choice; FinalSelection; END; END; BOOLEAN PROCEDURE readdir(path);TEXT path; BEGIN REF(simple_table) entries; INTEGER nbentries,i; Dir :- NEW DirectoryFile(path); entries :- NEW simple_table(50); IF Dir.Open THEN BEGIN list_wnd.MakeEmpty; WHILE Dir.Nextentry DO BEGIN nbentries:=nbentries+1; entries.insert(NEW DirEntry(Dir.EntryName,Dir.EntryIsDir)); END; entries.sort; i:=0; FOR i:=i+1 WHILE i<=nbentries DO BEGIN t:-entries.get(i) QUA direntry.filename; IF entries.get(i) QUA direntry.isdir THEN t:- t&"/"; InitPutLine(t); END; !InitPutLine does not refresh the window; RefreshLines; Dir.Close; DirName:-Dir.Directory; SetHeading(DirName); readdir:=TRUE; END ELSE readdir:=FALSE; END; readdir(DirName); END;