@@ -159,12 +159,14 @@ def __init__(self, figure):
159
159
160
160
self ._idle_draw_id = 0
161
161
self ._lastCursor = None
162
+ self ._rubberband_rect = None
162
163
163
164
self .connect ('scroll_event' , self .scroll_event )
164
165
self .connect ('button_press_event' , self .button_press_event )
165
166
self .connect ('button_release_event' , self .button_release_event )
166
167
self .connect ('configure_event' , self .configure_event )
167
168
self .connect ('draw' , self .on_draw_event )
169
+ self .connect ('draw' , self ._post_draw )
168
170
self .connect ('key_press_event' , self .key_press_event )
169
171
self .connect ('key_release_event' , self .key_release_event )
170
172
self .connect ('motion_notify_event' , self .motion_notify_event )
@@ -286,6 +288,40 @@ def configure_event(self, widget, event):
286
288
self .figure .set_size_inches (w / dpi , h / dpi , forward = False )
287
289
return False # finish event propagation?
288
290
291
+ def _draw_rubberband (self , rect ):
292
+ self ._rubberband_rect = rect
293
+ # TODO: Only update the rubberband area.
294
+ self .queue_draw ()
295
+
296
+ def _post_draw (self , widget , ctx ):
297
+ if self ._rubberband_rect is None :
298
+ return
299
+
300
+ x0 , y0 , w , h = self ._rubberband_rect
301
+ x1 = x0 + w
302
+ y1 = y0 + h
303
+
304
+ # Draw the lines from x0, y0 towards x1, y1 so that the
305
+ # dashes don't "jump" when moving the zoom box.
306
+ ctx .move_to (x0 , y0 )
307
+ ctx .line_to (x0 , y1 )
308
+ ctx .move_to (x0 , y0 )
309
+ ctx .line_to (x1 , y0 )
310
+ ctx .move_to (x0 , y1 )
311
+ ctx .line_to (x1 , y1 )
312
+ ctx .move_to (x1 , y0 )
313
+ ctx .line_to (x1 , y1 )
314
+
315
+ ctx .set_antialias (1 )
316
+ ctx .set_line_width (1 )
317
+ ctx .set_dash ((3 , 3 ), 0 )
318
+ ctx .set_source_rgb (0 , 0 , 0 )
319
+ ctx .stroke_preserve ()
320
+
321
+ ctx .set_dash ((3 , 3 ), 3 )
322
+ ctx .set_source_rgb (1 , 1 , 1 )
323
+ ctx .stroke ()
324
+
289
325
def on_draw_event (self , widget , ctx ):
290
326
# to be overwritten by GTK3Agg or GTK3Cairo
291
327
pass
@@ -507,26 +543,14 @@ def set_cursor(self, cursor):
507
543
Gtk .main_iteration ()
508
544
509
545
def draw_rubberband (self , event , x0 , y0 , x1 , y1 ):
510
- # adapted from
511
- # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/189744
512
- ctx = self .canvas .get_property ("window" ).cairo_create ()
513
-
514
- # todo: instead of redrawing the entire figure, copy the part of
515
- # the figure that was covered by the previous rubberband rectangle
516
- self .canvas .draw ()
517
-
518
546
height = self .canvas .figure .bbox .height
519
547
y1 = height - y1
520
548
y0 = height - y0
521
- w = abs (x1 - x0 )
522
- h = abs (y1 - y0 )
523
- rect = [int (val ) for val in (min (x0 , x1 ), min (y0 , y1 ), w , h )]
549
+ rect = [int (val ) for val in (x0 , y0 , x1 - x0 , y1 - y0 )]
550
+ self .canvas ._draw_rubberband (rect )
524
551
525
- ctx .new_path ()
526
- ctx .set_line_width (0.5 )
527
- ctx .rectangle (rect [0 ], rect [1 ], rect [2 ], rect [3 ])
528
- ctx .set_source_rgb (0 , 0 , 0 )
529
- ctx .stroke ()
552
+ def remove_rubberband (self ):
553
+ self .canvas ._draw_rubberband (None )
530
554
531
555
def _update_buttons_checked (self ):
532
556
for name , active in [("Pan" , "PAN" ), ("Zoom" , "ZOOM" )]:
@@ -721,6 +745,10 @@ def draw_rubberband(self, x0, y0, x1, y1):
721
745
NavigationToolbar2GTK3 .draw_rubberband (
722
746
self ._make_classic_style_pseudo_toolbar (), None , x0 , y0 , x1 , y1 )
723
747
748
+ def remove_rubberband (self ):
749
+ NavigationToolbar2GTK3 .remove_rubberband (
750
+ self ._make_classic_style_pseudo_toolbar ())
751
+
724
752
725
753
class SaveFigureGTK3 (backend_tools .SaveFigureBase ):
726
754
def trigger (self , * args , ** kwargs ):
0 commit comments