OSDN Git Service

change the mouse cursor according to text area, uri area and non text area.
authorAiwota Programmer <aiwotaprog@tetteke.tk>
Tue, 11 Dec 2007 15:11:31 +0000 (00:11 +0900)
committerAiwota Programmer <aiwotaprog@tetteke.tk>
Tue, 11 Dec 2007 15:11:31 +0000 (00:11 +0900)
src/FukuiNoNamari/thread_view.py
src/FukuiNoNamari/thread_window.py

index 120bd64..78a14da 100644 (file)
@@ -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)
index 59b4517..f9b4e6e 100644 (file)
@@ -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()