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)
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 |
+ gtk.gdk.BUTTON_PRESS_MASK |
+ gtk.gdk.BUTTON_RELEASE_MASK)
- self.adjustment.step_increment = 20
self.drawingarea_prev_width = 0
self.drawingarea.connect(
"expose-event", self.on_drawingarea_expose_event)
self.drawingarea.connect(
- "size-allocate", self.on_drawingarea_size_allocate)
+ "configure-event", self.on_drawingarea_configure_event)
+ self.drawingarea.connect(
+ "scroll-event", self.on_drawingarea_scroll_event)
+ self.drawingarea.connect(
+ "motion-notify-event", self.on_drawingrarea_motion_notify_event)
self.drawingarea.connect(
"button-press-event", self.on_drawingarea_button_press_event)
self.drawingarea.connect(
- "scroll-event", self.on_drawingarea_scroll_event)
+ "button-release-event", self.on_drawingarea_button_release_event)
self.vscrollbar.connect(
"value-changed", self.on_vscrollbar_value_changed)
self.initialize_buffer()
+ self.on_uri_clicked = self._on_uri_clicked
+
+ self.button1_pressed = False
+ self.current_pressed_uri = None
+
+ self.popupmenu = None
+ self.menu_openuri = None
+ self.menu_copylinkaddress = None
+ self.menu_separator_link = None
+ self.menu_copyselection = None
+ self.menu_openasuri = None
+ self.menu_separator_selection = None
+
+ self.menud_uri = None
+
+ def _on_uri_clicked(self, uri):
+ print uri, "clicked!!!!"
+
def initialize_buffer(self):
self.pangolayout = []
self.set_layout_width(pangolayout)
self.pangolayout.append(pangolayout)
x, y = pangolayout.get_pixel_size()
- self.adjustment.upper = pangolayout.posY + y
- self.prevent_adjustment_overflow()
+ self.vscrollbar.set_range(0, pangolayout.posY + y)
self.redraw()
self.change_vscrollbar_visible()
layout.posY = sum_height
x, y = layout.get_pixel_size()
sum_height += y
- self.adjustment.upper = sum_height
- self.prevent_adjustment_overflow()
+ self.vscrollbar.set_range(0, sum_height)
self.change_vscrollbar_visible()
def change_vscrollbar_visible(self):
self.vscrollbar.show()
def jump(self, value):
- if value > self.adjustment.upper - self.adjustment.page_size:
- value = self.adjustment.upper - self.adjustment.page_size
- self.adjustment.set_value(value)
+ self.vscrollbar.set_value(value)
def jump_to_layout(self, layout):
self.jump(layout.posY)
def jump_to_the_end(self):
value = self.adjustment.upper - self.adjustment.page_size
- self.adjustment.set_value(value)
+ self.vscrollbar.set_value(value)
def jump_to_res(self, resnum):
for layout in self.pangolayout:
return False
def draw_viewport(self):
- view_y = self.adjustment.get_value()
+ view_y = self.vscrollbar.get_value()
self.drawingarea.window.draw_rectangle(
self.drawingarea.style.base_gc[0],
True, 0, 0,
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.vscrollbar.get_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()
- def on_drawingarea_size_allocate(self, widget, allocation, data=None):
- if allocation.width != self.drawingarea_prev_width:
+ def on_drawingarea_configure_event(self, widget, event, data=None):
+ if event.width != self.drawingarea_prev_width:
self.relayout()
- self.drawingarea_prev_width = allocation.width
+ self.drawingarea_prev_width = event.width
self.adjustment.page_size = self.drawingarea.allocation.height
- self.adjustment.page_increment = self.drawingarea.allocation.height
+ self.vscrollbar.set_increments(20, self.drawingarea.allocation.height)
- self.prevent_adjustment_overflow()
+ # re-set 'value' for prevent overflow
+ self.vscrollbar.set_value(self.vscrollbar.get_value())
self.change_vscrollbar_visible()
- def prevent_adjustment_overflow(self):
- if (self.adjustment.value >
- self.adjustment.upper - self.adjustment.page_size):
- self.adjustment.value = (self.adjustment.upper -
- self.adjustment.page_size)
+ def on_vscrollbar_value_changed(self, widget, data=None):
+ self.drawingarea.queue_draw()
- if self.adjustment.value < 0:
- self.adjustment.value = 0
+ def on_drawingarea_scroll_event(self, widget, event, data=None):
+ self.vscrollbar.emit("scroll-event", event)
+
+ def on_drawingrarea_motion_notify_event(self, widget, event, data=None):
+ if event.state & gtk.gdk.BUTTON1_MASK != gtk.gdk.BUTTON1_MASK:
+ self.button1_pressed = False
+
+ 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)
def on_drawingarea_button_press_event(self, widget, event, data=None):
- self.drawingarea.queue_draw()
+ if event.button == 1:
+ self.current_pressed_uri = None
+ self.button1_pressed = True
+ uri, layout, index = self.ptrpos_to_uri(event.x, event.y)
+ if uri is not None and layout is not None and index is not None:
+ self.current_pressed_uri = (uri, layout, index)
+ elif event.button == 3:
+ time = event.time
+ uri, layout, index = self.ptrpos_to_uri(event.x, event.y)
+ if uri is not None and layout is not None and index is not None:
+ self.menu_openuri.show()
+ self.menu_copylinkaddress.show()
+ self.menu_separator_link.show()
+ self.menu_openuri.uri = uri
+ self.menu_copylinkaddress.uri = uri
+ else:
+ self.menu_openuri.hide()
+ self.menu_copylinkaddress.hide()
+ self.menu_separator_link.hide()
+ self.menu_openuri.uri = None
+ self.menu_copylinkaddress.uri = None
- def on_vscrollbar_value_changed(self, widget, data=None):
- self.drawingarea.queue_draw()
+ self.menu_copyselection.hide()
+ self.menu_openasuri.hide()
+ self.menu_separator_selection.hide()
- def on_drawingarea_scroll_event(self, widget, event, data=None):
- if event.direction == gtk.gdk.SCROLL_UP:
- self.adjustment.value -= 66.476200804
- if self.adjustment.value < self.adjustment.lower:
- self.adjustment.value = self.adjustment.lower
- if event.direction == gtk.gdk.SCROLL_DOWN:
- self.adjustment.value += 66.476200804
- max_value = self.adjustment.upper - self.adjustment.page_size
- if self.adjustment.value > max_value:
- self.adjustment.value = max_value
- self.prevent_adjustment_overflow()
+ self.popupmenu.popup(None, None, None, event.button, time)
+ return True
+
+
+ def on_drawingarea_button_release_event(self, widget, event, data=None):
+ if event.button == 1:
+ button1_pressed = self.button1_pressed
+ self.button1_pressed = False
+
+ if button1_pressed and self.current_pressed_uri is not None:
+ uri, layout, index = self.ptrpos_to_uri(event.x, event.y)
+ p_uri, p_layout, p_index = self.current_pressed_uri
+ self.current_preesed_uri = None
+ if uri == p_uri and layout == p_layout and index == p_index:
+ self.on_uri_clicked(uri)