comparison pyink/frameline.py @ 1214:e55499f7505a

Fix the issues with multiple framelines - For multiple framelines, user move mouse from one frameline to another, the frame is not showed correctly. - Old implementation always draw normal frame on the frameline where mouse just leaving. - It is fixed by detecting leave-notify event and removing hover mark. - When user active a frame on a frameline that is not what old active frame is at, the old active frame is not deactivated. - It is fixed by calling frameline.deactive() of a frameline when a frame is activated on another frameline.
author Thinker K.F. Li <thinker@codemud.net>
date Wed, 05 Jan 2011 17:56:14 +0800
parents 1d476b35dc79
children 8e372ae69010
comparison
equal deleted inserted replaced
1213:86428aa657ab 1214:e55499f7505a
221 color = gtk.gdk.Color(*color_rgb) 221 color = gtk.gdk.Color(*color_rgb)
222 222
223 gc = self._gc 223 gc = self._gc
224 gc.set_rgb_fg_color(color) 224 gc.set_rgb_fg_color(color)
225 225
226 line_x1 = idx * self._frame_width 226 line_x1 = idx * self._frame_width + 1
227 line_x2 = line_x1 + self._frame_width 227 line_x2 = line_x1 + self._frame_width - 2
228 228
229 win.draw_line(gc, line_x1, 0, line_x1, w_h) 229 win.draw_line(gc, line_x1, 0, line_x1, w_h - 2)
230 win.draw_line(gc, line_x2, 0, line_x2, w_h) 230 win.draw_line(gc, line_x2, 0, line_x2, w_h - 2)
231 win.draw_line(gc, line_x1, w_h - 1, line_x2, w_h - 1) 231 win.draw_line(gc, line_x1, w_h - 2, line_x2, w_h - 2)
232 win.draw_line(gc, line_x1, 0, line_x2, 0) 232 win.draw_line(gc, line_x1, 0, line_x2, 0)
233 pass 233 pass
234 234
235 def _draw_keyframe_(self, frame_idx): 235 def _draw_keyframe_(self, frame_idx):
236 win = self.window 236 win = self.window
259 259
260 color_rgb = color_to_rgb(self._hover_border_color) 260 color_rgb = color_to_rgb(self._hover_border_color)
261 color = gtk.gdk.Color(*color_rgb) 261 color = gtk.gdk.Color(*color_rgb)
262 gc.set_rgb_fg_color(color) 262 gc.set_rgb_fg_color(color)
263 263
264 line_x1 = frame_idx * self._frame_width + 1 264 line_x1 = frame_idx * self._frame_width + 2
265 line_x2 = line_x1 + self._frame_width - 2 265 line_x2 = line_x1 + self._frame_width - 4
266 266
267 win.draw_line(gc, line_x1, 1, line_x1, w_h - 2) 267 win.draw_line(gc, line_x1, 1, line_x1, w_h - 3)
268 win.draw_line(gc, line_x2, 1, line_x2, w_h - 2) 268 win.draw_line(gc, line_x2, 1, line_x2, w_h - 3)
269 win.draw_line(gc, line_x1, 1, line_x2, 1) 269 win.draw_line(gc, line_x1, 1, line_x2, 1)
270 win.draw_line(gc, line_x1, w_h - 2, line_x2, w_h - 2) 270 win.draw_line(gc, line_x1, w_h - 3, line_x2, w_h - 3)
271 pass 271 pass
272 pass 272 pass
273 273
274 274
275 ## \brief Drawing frameline according state of a frameline. 275 ## \brief Drawing frameline according state of a frameline.
293 293
294 self._num_frames = num_frames 294 self._num_frames = num_frames
295 self._keys = [] 295 self._keys = []
296 self._active_frame = -1 296 self._active_frame = -1
297 self._drawing = False 297 self._drawing = False
298 self._last_hover = -1 # frame index of last hover
298 pass 299 pass
299 300
300 def _draw_keyframe(self, frame_idx): 301 def _draw_keyframe(self, frame_idx):
301 # Only keyframes that is not right-side of NONE type tween should be 302 # Only keyframes that is not right-side of NONE type tween should be
302 # draw. 303 # draw.
425 pass 426 pass
426 427
427 def _draw_hover_frame(self, frame_idx): 428 def _draw_hover_frame(self, frame_idx):
428 if not self._drawing: 429 if not self._drawing:
429 return 430 return
430 self._draw_hover(frame_idx) 431
431 pass 432 if self._last_hover != -1:
432 433 self._draw_frame(self._last_hover)
434 if self._last_hover == self._active_frame:
435 self._draw_active_frame()
436 pass
437 pass
438
439 if frame_idx < self._num_frames and frame_idx >= 0:
440 self._draw_hover(frame_idx)
441 if self._last_hover == self._active_frame:
442 self._draw_active_frame()
443 pass
444 self._last_hover = frame_idx
445 else:
446 self._last_hover = -1
447 pass
448 pass
449
433 ## \brief Start future drawing actions 450 ## \brief Start future drawing actions
434 # 451 #
435 def start_drawing(self): 452 def start_drawing(self):
436 if not hasattr(self, '_gc'): 453 if not hasattr(self, '_gc'):
437 win = self.window 454 win = self.window
490 def __init__(self, num_frames=20): 507 def __init__(self, num_frames=20):
491 frameline_draw_state.__init__(self, num_frames) 508 frameline_draw_state.__init__(self, num_frames)
492 509
493 self.connect('button-press-event', self._press_hdl) 510 self.connect('button-press-event', self._press_hdl)
494 self.connect('expose-event', self._fl_expose) 511 self.connect('expose-event', self._fl_expose)
495 self.connect('motion-notify-event', self._motion_hdl) 512 self.connect('motion-notify-event', self._motion_n_leave_hdl)
496 self._last_hover = -1 # frame index of last hover 513 self.connect('leave-notify-event', self._motion_n_leave_hdl)
497 pass 514 pass
498 515
499 def __len__(self): 516 def __len__(self):
500 return self._num_frames 517 return self._num_frames
501 518
564 frame = event.x / self._frame_width 581 frame = event.x / self._frame_width
565 but = event.button 582 but = event.button
566 self.emit(frameline.FRAME_BUT_PRESS, frame, but) 583 self.emit(frameline.FRAME_BUT_PRESS, frame, but)
567 pass 584 pass
568 585
569 def hide_hover(self): 586 def _motion_n_leave_hdl(self, widget, event):
570 if self._active_frame != self._last_hover: 587 if event.type == gtk.gdk.LEAVE_NOTIFY:
571 self._draw_normal_frame(self._last_hover) 588 frame_idx = -1
572 pass 589 else:
590 frame_idx = int(event.x / self._frame_width)
591 pass
592
593 self._draw_hover_frame(frame_idx)
573 pass 594 pass
574 595
575 def _motion_hdl(self, widget, event):
576 frame_idx = int(event.x / self._frame_width)
577 if self._last_hover != -1:
578 self._draw_frame(self._last_hover)
579 if self._last_hover == self._active_frame:
580 self._draw_active_frame()
581 pass
582 pass
583
584 if frame_idx < self._num_frames and frame_idx >= 0:
585 self._draw_hover_frame(frame_idx)
586 if self._last_hover == self._active_frame:
587 self._draw_active_frame()
588 pass
589 self._last_hover = frame_idx
590 else:
591 self._last_hover = -1
592 pass
593 pass
594
595 def _fl_expose(self, widget, event): 596 def _fl_expose(self, widget, event):
596 win = self.window 597 win = self.window
597 self.start_drawing() 598 self.start_drawing()
598 self.update() 599 self.update()
599 pass 600 pass
868 def reset(self): 869 def reset(self):
869 self._keys = [] 870 self._keys = []
870 self._active_frame = -1 871 self._active_frame = -1
871 self._draw_all_frames() 872 self._draw_all_frames()
872 pass 873 pass
874
875 ## \brief Called when mouse leave the widget.
876 #
877 # This is here for buggy pygtk. It does not send leave-notify-event. We
878 # need this to workaround.
879 #
880 def mouse_leave(self):
881 self._draw_hover_frame(-1)
882 pass
873 pass 883 pass
874 884
875 if __name__ == '__main__': 885 if __name__ == '__main__':
876 window = gtk.Window(gtk.WINDOW_TOPLEVEL) 886 window = gtk.Window(gtk.WINDOW_TOPLEVEL)
877 fr = frameruler(40) 887 fr = frameruler(40)