@@ -39,7 +39,6 @@ namespace pdfpc {
39
39
* Controller handling all the triggered events/signals
40
40
*/
41
41
public class PresentationController : Object {
42
-
43
42
/**
44
43
* The currently displayed slide
45
44
*/
@@ -1369,6 +1368,70 @@ namespace pdfpc {
1369
1368
gdk_scale = view. scale_factor;
1370
1369
return (uint * ) ((Gdk . X11. Window ) view. get_window()). get_xid();
1371
1370
}
1371
+
1372
+ /**
1373
+ * Create a widget corresponding to the Poppler.Rectangle for the nth
1374
+ * controllable's main view, and return it. The widget is automatically
1375
+ * destroyed when the slide changes. Note that the widget might not
1376
+ * have been realized yet right after creation.
1377
+ */
1378
+ public Gtk .Widget overlay_widget (int n , Poppler .Rectangle area ) {
1379
+ Controllable c = (n < this . controllables. size) ? this . controllables. get (n) : null ;
1380
+ View . Pdf view = c. main_view;
1381
+ Gdk . Rectangle rect = view. convert_poppler_rectangle_to_gdk_rectangle(area);
1382
+
1383
+ var widget = new Gtk .EventBox ();
1384
+ widget. set_size_request(rect. width, rect. height);
1385
+ widget. add_events(Gdk . EventMask . BUTTON_PRESS_MASK | Gdk . EventMask . BUTTON_RELEASE_MASK | Gdk . EventMask . POINTER_MOTION_MASK );
1386
+
1387
+ // Find the fixed view that the view belongs to; this could be
1388
+ // improved by refactoring the API. Then add the widget to it.
1389
+ Gtk . Container parent = view. parent;
1390
+ while (parent != null && ! (parent is Gtk . Fixed )) {
1391
+ parent = parent. parent;
1392
+ }
1393
+ if (parent == null ) {
1394
+ printerr(" Warning: Unhandled case in presentation_controller.overlay_pos(): View is not contained in a Gtk.Fixed\n " );
1395
+ }
1396
+ else {
1397
+ var allocation = Gtk . Allocation ();
1398
+ view. get_allocation(out allocation);
1399
+ (parent as Gtk . Fixed ). put(widget, rect. x + allocation. x, rect. y + allocation. y);
1400
+
1401
+ // Pass events on to the underlying view
1402
+ widget. motion_notify_event. connect((event) = > {
1403
+ event. x + = allocation. x + rect. x;
1404
+ event. y + = allocation. y + rect. y;
1405
+ view. motion_notify_event(event);
1406
+ return true ;
1407
+ });
1408
+ widget. button_press_event. connect((event) = > {
1409
+ event. x + = allocation. x + rect. x;
1410
+ event. y + = allocation. y + rect. y;
1411
+ view. button_press_event(event);
1412
+ return true ;
1413
+ });
1414
+ widget. button_release_event. connect((event) = > {
1415
+ event. x + = allocation. x + rect. x;
1416
+ event. y + = allocation. y + rect. y;
1417
+ view. button_release_event(event);
1418
+ return true ;
1419
+ });
1420
+ }
1421
+
1422
+ // Set up automated removal of the widget
1423
+ ulong handler_id = 0 ;
1424
+ int slide_at_setup = this . current_slide_number;
1425
+ handler_id = this . update_request. connect(() = > {
1426
+ if (this . current_slide_number != slide_at_setup) {
1427
+ widget. destroy();
1428
+ this . disconnect(handler_id);
1429
+ }
1430
+ });
1431
+
1432
+ widget. show();
1433
+ return widget;
1434
+ }
1372
1435
#endif
1373
1436
}
1374
1437
}
0 commit comments