From: Aiwota Programmer Date: Tue, 11 Dec 2007 15:11:31 +0000 (+0900) Subject: change the mouse cursor according to text area, uri area and non text area. X-Git-Url: http://git.sourceforge.jp/view?p=fukui-no-namari%2Ffukui-no-namari.git;a=commitdiff_plain;h=d4cd260e46f7b191fd6e5a8c899da9d9d23bd492 change the mouse cursor according to text area, uri area and non text area. --- diff --git a/src/FukuiNoNamari/thread_view.py b/src/FukuiNoNamari/thread_view.py index 120bd64..78a14da 100644 --- a/src/FukuiNoNamari/thread_view.py +++ b/src/FukuiNoNamari/thread_view.py @@ -22,6 +22,9 @@ import pango class ThreadView(gtk.HBox): + hand_cursor = gtk.gdk.Cursor(gtk.gdk.HAND2) + regular_cursor = gtk.gdk.Cursor(gtk.gdk.XTERM) + arrow_cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR) def __init__(self): gtk.HBox.__init__(self, False, 0) @@ -31,7 +34,9 @@ class ThreadView(gtk.HBox): self.pack_start(self.vscrollbar, expand=False) self.adjustment = self.vscrollbar.get_adjustment() - self.drawingarea.add_events(gtk.gdk.SCROLL_MASK) + self.drawingarea.add_events( + gtk.gdk.SCROLL_MASK | + gtk.gdk.POINTER_MOTION_MASK) self.adjustment.step_increment = 20 self.drawingarea_prev_width = 0 @@ -44,6 +49,8 @@ class ThreadView(gtk.HBox): "button-press-event", self.on_drawingarea_button_press_event) self.drawingarea.connect( "scroll-event", self.on_drawingarea_scroll_event) + self.drawingarea.connect( + "motion-notify-event", self.on_drawingrarea_motion_notify_event) self.vscrollbar.connect( "value-changed", self.on_vscrollbar_value_changed) @@ -131,6 +138,56 @@ class ThreadView(gtk.HBox): self.drawingarea.window.draw_layout( gc, layout.marginleft, layout.posY - int(view_y), layout) + def transform_coordinate_gdk_to_adj(self, y): + return y + self.adjustment.value + + def transform_coordinate_adj_to_layout(self, x, y, layout): + return x - layout.marginleft, y - layout.posY + + def transform_coordinate_gdk_to_layout(self, x, y, layout): + return self.transform_coordinate_adj_to_layout( + x, self.transform_coordinate_gdk_to_adj(y), layout) + + def ptrpos_to_layout(self, x, y): + # transform coordinate, GdkWindow -> adjustment + adj_x = x + adj_y = self.transform_coordinate_gdk_to_adj(y) + for lay in self.pangolayout: + width, height = lay.get_pixel_size() + if (adj_y >= lay.posY and adj_y < lay.posY + height and + adj_x >= lay.marginleft): + return lay + return None + + def ptrpos_to_uri(self, x, y): + # x, y is GdkWindow coordinate + + layout = self.ptrpos_to_layout(x, y) + + if layout is None: + return None, None, None + + # transform coordinate, GdkWindow -> pangolayout + lay_x, lay_y = self.transform_coordinate_gdk_to_layout(x, y, layout) + + # xy -> index + idx, clk = layout.xy_to_index( + int(lay_x)*pango.SCALE, int(lay_y)*pango.SCALE) + + x, y, width, height = layout.index_to_pos(idx) + x /= pango.SCALE + y /= pango.SCALE + width /= pango.SCALE + height /= pango.SCALE + if (lay_x >= x and lay_x < x + width and + lay_y >= y and lay_y < y + height): + + for i, (start, end, href) in enumerate(layout.urilist): + if idx >= start and idx < end: + return href, layout, i + + return None, layout, None + def on_drawingarea_expose_event(self, widget, event, data=None): self.draw_viewport() @@ -170,3 +227,15 @@ class ThreadView(gtk.HBox): if self.adjustment.value > max_value: self.adjustment.value = max_value self.prevent_adjustment_overflow() + + def on_drawingrarea_motion_notify_event(self, widget, event, data=None): + cursor = ThreadView.regular_cursor + + uri, layout, index = self.ptrpos_to_uri(event.x, event.y) + if layout is None: + cursor = ThreadView.arrow_cursor + else: + if uri is not None and uri != "": + cursor = ThreadView.hand_cursor + + self.drawingarea.window.set_cursor(cursor) diff --git a/src/FukuiNoNamari/thread_window.py b/src/FukuiNoNamari/thread_window.py index 59b4517..f9b4e6e 100644 --- a/src/FukuiNoNamari/thread_window.py +++ b/src/FukuiNoNamari/thread_window.py @@ -93,6 +93,7 @@ class HTMLParserToThreadView: def initialize(self): self.buf = "" self.attrlist = pango.AttrList() + self.urilist = [] def from_html_parser(self, data, bold, href): data = data.encode("utf8") @@ -105,6 +106,7 @@ class HTMLParserToThreadView: if href: attr = pango.AttrUnderline(pango.UNDERLINE_SINGLE, start, end) self.attrlist.insert(attr) + self.urilist.append((start, end, href)) def to_thread_view(self, marginleft): layout = self.threadview.create_pango_layout(self.buf) @@ -112,6 +114,7 @@ class HTMLParserToThreadView: layout.resnum = self.resnum layout.marginleft = marginleft layout.set_attributes(self.attrlist) + layout.urilist = self.urilist gobject.idle_add(self.threadview.add_layout, layout) self.initialize()