Advanced dialogs¶
Advanced dialogs¶
1import win32com.client
2import win32com.server.util
3
4
5class _CallbackSink:
6 # COM adapter: Impact invokes dialog callbacks via IDispatch dispid 0
7 _public_methods_ = ["Invoke0"]
8 _dispid_to_func_ = {0: "Invoke0"}
9
10 def Invoke0(self, raw_params):
11 try:
12 return callback(IDialogCallbackParams(win32com.client.Dispatch(raw_params)))
13 except Exception as exc:
14 # ShowModal ignores callback errors; report them or they vanish silently
15 impact.gui.output_toolbox.add(f"Callback error: {exc!r}")
16
17
18preview_file1 = r"d:\preview1.ipd"
19preview_file2 = r"d:\preview2.ipd"
20
21picture_file1 = r"d:\picture1.jpg"
22picture_file2 = r"d:\picture2.jpg"
23
24
25# Define a function to describe a constant from the ipDialogCallbackReason enumeration
26_DESCRIBE_CALLBACK_REASON_MAP = {
27 ipDialogCallbackReason.dcrFieldSelected: "Field Selected",
28 ipDialogCallbackReason.dcrFieldCurrent: "Field Current",
29 ipDialogCallbackReason.dcrFieldNonCurrent: "Field Non Current",
30 ipDialogCallbackReason.dcrDialogClosing: "DialogClosing",
31}
32
33def describe_callback_reason(reason):
34 return _DESCRIBE_CALLBACK_REASON_MAP.get(reason, "Unknown")
35
36# Define a function to describe a constant from the ipDialogButtonType enumeration
37_DESCRIBE_DIALOG_BUTTON_TYPE_MAP = {
38 ipDialogButtonType.dbtUnknown: "Unknown",
39 ipDialogButtonType.dbtOk: "Ok",
40 ipDialogButtonType.dbtCancel: "Cancel",
41 ipDialogButtonType.dbtYes: "Yes",
42 ipDialogButtonType.dbtNo: "No",
43 ipDialogButtonType.dbtNext: "Next",
44 ipDialogButtonType.dbtPrevious: "Previous",
45 ipDialogButtonType.dbtClose: "Close",
46 ipDialogButtonType.dbtPrint: "Print",
47 ipDialogButtonType.dbtCustom: "Custom",
48}
49
50def describe_dialog_button_type(button_type):
51 return _DESCRIBE_DIALOG_BUTTON_TYPE_MAP.get(button_type, "Unknown")
52
53# Define a function to describe a constant from the ipDialogFieldType enumeration
54_DESCRIBE_DIALOG_FIELD_TYPE_MAP = {
55 ipDialogFieldType.dftUnknown: "Unknown",
56 ipDialogFieldType.dftAngle: "Angle",
57 ipDialogFieldType.dftArea: "Area",
58 ipDialogFieldType.dftCheckBox: "Check Box",
59 ipDialogFieldType.dftComboBox: "Combo Box",
60 ipDialogFieldType.dftDate: "Date",
61 ipDialogFieldType.dftDistance: "Distance",
62 ipDialogFieldType.dftInteger: "Integer",
63 ipDialogFieldType.dftLine: "Line",
64 ipDialogFieldType.dftListBox: "List Box",
65 ipDialogFieldType.dftPreview: "Preview",
66 ipDialogFieldType.dftRadioGroup: "Radio Group",
67 ipDialogFieldType.dftReal: "Real",
68 ipDialogFieldType.dftText: "Text",
69 ipDialogFieldType.dftTextBox: "Text Box",
70 ipDialogFieldType.dftTime: "Time",
71 ipDialogFieldType.dftTwinList: "Twin List",
72 ipDialogFieldType.dftVolume: "Volume",
73 ipDialogFieldType.dftWeight: "Weight",
74 ipDialogFieldType.dftPicture: "Picture",
75 ipDialogFieldType.dftButton: "Button",
76}
77
78def describe_dialog_field_type(field_type):
79 return _DESCRIBE_DIALOG_FIELD_TYPE_MAP.get(field_type, "Unknown")
80
81# Define a sub routine to display a list of items in the output toolbox
82def display_list_values(message, list):
83 ot.add(message)
84
85 for item in list:
86 ot.add(item)
87
88# Define a callback(), passed into the ShowModal method of IDialog
89def callback(callback_params):
90 field = callback_params.field
91
92 if not field.isNone():
93 ot.add(field.label + ": " + str(describe_callback_reason(callback_params.reason)))
94
95 if field.field_type == ipDialogFieldType.dftPicture:
96 ot.add("HasImage: " + str(field.picture_has_image))
97 else:
98 ot.add("Value: " + str(field.value))
99
100 if field.label == "Click Me!":
101 impact.gui.show_message(ipShowMessageType.smtInfo, "You clicked me!", None)
102
103 elif field.label == "Preview Group":
104 if field.value == 0:
105 preview_field.show_preview(preview_file1, "One up", True)
106 else:
107 preview_field.show_preview(preview_file2, "One up", True)
108
109 elif field.label == "load Picture 1":
110 pic1_field.show_picture(picture_file1)
111
112 elif field.label == "load Picture 2":
113 pic1_field.show_picture(picture_file2)
114
115 elif field.field_type == ipDialogFieldType.dftPicture:
116 if pic1_field.picture_has_image:
117 if pic1_field.picture_file_name == "":
118 impact.gui.show_message(ipShowMessageType.smtInfo, "The image was changed from the clipboard", None)
119
120 else:
121 impact.gui.show_message(ipShowMessageType.smtInfo, "The image was changed and loaded from '" + str(pic1_field.picture_file_name) + "'", None)
122
123 else:
124 impact.gui.show_message(ipShowMessageType.smtInfo, "The image was cleared", None)
125
126
127 if callback_params.reason == ipDialogCallbackReason.dcrDialogClosing:
128 ot.add(describe_dialog_button_type(callback_params.button_type))
129
130 if callback_params.button_type == ipDialogButtonType.dbtOk:
131 callback_params.can_close = allow_close_field.value
132
133
134# Create a local variable for the impact impact.gui object
135g = impact.gui
136
137# Create a local variable for the output toolbox
138ot = g.output_toolbox
139
140# Create a dialog
141d = g.make_dialog("Options")
142
143# Check the dialog was created
144if not d.isNone():
145
146 # Create a local variable for the fields of the dialog
147 fields = d.fields
148
149 # Build up the controls to display in the dialog
150 d.add_button(ipDialogButtonType.dbtOk)
151
152 types_tab = d.add_tab("Types")
153
154 fields.add_line("Simple Types")
155
156 check_box_field = fields.add_check_box(False, "Boolean")
157 check_box_field.value = True
158 check_box_field.use_callback = True
159
160 integer_field = fields.add_integer(5, "Integer")
161 integer_field.value = 2
162 integer_field.use_callback = True
163
164 real_field = fields.add_real(91.2, "Real")
165 real_field.value = 6.23
166 real_field.use_callback = True
167
168 text_field = fields.add_text("Simple text", "Text")
169 text_field.value = "Modified simple text"
170 text_field.case = ipDialogStringCase.dscAll
171 text_field.chars = ipDialogStringChars.dshAll
172
173 short_text_field = fields.add_text("AA123", "Short text")
174 short_text_field.max_length = 5
175 short_text_field.case = ipDialogStringCase.dscUpper
176 short_text_field.chars = ipDialogStringChars.dshAlphaNumeric
177 short_text_field.use_callback = True
178
179 text_box_field = fields.add_text_box("Advanced text" + "\r\n" + "New Line", "Text Box")
180 text_box_field.value = "Modified advanced text" + "\r\n" + "New Line"
181 text_box_field.use_callback = True
182
183 date_field = fields.add_date(datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0), "Date")
184 date_field.value = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
185 date_field.use_callback = True
186
187 time_field = fields.add_time(datetime.datetime.now(), "Time")
188 time_field.value = datetime.datetime.now()
189 time_field.use_callback = True
190
191 fields.add_line("Advanced Types")
192
193 distance_field = fields.add_distance(-200.0, "Distance", True)
194 distance_field.value = 100.0
195 distance_field.hint = "Enter a distance"
196 distance_field.use_callback = True
197
198 angle_field = fields.add_angle(45.0, "Angle" + "\r\n" + "(use 90 if possible)")
199 angle_field.value = 180.0
200 angle_field.use_callback = True
201
202 weight_field = fields.add_weight(9.2, "Weight")
203 weight_field.value = 64.5
204 weight_field.use_callback = True
205
206 area_field = fields.add_area(8.6, "Area")
207 area_field.value = 23.9
208 area_field.use_callback = True
209
210 volume_field = fields.add_volume(2.4, "Volume")
211 volume_field.value = 15.2
212 volume_field.use_callback = True
213
214 button_field = fields.add_button("Click Me!")
215
216 button_field.hint = "Click this button to show how a callback() is triggered"
217
218 # Adds a checkbox field to control the closing of the dialog
219 allow_close_field = fields.add_check_box(False, "Allow close on OK")
220 allow_close_field.value = True
221 allow_close_field.use_callback = True
222
223 lists_tab = d.add_tab("Lists")
224
225 fruits = ["Orange", "Apple", "Banana", "Lemon", "Pineapple", "Kiwi", "Strawberry", "Lime"]
226
227 fields.add_line("Select a single fruit from this list")
228
229 combo_box_field = fields.add_combo_box("Lemon", "Fruit Combo", fruits)
230
231 # Set combo_box_field = fields.add_combo_box(3, "Fruit Combo", fruits, False)
232 # combo_box_field.value = 4
233 combo_box_field.value = "Kiwi"
234 combo_box_field.use_callback = True
235
236 selection = [False, True, False, True, False, True, False, True]
237
238 fields.add_line("Select none or more fruits from this list box")
239
240 list_box_field = fields.add_list_box(fruits, selection, True, 5)
241 list_box_field.height = 5
242
243 fields.add_line("Select a single fruit from this group")
244
245 radio_group_field = fields.add_radio_group("Apple", "Fruit Group", fruits)
246
247 # Set radio_group_field = fields.add_radio_group(1, "Fruit Group", fruits)
248 # radio_group_field.value = 2
249 radio_group_field.value = "Banana"
250 radio_group_field.use_callback = True
251
252 fields.add_line("Select none or more fruits from this twin list")
253
254 twin_list_field = fields.add_twin_list("Left", "Right", fruits, selection, 6)
255 twin_list_field.height = 6
256
257 preview_tab = d.add_tab("Preview")
258
259 previews = ["Preview 1", "Preview 2"]
260
261 preview_group_field = fields.add_radio_group("Preview 1", "Preview Group", previews)
262 preview_group_field.use_callback = True
263
264 preview_field = fields.add_preview(preview_file1, "One up", True, ipDialogPreviewOrientation.dpoVertical)
265
266 picture_tab = d.add_tab("Picture")
267
268 pic1_opts = impact.gui.create_dialog_picture_options()
269
270 pic1_opts.width = 320
271 pic1_opts.height = 240
272
273 pic1_opts.command_panel_position = ipDialogPictureCommandsPosition.dpcpRightTop
274 pic1_opts.command_panel_always_visible = True
275
276 pic1_field = fields.add_picture(picture_file1, "Picture1", pic1_opts)
277
278 pic1_field.use_callback = True
279
280 load_pic1_button = fields.add_button("load Picture 1")
281 load_pic2_button = fields.add_button("load Picture 2")
282
283 # Display the type of each field in the output toolbox
284 for field in fields:
285 ot.add(describe_dialog_field_type(field.field_type))
286
287 # Show the dialog with a callback() handler
288 button_pressed = d.show_modal(win32com.server.util.wrap(_CallbackSink()))
289
290 if button_pressed == ipDialogButtonType.dbtOk:
291
292 # Display the values from the dialog
293 ot.add(check_box_field.label + ": " + str(check_box_field.value))
294 ot.add(integer_field.label + ": " + str(integer_field.value))
295 ot.add(real_field.label + ": " + str(real_field.value))
296 ot.add(text_field.label + ": " + str(text_field.value))
297 ot.add(text_box_field.label + ": " + str(text_box_field.value))
298 ot.add(date_field.label + ": " + str(date_field.value))
299 ot.add(time_field.label + ": " + str(time_field.value))
300
301 ot.add(distance_field.label + ": " + str(distance_field.value))
302 ot.add(angle_field.label + ": " + str(angle_field.value))
303 ot.add(weight_field.label + ": " + str(weight_field.value))
304 ot.add(area_field.label + ": " + str(area_field.value))
305 ot.add(volume_field.label + ": " + str(volume_field.value))
306
307 ot.add(radio_group_field.label + ": " + str(radio_group_field.value))
308 ot.add(radio_group_field.label + ": " + str(radio_group_field.selected_item))
309
310 ot.add(combo_box_field.label + ": " + str(combo_box_field.value))
311 ot.add(combo_box_field.label + ": " + str(combo_box_field.selected_item))
312
313 display_list_values("Listbox selected values:", list_box_field.selected_items)
314 display_list_values("Listbox selected indicies:", list_box_field.selected_indices)
315 display_list_values("Twinlist selected values:", twin_list_field.selected_items)
316 display_list_values("Twinlist selected indicies:", twin_list_field.selected_indices)
317
318 ot.add(pic1_field.label + ": " + str(pic1_field.picture_file_name))