# HG changeset patch # User Thinker K.F. Li # Date 1294221374 -28800 # Node ID e55499f7505a59e2baec2259ac6ac9d0fe3805b6 # Parent 86428aa657abdd8d637d8f92fabb32147d0b9fd1 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. diff -r 86428aa657ab -r e55499f7505a pyink/MBScene.py --- a/pyink/MBScene.py Tue Jan 04 13:06:56 2011 +0800 +++ b/pyink/MBScene.py Wed Jan 05 17:56:14 2011 +0800 @@ -448,16 +448,16 @@ # This is here to monitor changes of scene node. def chg_scene_node(self, scene_node, start=None, end=None, tween_type=None, ref=None): - if start: + if start is not None: scene_node.setAttribute('start', str(start)) pass - if end: + if end is not None: scene_node.setAttribute('end', str(end)) pass - if tween_type: + if tween_type is not None: scene_node.setAttribute('type', tween_type) pass - if ref: + if ref is not None: scene_node.setAttribute('ref', ref) pass pass @@ -537,18 +537,33 @@ def __init__(self, *args, **kws): super(MBScene_framelines, self).__init__(*args, **kws) + + self._last_mouse_over_frameline = None + self._last_active_frameline = None pass - def _remove_active_frame(self,widget,event): + def _change_hover_frameline(self, widget, event): """ Hide all hover frames. This is a hack. We should use the lost focus event instead in the future to reduce the overhead. """ - for f in self._framelines: - if f != widget: - f.hide_hover() - pass + if self._last_mouse_over_frameline and \ + widget != self._last_mouse_over_frameline: + self._last_mouse_over_frameline.mouse_leave() pass + self._last_mouse_over_frameline = widget + pass + + ## \brief Called for changing of active frame. + # + # This handle deactive previous frameline that owns an active frame when a + # frame in another frameline is activated. + def _change_active_frame(self, widget, frame, button): + if self._last_active_frameline and \ + self._last_active_frameline != widget: + self._last_active_frameline.deactive() + pass + self._last_active_frameline = widget pass ## \brief Add a frameline into the frameline box for the given layer. @@ -578,7 +593,8 @@ line.label = label line.layer_idx = layer_idx line.connect(line.FRAME_BUT_PRESS, self.onCellClick) - line.connect('motion-notify-event', self._remove_active_frame) + line.connect('motion-notify-event', self._change_hover_frameline) + line.connect(frameline.FRAME_BUT_PRESS, self._change_active_frame) pass ## \brief Remove the given frameline from the frameline box. diff -r 86428aa657ab -r e55499f7505a pyink/frameline.py --- a/pyink/frameline.py Tue Jan 04 13:06:56 2011 +0800 +++ b/pyink/frameline.py Wed Jan 05 17:56:14 2011 +0800 @@ -223,12 +223,12 @@ gc = self._gc gc.set_rgb_fg_color(color) - line_x1 = idx * self._frame_width - line_x2 = line_x1 + self._frame_width + line_x1 = idx * self._frame_width + 1 + line_x2 = line_x1 + self._frame_width - 2 - win.draw_line(gc, line_x1, 0, line_x1, w_h) - win.draw_line(gc, line_x2, 0, line_x2, w_h) - win.draw_line(gc, line_x1, w_h - 1, line_x2, w_h - 1) + win.draw_line(gc, line_x1, 0, line_x1, w_h - 2) + win.draw_line(gc, line_x2, 0, line_x2, w_h - 2) + win.draw_line(gc, line_x1, w_h - 2, line_x2, w_h - 2) win.draw_line(gc, line_x1, 0, line_x2, 0) pass @@ -261,13 +261,13 @@ color = gtk.gdk.Color(*color_rgb) gc.set_rgb_fg_color(color) - line_x1 = frame_idx * self._frame_width + 1 - line_x2 = line_x1 + self._frame_width - 2 + line_x1 = frame_idx * self._frame_width + 2 + line_x2 = line_x1 + self._frame_width - 4 - win.draw_line(gc, line_x1, 1, line_x1, w_h - 2) - win.draw_line(gc, line_x2, 1, line_x2, w_h - 2) + win.draw_line(gc, line_x1, 1, line_x1, w_h - 3) + win.draw_line(gc, line_x2, 1, line_x2, w_h - 3) win.draw_line(gc, line_x1, 1, line_x2, 1) - win.draw_line(gc, line_x1, w_h - 2, line_x2, w_h - 2) + win.draw_line(gc, line_x1, w_h - 3, line_x2, w_h - 3) pass pass @@ -295,6 +295,7 @@ self._keys = [] self._active_frame = -1 self._drawing = False + self._last_hover = -1 # frame index of last hover pass def _draw_keyframe(self, frame_idx): @@ -427,9 +428,25 @@ def _draw_hover_frame(self, frame_idx): if not self._drawing: return - self._draw_hover(frame_idx) - pass - + + if self._last_hover != -1: + self._draw_frame(self._last_hover) + if self._last_hover == self._active_frame: + self._draw_active_frame() + pass + pass + + if frame_idx < self._num_frames and frame_idx >= 0: + self._draw_hover(frame_idx) + if self._last_hover == self._active_frame: + self._draw_active_frame() + pass + self._last_hover = frame_idx + else: + self._last_hover = -1 + pass + pass + ## \brief Start future drawing actions # def start_drawing(self): @@ -492,8 +509,8 @@ self.connect('button-press-event', self._press_hdl) self.connect('expose-event', self._fl_expose) - self.connect('motion-notify-event', self._motion_hdl) - self._last_hover = -1 # frame index of last hover + self.connect('motion-notify-event', self._motion_n_leave_hdl) + self.connect('leave-notify-event', self._motion_n_leave_hdl) pass def __len__(self): @@ -566,32 +583,16 @@ self.emit(frameline.FRAME_BUT_PRESS, frame, but) pass - def hide_hover(self): - if self._active_frame != self._last_hover: - self._draw_normal_frame(self._last_hover) + def _motion_n_leave_hdl(self, widget, event): + if event.type == gtk.gdk.LEAVE_NOTIFY: + frame_idx = -1 + else: + frame_idx = int(event.x / self._frame_width) pass + + self._draw_hover_frame(frame_idx) pass - def _motion_hdl(self, widget, event): - frame_idx = int(event.x / self._frame_width) - if self._last_hover != -1: - self._draw_frame(self._last_hover) - if self._last_hover == self._active_frame: - self._draw_active_frame() - pass - pass - - if frame_idx < self._num_frames and frame_idx >= 0: - self._draw_hover_frame(frame_idx) - if self._last_hover == self._active_frame: - self._draw_active_frame() - pass - self._last_hover = frame_idx - else: - self._last_hover = -1 - pass - pass - def _fl_expose(self, widget, event): win = self.window self.start_drawing() @@ -870,6 +871,15 @@ self._active_frame = -1 self._draw_all_frames() pass + + ## \brief Called when mouse leave the widget. + # + # This is here for buggy pygtk. It does not send leave-notify-event. We + # need this to workaround. + # + def mouse_leave(self): + self._draw_hover_frame(-1) + pass pass if __name__ == '__main__':