34
35:- module(pce_prompter,
36 [ prompter/2
37 ]). 38:- use_module(library(pce)). 39:- use_module(library(pce_report)). 40:- require([ delete/3
41 , maplist/3
42 , term_to_atom/2
43 ]). 44
79
80:- pce_global(@prompter, make_promper). 81
82make_promper(P) :-
83 new(P, dialog),
84 send(P, resize_message, message(@prolog, stretch_items, P)),
85 send(new(report_dialog), below, P),
86 send(P, done_message, message(P, return, cancel)).
87
88prompter(Title, Attributes) :-
89 maplist(canonicalise_attribute, Attributes, CAtts),
90 send(@prompter, clear),
91 maplist(append_prompter(@prompter), CAtts),
92 send(@prompter, append,
93 new(Ok, button(ok, message(@prompter, return, ok))), next_row),
94 send(Ok, default_button, @on),
95 send(@prompter, append,
96 button(cancel, message(@prompter, return, cancel))),
97 get(@prompter, frame, Frame),
98 send(Frame, label, Title),
99 send(@prompter, fit),
100 stretch_items(@prompter),
101 ( send(@event, instance_of, event)
102 -> get(@event, position, @display, Pos),
103 get(@event?receiver, frame, MainFrame),
104 send(Frame, transient_for, MainFrame),
105 send(Frame, modal, transient)
106 ; Pos = @default
107 ),
108 repeat,
109 ( get(@prompter, confirm_centered, Pos, OK)
110 ; get(@prompter, confirm, OK) 111 ),
112 ( OK == ok
113 -> maplist(read_prompter(@prompter), CAtts),
114 !,
115 send(@prompter, show, @off)
116 ; !,
117 send(@prompter, show, @off),
118 fail
119 ).
120
121canonicalise_attribute(Label:Type = Value, Label:PceType = Value) :-
122 pce_type(Type, PceType).
123
124pce_type(Type, Type) :-
125 atom(Type),
126 !.
127pce_type(Term, Type) :-
128 term_to_atom(Term, A0),
129 atom_codes(A0, S0),
130 delete(S0, 0' , S1),
131 atom_codes(Type, S1).
132
133
134 137
138stretch_items(Dialog) :-
139 send(Dialog?graphicals, for_all,
140 message(@prolog, stretch_item, @arg1)).
141
142stretchable(text_item).
143stretchable(list_browser).
144
145stretch_item(Item) :-
146 get(Item, class_name, ClassName),
147 stretchable(ClassName),
148 \+ (get(Item, right, RI), RI \== @nil),
149 !,
150 get(Item?device?visible, right_side, Right),
151 get(Item?device?gap, width, W),
152 R is Right - W,
153 get(Item, left_side, L),
154 Width is R - L,
155 send(Item, do_set, width := Width).
156stretch_item(_).
157
158
159 162
163append_prompter(P, Label:Type = Value) :-
164 make_dialog_item(Type, Label, DI),
165 set_default(Value, DI),
166 send(P, append, DI).
167
168 169make_dialog_item(Type, Label, DI) :-
170 get(@pce, convert, Type, type, PceType),
171 get(PceType, kind, Kind),
172 dialog_item_from_type_kind(Kind, PceType, Label, DI),
173 !.
174make_dialog_item(Type, Label, DI) :-
175 get(@pce, convert, Type, type, PceType),
176 get(PceType, value_set, Set),
177 !,
178 get(Set, size, Size),
179 ( Size < 6
180 -> new(DI, menu(Label, choice))
181 ; new(DI, list_browser(@default, 10, 6)),
182 send(DI, label, Label),
183 send(DI, name, Label)
184 ),
185 send(Set, for_all, message(DI, append, @arg1)).
186make_dialog_item(Type, Label, DI) :-
187 new(DI, text_item(Label, '')),
188 send(DI, type, Type).
189
190
191dialog_item_from_type_kind(int, Type, Label, DI) :-
192 !,
193 new(DI, int_item(Label)),
194 send(DI, type, Type).
195dialog_item_from_type_kind(Range, Type, Label, DI) :-
196 ( Range == int_range
197 ; Range == real_range
198 ),
199 !,
200 get(Type?context, first, Low),
201 get(Type?context, second, High),
202 new(DI, slider(Label, Low, High, (Low+High)/2)).
203
204
205 208
209set_default(Value, DI) :-
210 nonvar(Value),
211 Value = _RVal/Default,
212 !,
213 send(DI, selection, Default).
214set_default(_, _).
215
216 219
220read_prompter(P, Label:Type = Value) :-
221 get(P, member, Label, DI),
222 ( get(DI, selection, V0)
223 -> canonicalise(DI, V0, V1),
224 ( get(@pce, convert, V1, Type, Val)
225 -> ( nonvar(Value),
226 Value = RVal/_
227 -> RVal = Val
228 ; Value = Val
229 )
230 ; send(DI, report, warning, 'Invalid value for %s', Label),
231 fail
232 )
233 ; send(DI, report, warning, 'No selection for %s', Label),
234 fail
235 ).
236
237
238canonicalise(DI, A, B) :-
239 send(DI, instance_of, text_item),
240 !,
241 get(A, strip, B).
242canonicalise(DI, A, B) :-
243 send(DI, instance_of, list_browser),
244 !,
245 get(A, key, B).
246canonicalise(_, Val, Val).