67
72
elif key == 'scroll-image':
68
73
self.scroll_image = value
69
74
self._scroll_image.set_source(self.scroll_image)
70
self._scroll_image._update_layout()
75
self._scroll_image._update_layout()
72
77
def _update_layout(self):
73
78
""" Updates layout """
75
80
super(ScrollArea, self)._update_layout()
82
# Subscribe to key-press events
84
_stage = self.get_stage()
85
_stage.connect('key-press-event', self.do_key_press_event)
87
# Update background and scroll image layouts
77
88
self._background_image._update_layout()
78
self._scroll_image._update_layout()
89
self._scroll_image._update_layout()
80
91
for item in self._items:
81
92
item._update_layout()
83
#print self._scroll_image.get_height(), item.get_height()
94
# Clip the scroll area
85
95
self.set_clipu(0, 0, self.get_widthu(), self.get_heightu())
86
#self._scroll_image.set_clipu(0, 0, self._scroll_image.get_widthu(), self._scroll_image.get_heightu())
88
def _scroll_up(self, factor=0.2, px=None):
93
self._scroll_image.get_y() - px
96
self._scroll_image.get_y() - self._scroll_image.get_height() * factor
98
if not self._timeline or not self._timeline.is_playing():
99
if target_y < self.get_height() - self._scroll_image.get_height():
100
self._timeline = clutter.Timeline(fps=60, duration=200)
101
alpha = clutter.Alpha(self._timeline, clutter.sine_inc_func)
102
self._behaviour = clutter.BehaviourPath(alpha)
103
self._behaviour.append_knots(
104
(0, self._scroll_image.get_y()),
106
(0, -(self._scroll_image.get_height() - self.get_height()))
109
self._timeline = clutter.Timeline(fps=60, duration=100)
110
alpha = clutter.Alpha(self._timeline, clutter.smoothstep_inc_func)
111
self._behaviour = clutter.BehaviourPath(alpha)
112
self._behaviour.append_knots(
113
(0, self._scroll_image.get_y()),
116
self._behaviour.apply(self._scroll_image)
117
self._timeline.start()
120
def _scroll_down(self, factor=0.2, px=None):
125
self._scroll_image.get_y() + px
128
self._scroll_image.get_y() + self._scroll_image.get_height() * factor
129
if not self._timeline or not self._timeline.is_playing():
131
self._timeline = clutter.Timeline(fps=60, duration=200)
132
alpha = clutter.Alpha(self._timeline, clutter.sine_inc_func)
133
self._behaviour = clutter.BehaviourPath(alpha)
134
self._behaviour.append_knots(
140
self._timeline = clutter.Timeline(fps=60, duration=100)
141
alpha = clutter.Alpha(self._timeline, clutter.smoothstep_inc_func)
142
self._behaviour = clutter.BehaviourPath(alpha)
143
self._behaviour.append_knots(
144
(0, self._scroll_image.get_y()),
147
self._behaviour.apply(self._scroll_image)
148
self._timeline.start()
150
def _scroll_to(self, factor):
151
""" Scrolls to a given position
153
factor -- (float) position as a factor of the scroll area height
97
def pack(self, widget):
98
""" Packs a widget into the scroll area """
100
self._scroll_image.add(widget)
101
self._items.append(widget)
103
self._update_layout()
105
def unpack(self, widget):
106
""" Unpacks a widget from the scroll widget """
108
self._scroll_image.remove(widget)
109
self._items.remove(widget)
111
self._update_layout()
113
def scroll(self, horiz_factor=0.0, vert_factor=0.0):
114
""" Scroll by a horizontal and/or vertical factor
116
horiz_factor -- (float) Horizontal factor to scroll
117
vert_factor -- (float) Vertical factor to scroll
156
if self._previous_scroll_image_y:
157
_scroll_image_y = self._previous_scroll_image_y
159
_scroll_image_y = self._scroll_image.get_y()
160
target_y = _scroll_image_y + self._scroll_image.get_height() * factor
120
self._horiz_factor += horiz_factor
121
self._vert_factor += vert_factor
123
# Determine target x and y values for the scroll image
124
horiz_factor_as_units = self._horiz_factor * self._scroll_image.get_widthu()
125
target_x = self._scroll_image.get_xu() + horiz_factor_as_units
127
vert_factor_as_units = self._vert_factor * self._scroll_image.get_heightu()
128
target_y = self._scroll_image.get_yu() + vert_factor_as_units
130
# Normalize targets out of bounds
133
elif target_x < self.get_widthu() - self._scroll_image.get_widthu():
134
target_x = -(self._scroll_image.get_widthu() - self.get_widthu())
137
elif target_y < self.get_heightu() - self._scroll_image.get_heightu():
138
target_y = -(self._scroll_image.get_heightu() - self.get_heightu())
140
if self._scroll_image.get_xu() == 0 or self._scroll_image.get_xu() == self.get_widthu() - self._scroll_image.get_widthu():
141
self._horiz_factor = 0.0
142
if self._scroll_image.get_yu() == 0 or self._scroll_image.get_yu() == self.get_heightu() - self._scroll_image.get_heightu():
143
self._vert_factor = 0.0
145
# Kick-start scroll animations
162
146
if self._timeline:
163
147
self._timeline.rewind()
165
149
self._timeline = clutter.Timeline(fps=60, duration=200)
166
alpha = clutter.Alpha(self._timeline, clutter.sine_inc_func)
150
alpha = clutter.Alpha(self._timeline, clutter.sine_inc_func)
167
151
self._behaviour = clutter.BehaviourPath(alpha)
168
152
self._behaviour.append_knots(
169
(0, self._scroll_image.get_y()),
153
(self._scroll_image.get_x(), self._scroll_image.get_y()),
154
(clutter.units_to_device(target_x), clutter.units_to_device(target_y))
172
self._previous_scroll_image_y = target_y
173
156
self._behaviour.apply(self._scroll_image)
174
157
self._timeline.start()
176
#self._scroll_image.set_y(int(target_y))
178
def pack(self, widget):
179
""" Packs a widget into the scroll area """
181
self._scroll_image.add(widget)
182
self._items.append(widget)
184
if isinstance(widget, Scrollable):
185
widget.connect('view-changed', self.on_scrollable_view_changed)
187
self._update_layout()
189
def unpack(self, widget):
190
""" Unpacks a widget in the scroll widget """
192
self._scroll_image.remove(widget)
193
self._items.remove(widget)
195
self._update_layout()
197
def on_scroll_event(self, widget, event):
159
def do_scroll_event(self, widget, event):
160
""" Handles scroll event """
200
162
if event.direction == clutter.SCROLL_UP:
164
self.scroll(vert_factor=0.1)
202
165
elif event.direction == clutter.SCROLL_DOWN:
167
self.scroll(vert_factor=-0.1)
204
168
elif event.direction == clutter.SCROLL_LEFT:
206
171
elif event.direction == clutter.SCROLL_RIGHT:
209
def on_scrollable_view_changed(self, widget, event, offset):
210
""" Scrollable view changed """
212
# Get event widget allocation box (clutter units)
213
xu, yu, widthu, heightu = event
215
# Update xu, yu for coords relative to self
217
while parent != self:
218
yu += parent.get_yu()
219
parent = parent.get_parent()
221
scroll_delta = float(heightu) / float(self._scroll_image.get_heightu())
223
self._scroll_to(scroll_delta)
224
elif yu + heightu > self.get_heightu():
225
self._scroll_to(-scroll_delta)
175
def do_key_press_event(self, widget, event):
176
""" Handles key press event """
178
if event.keyval == clutter.keysyms.Up:
180
self.scroll(vert_factor=0.1)
181
elif event.keyval == clutter.keysyms.Down:
183
self.scroll(vert_factor=-0.1)
184
elif event.keyval == clutter.keysyms.Left:
187
elif event.keyval == clutter.keysyms.Right: