GTK and scrolling without scrollbars
There’s still some work to do on the full screen plugin for Rhythmbox, but the current version is very usable indeed. The latest addition is scrolling by hovering the track list.
I changed the display from a normal fixed table with 3 tracks to a gtk.Layout with a gtk.VBox containing n tracks. In a Layout widget it’s possible to freely place and move child widgets, so by detecting motion events on the edges of the Layout you can emulate scrolling by moving a child widget accordingly with Layout.move(widget, x, y). Unfortunately I get a rather nasty blinking effect when scrolling too fast, and I don’t have an explanation for this, so I’d be glad to hear from anyone who can help.
def track_layout_scroll(self, widget, event): time_step = 10 #msecs ycoord = event.y accel_factor = 10 #how many pixels to scroll at the edge edge_distance = 100.0 #pixels layout_size = widget.get_size() top_dist = edge_distance - ycoord bot_dist = edge_distance - layout_size[1] + ycoord if top_dist > 0: accel = -1 - (top_dist / edge_distance) * accel_factor elif bot_dist > 0: accel = 1 + (bot_dist / edge_distance) * accel_factor else: accel = 0.0 if self.scroll_event_id: gobject.source_remove(self.scroll_event_id) if not accel == 0.0: self.scroll_event_id = gobject.timeout_add(time_step, self.do_scrolling, accel, widget) def do_scrolling(self, accel, layout_widget): step = int(1*accel) if step == 0: return vbox_size = self.vbox.size_request() layout_size = layout_widget.get_size() scroll_height = vbox_size[1]-layout_size[1] if self.scroll_y + step < 0: self.scroll_y = 0 elif self.scroll_y + step > scroll_height: self.scroll_y = scroll_height else: self.scroll_y += step self.track_layout.move(self.vbox, 0, -self.scroll_y) return self.scroll_y > 0 and self.scroll_y < scroll_height
The code is related to my Rhythmbox plugin, but I’m sure you get the idea. Also please note, that track_layout_scroll has to receive notify_motion_event from the Layout widget, and that you have to set a size for the Layout widget with set_size().
Update: By playing around with time_step (lowering it to be more exact) and slowing down the acceleration, I managed to almost make the white flashes disappear.