|
@@ -17,7 +17,7 @@ def comms_error_dialog(parent, e):
|
17
|
17
|
dialog.destroy()
|
18
|
18
|
|
19
|
19
|
|
20
|
|
-class ListRowModel(GObject.GObject):
|
|
20
|
+class SelectListRowModel(GObject.GObject):
|
21
|
21
|
|
22
|
22
|
def __init__(self, serport):
|
23
|
23
|
GObject.GObject.__init__(self)
|
|
@@ -49,7 +49,7 @@ class SelectListStore(Gio.ListStore):
|
49
|
49
|
# Add any new ports
|
50
|
50
|
for port in serports:
|
51
|
51
|
if port is not None:
|
52
|
|
- self.append(ListRowModel(port))
|
|
52
|
+ self.append(SelectListRowModel(port))
|
53
|
53
|
|
54
|
54
|
|
55
|
55
|
def list_box_update_header_func(row, before, data):
|
|
@@ -114,7 +114,6 @@ class SelectListRow(Gtk.ListBoxRow):
|
114
|
114
|
|
115
|
115
|
def __init__(self, model):
|
116
|
116
|
Gtk.EventBox.__init__(self)
|
117
|
|
-
|
118
|
117
|
self.model = model
|
119
|
118
|
|
120
|
119
|
self._builder = Gtk.Builder()
|
|
@@ -142,6 +141,97 @@ class SelectListRow(Gtk.ListBoxRow):
|
142
|
141
|
return
|
143
|
142
|
|
144
|
143
|
|
|
144
|
+class PDOListRowModel(GObject.GObject):
|
|
145
|
+
|
|
146
|
+ def __init__(self, pdo):
|
|
147
|
+ GObject.GObject.__init__(self)
|
|
148
|
+ self.pdo = pdo
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+class PDOListStore(Gio.ListStore):
|
|
152
|
+
|
|
153
|
+ def update_items(self, pdo_list):
|
|
154
|
+ # Clear the list
|
|
155
|
+ self.remove_all()
|
|
156
|
+
|
|
157
|
+ # Add everything from the new list
|
|
158
|
+ for pdo in pdo_list:
|
|
159
|
+ self.append(PDOListRowModel(pdo))
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+class PDOListRow(Gtk.ListBoxRow):
|
|
163
|
+ oc_tooltips = [
|
|
164
|
+ "I<sub>Peak</sub> = I<sub>OC</sub> (default)",
|
|
165
|
+ """Overload Capabilities:
|
|
166
|
+1. I<sub>Peak</sub> = 150% I<sub>OC</sub> for 1 ms @ 5% duty cycle (I<sub>Low</sub> = 97% I<sub>OC</sub> for 19 ms)
|
|
167
|
+2. I<sub>Peak</sub> = 125% I<sub>OC</sub> for 2 ms @ 10% duty cycle (I<sub>Low</sub> = 97% I<sub>OC</sub> for 18 ms)
|
|
168
|
+3. I<sub>Peak</sub> = 110% I<sub>OC</sub> for 10 ms @ 50% duty cycle (I<sub>Low</sub> = 90% I<sub>OC</sub> for 10 ms)""",
|
|
169
|
+ """Overload Capabilities:
|
|
170
|
+1. I<sub>Peak</sub> = 200% I<sub>OC</sub> for 1 ms @ 5% duty cycle (I<sub>Low</sub> = 95% I<sub>OC</sub> for 19 ms)
|
|
171
|
+2. I<sub>Peak</sub> = 150% I<sub>OC</sub> for 2 ms @ 10% duty cycle (I<sub>Low</sub> = 94% I<sub>OC</sub> for 18 ms)
|
|
172
|
+3. I<sub>Peak</sub> = 125% I<sub>OC</sub> for 10 ms @ 50% duty cycle (I<sub>Low</sub> = 75% I<sub>OC</sub> for 10 ms)""",
|
|
173
|
+ """Overload Capabilities:
|
|
174
|
+1. I<sub>Peak</sub> = 200% I<sub>OC</sub> for 1 ms @ 5% duty cycle (I<sub>Low</sub> = 95% I<sub>OC</sub> for 19 ms)
|
|
175
|
+2. I<sub>Peak</sub> = 175% I<sub>OC</sub> for 2 ms @ 10% duty cycle (I<sub>Low</sub> = 92% I<sub>OC</sub> for 18 ms)
|
|
176
|
+3. I<sub>Peak</sub> = 150% I<sub>OC</sub> for 10 ms @ 50% duty cycle (I<sub>Low</sub> = 50% I<sub>OC</sub> for 10 ms)"""
|
|
177
|
+ ]
|
|
178
|
+
|
|
179
|
+ def __init__(self, model):
|
|
180
|
+ Gtk.ListBoxRow.__init__(self)
|
|
181
|
+ self.model = model
|
|
182
|
+
|
|
183
|
+ self.set_activatable(False)
|
|
184
|
+ self.set_selectable(False)
|
|
185
|
+ self.set_can_focus(False)
|
|
186
|
+
|
|
187
|
+ # Make the widgets and populate them with info from the model
|
|
188
|
+ # Main box
|
|
189
|
+ box = Gtk.Box(Gtk.Orientation.HORIZONTAL, 12)
|
|
190
|
+ box.set_homogeneous(True)
|
|
191
|
+ box.set_margin_left(12)
|
|
192
|
+ box.set_margin_right(12)
|
|
193
|
+ box.set_margin_top(6)
|
|
194
|
+ box.set_margin_bottom(6)
|
|
195
|
+
|
|
196
|
+ # Type label
|
|
197
|
+ type_label = Gtk.Label(model.pdo.pdo_type.capitalize())
|
|
198
|
+ type_label.set_halign(Gtk.Align.START)
|
|
199
|
+ box.pack_start(type_label, True, True, 0)
|
|
200
|
+
|
|
201
|
+ # Voltage label
|
|
202
|
+ if model.pdo.pdo_type != "unknown":
|
|
203
|
+ voltage_label = Gtk.Label("{:g} V".format(model.pdo.v / 1000.0))
|
|
204
|
+ voltage_label.set_halign(Gtk.Align.END)
|
|
205
|
+ box.pack_start(voltage_label, True, True, 0)
|
|
206
|
+
|
|
207
|
+ # Right box
|
|
208
|
+ right_box = Gtk.Box(Gtk.Orientation.HORIZONTAL, 6)
|
|
209
|
+ right_box.set_halign(Gtk.Align.END)
|
|
210
|
+ if model.pdo.pdo_type != "unknown":
|
|
211
|
+ # Current label
|
|
212
|
+ current_label = Gtk.Label("{:g} A".format(model.pdo.i / 1000.0))
|
|
213
|
+ current_label.set_halign(Gtk.Align.END)
|
|
214
|
+ right_box.pack_end(current_label, True, False, 0)
|
|
215
|
+
|
|
216
|
+ # Over-current image(?)
|
|
217
|
+ if model.pdo.peak_i > 0:
|
|
218
|
+ oc_image = Gtk.Image.new_from_icon_name(
|
|
219
|
+ "dialog-information-symbolic", Gtk.IconSize.BUTTON)
|
|
220
|
+ oc_image.set_tooltip_markup(
|
|
221
|
+ PDOListRow.oc_tooltips[model.pdo.peak_i])
|
|
222
|
+ right_box.pack_end(oc_image, True, False, 0)
|
|
223
|
+ else:
|
|
224
|
+ # PDO value
|
|
225
|
+ text_label = Gtk.Label()
|
|
226
|
+ text_label.set_markup("<tt>{}</tt>".format(model.pdo))
|
|
227
|
+ right_box.pack_end(text_label, True, False, 0)
|
|
228
|
+
|
|
229
|
+ box.pack_end(right_box, True, True, 0)
|
|
230
|
+
|
|
231
|
+ self.add(box)
|
|
232
|
+ self.show_all()
|
|
233
|
+
|
|
234
|
+
|
145
|
235
|
class Handler:
|
146
|
236
|
|
147
|
237
|
def __init__(self, builder):
|
|
@@ -339,26 +429,56 @@ class Handler:
|
339
|
429
|
if row != sc_row:
|
340
|
430
|
# If it's not the source-cap-row, leave
|
341
|
431
|
return
|
|
432
|
+
|
342
|
433
|
# Get the source capabilities
|
343
|
434
|
with pdbuddy.Sink(self.serial_port) as pdbs:
|
344
|
435
|
caps = pdbs.get_source_cap()
|
345
|
|
- s = ""
|
346
|
|
- for i, cap in enumerate(caps):
|
347
|
|
- s += "PDO {}: {}".format(i+1, cap)
|
348
|
|
- if i < len(caps) - 1:
|
349
|
|
- s += "\n"
|
350
|
|
- if not s:
|
351
|
|
- s = "No Source_Capabilities"
|
352
|
|
- flags = Gtk.DialogFlags.DESTROY_WITH_PARENT;
|
353
|
|
- window = self.builder.get_object("pdb-window")
|
354
|
|
- dialog = Gtk.MessageDialog(window,
|
355
|
|
- flags,
|
356
|
|
- Gtk.MessageType.INFO,
|
357
|
|
- Gtk.ButtonsType.CLOSE,
|
358
|
|
- None)
|
359
|
|
- dialog.set_markup("<span font_family='monospace'>{}</span>".format(s))
|
360
|
|
- dialog.run()
|
361
|
|
- dialog.destroy()
|
|
436
|
+
|
|
437
|
+ # Create the dialog
|
|
438
|
+ window = self.builder.get_object("pdb-window")
|
|
439
|
+ dialog_builder = Gtk.Builder.new_from_file("data/src-cap-dialog.ui")
|
|
440
|
+ dialog = dialog_builder.get_object("src-cap-dialog")
|
|
441
|
+ dialog.set_transient_for(window)
|
|
442
|
+
|
|
443
|
+ # Populate PD Power
|
|
444
|
+ d_power = dialog_builder.get_object("power-label")
|
|
445
|
+ d_power.set_text("{:g} W".format(pdbuddy.calculate_pdp(caps)))
|
|
446
|
+ # Warning icon
|
|
447
|
+ cap_warning = dialog_builder.get_object("source-cap-warning")
|
|
448
|
+ cap_warning.set_visible(not pdbuddy.follows_power_rules(caps))
|
|
449
|
+
|
|
450
|
+ # Populate Information
|
|
451
|
+ d_info_header = dialog_builder.get_object("info-header")
|
|
452
|
+ d_info = dialog_builder.get_object("info-label")
|
|
453
|
+ # Make the string to display
|
|
454
|
+ info_str = ""
|
|
455
|
+ if caps[0].dual_role_pwr:
|
|
456
|
+ info_str += "Dual-Role Power\n"
|
|
457
|
+ if caps[0].usb_suspend:
|
|
458
|
+ info_str += "USB Suspend Supported\n"
|
|
459
|
+ if caps[0].unconstrained_pwr:
|
|
460
|
+ info_str += "Unconstrained Power\n"
|
|
461
|
+ if caps[0].usb_comms:
|
|
462
|
+ info_str += "USB Communications Capable\n"
|
|
463
|
+ if caps[0].dual_role_data:
|
|
464
|
+ info_str += "Dual-Role Data\n"
|
|
465
|
+ info_str = info_str[:-1]
|
|
466
|
+ # Set the text and label visibility
|
|
467
|
+ d_info.set_text(info_str)
|
|
468
|
+ d_info_header.set_visible(info_str)
|
|
469
|
+ d_info.set_visible(info_str)
|
|
470
|
+
|
|
471
|
+ # PDO list
|
|
472
|
+ d_list = dialog_builder.get_object("src-cap-list")
|
|
473
|
+ d_list.set_header_func(list_box_update_header_func, None)
|
|
474
|
+
|
|
475
|
+ model = PDOListStore()
|
|
476
|
+ d_list.bind_model(model, PDOListRow)
|
|
477
|
+ model.update_items(caps)
|
|
478
|
+
|
|
479
|
+ # Show the dialog
|
|
480
|
+ dialog.run()
|
|
481
|
+ dialog.destroy()
|
362
|
482
|
|
363
|
483
|
|
364
|
484
|
class Application(Gtk.Application):
|
|
@@ -371,8 +491,7 @@ class Application(Gtk.Application):
|
371
|
491
|
def do_startup(self):
|
372
|
492
|
Gtk.Application.do_startup(self)
|
373
|
493
|
|
374
|
|
- self.builder = Gtk.Builder()
|
375
|
|
- self.builder.add_from_file("data/pd-buddy-gtk.ui")
|
|
494
|
+ self.builder = Gtk.Builder.new_from_file("data/pd-buddy-gtk.ui")
|
376
|
495
|
self.builder.connect_signals(Handler(self.builder))
|
377
|
496
|
|
378
|
497
|
def do_activate(self):
|