def __init__(self, x, y, width, height, pixbuf, margin=1, radius=15): Base.__init__(self) abs_width = self.get_abs_x(width) abs_height = self.get_abs_y(height) clutter.CairoTexture.__init__(self, abs_width, abs_height) context = self.cairo_create() ct = gtk.gdk.CairoContext(context) # Round corners w1 = abs_width - (margin * 2) h1 = abs_height - (margin * 2) self.roundedCorners(context, margin, margin, w1, h1, radius, radius) # Scale context area wr = abs_width / float(pixbuf.get_width()) hr = abs_height / float(pixbuf.get_height()) context.scale(wr, hr) ct.set_source_pixbuf(pixbuf, 0, 0) context.paint() del context # Update texture del ct self.set_position(self.get_abs_x(x), self.get_abs_y(y))
def __init__(self, x, y, size=0.03, inner_radius=0.25, outter_radius=0.45, thickness=0.08): Base.__init__(self) abs_size = self.get_abs_x(size) clutter.CairoTexture.__init__(self, abs_size, abs_size) self.set_anchor_point(abs_size / 2, abs_size / 2) c = self._clutterColorToCairoColor(clutter.Color(255, 255, 255, 255)) bg = self._clutterColorToCairoColor(clutter.Color(128, 128, 128, 128)) context = self.cairo_create() context.scale(abs_size, abs_size) context.set_line_width(thickness) context.set_line_cap(cairo.LINE_CAP_ROUND) # Draw the 12 lines for i in range(12): self._draw_line(context, bg, c, outter_radius, inner_radius, i) del (context) # Updates texture self.keep_going = False self.set_position(self.get_abs_x(x), self.get_abs_y(y))
def __init__(self, font_size, color_name, x_pos_percent, y_pos_percent, text=None, name=None, font_weight=""): """Initialize the Label object""" Base.__init__(self) clutter.Text.__init__(self) self.theme = self.config.theme self._font_weight = font_weight self._font_size = font_size self._set_font_size(font_size) self.color = color_name self._position = None self._set_position((x_pos_percent, y_pos_percent)) if text: self.set_text(text) if name: self.set_name(name) self.set_line_wrap(True)
def __init__(self, name, title="Untitled tab", callback=None): Base.__init__(self) clutter.Group.__init__(self) self.name = name self.title = title self.callback = callback self.theme = self.config.theme self.dispatch = { UserEvent.NAVIGATE_UP : self._handle_up, UserEvent.NAVIGATE_DOWN : self._handle_down, UserEvent.NAVIGATE_LEFT : self._handle_left, UserEvent.NAVIGATE_RIGHT : self._handle_right, UserEvent.NAVIGATE_SELECT : self._handle_select, } # show/hide animation on the Tab self.timeline = clutter.Timeline(500) self.timeline.connect('completed', self._on_timeline_completed) self.alpha = clutter.Alpha(self.timeline, clutter.EASE_IN_OUT_SINE) self.behaviour = clutter.BehaviourOpacity(0, 255, self.alpha) self.behaviour.apply(self) # Tabs are created deactivated and invisible self._active = None self._visible = False self.set_opacity(0) self.hide()
def __init__(self, x, y, size=0.03, inner_radius=0.25, outter_radius=0.45, thickness=0.08): Base.__init__(self) abs_size = self.get_abs_x(size) clutter.CairoTexture.__init__(self, abs_size, abs_size) self.set_anchor_point(abs_size / 2, abs_size / 2) c = self._clutterColorToCairoColor(clutter.Color(255, 255, 255, 255)) bg = self._clutterColorToCairoColor(clutter.Color(128, 128, 128, 128)) context = self.cairo_create() context.scale(abs_size, abs_size) context.set_line_width (thickness) context.set_line_cap(cairo.LINE_CAP_ROUND) # Draw the 12 lines for i in range(12): self._draw_line(context, bg, c, outter_radius, inner_radius, i) del(context) # Updates texture self.keep_going = False self.set_position(self.get_abs_x(x), self.get_abs_y(y))
def __init__(self, filename, x_pos_percent=0, y_pos_percent=0): """Initialize the Texture object""" Base.__init__(self) clutter.Texture.__init__(self, filename) self.logger = Logger().getLogger('gui.widgets.Texture') self._position = None self._set_position((x_pos_percent, y_pos_percent))
def __init__(self, x, y, width, height, color="title"): Base.__init__(self) clutter.Group.__init__(self) self.width = self.get_abs_x(width) self.height = self.get_abs_y(height) self.bar_width = int(self.width * self.BAR_LENGTH) self.bar_x = int(self.width * self.INFO_LENGTH) self.media_length_x = (1 - self.INFO_LENGTH + 0.05) * width self.set_position(self.get_abs_x(x), self.get_abs_y(y)) self._color = self._color_to_cairo_color( self.config.theme.get_color(color)) self._background = clutter.CairoTexture(self.bar_width, self.height) self._draw_background() self._background.set_position(self.bar_x, 0) self.add(self._background) self._foreground = clutter.CairoTexture(self.height, self.height) self._foreground.set_anchor_point_from_gravity(clutter.GRAVITY_CENTER) self._draw_foreground() self._foreground.set_position(self.bar_x, 0) self.add(self._foreground) self.media_position = Label(0.037, "title", 0, 0, "") self.add(self.media_position) self.media_length = Label(0.037, "title", self.media_length_x, 0, "") self.add(self.media_length) self._media_player = None self._progress_bar_moving = False self._hide_timeout_key = None self.auto_display = False self._visible = None self._timeline = clutter.Timeline(500) self._alpha = clutter.Alpha(self._timeline, clutter.EASE_IN_OUT_SINE) self._behaviour = clutter.BehaviourOpacity(0, 255, self._alpha) self._behaviour.apply(self) self._progress = None # Call the property setter to initialize the displayed position. self.progress = 0 # Preparation to pointer events handling. self._motion_handler = 0 self.set_reactive(True) self.connect('scroll-event', self._on_scroll_event) self.connect('button-press-event', self._on_button_press_event) self.connect('button-release-event', self._on_button_release_event) self.connect('enter-event', self._on_enter_event) self.connect('leave-event', self._on_leave_event)
def __init__(self, x, y, width, height, pixbuf): Base.__init__(self) clutter.Group.__init__(self) rounded = RoundedTexture(0.0, 0.0, width, height, pixbuf) reflection = ReflectionTexture(0.0, 0.0, width, height, pixbuf, round_corners=True) reflection.set_position(0, rounded.get_height()) self.set_position(self.get_abs_x(x), self.get_abs_y(y)) self.add(rounded) self.add(reflection)
def __init__(self, x, y, width, height, pixbuf, ref_height=0.3, opacity=0.3, round_corners=False, margin=1, radius=15): Base.__init__(self) abs_width = self.get_abs_x(width) abs_height = self.get_abs_y(height) clutter.CairoTexture.__init__(self, abs_width, abs_height) context = self.cairo_create() ct = gtk.gdk.CairoContext(context) # Round corners if round_corners: x = 0 + margin y = 0 + margin w1 = abs_width - (margin * 2) h1 = abs_height - (margin * 2) self.roundedCorners(context, x, y, w1, h1, radius, radius) # Scale context area wr = abs_width / float(pixbuf.get_width()) hr = abs_height / float(pixbuf.get_height()) context.scale(wr, hr) # Create gradient mask self.gradient = cairo.LinearGradient(0, 0, 0, pixbuf.get_height()) self.gradient.add_color_stop_rgba(1 - ref_height, 1, 1, 1, 0) self.gradient.add_color_stop_rgba(1, 0, 0, 0, opacity) ct.set_source_pixbuf(pixbuf, 0, 0) context.mask(self.gradient) del context # Update texture del ct self.set_anchor_point_from_gravity(clutter.GRAVITY_SOUTH_WEST) self.set_rotation(clutter.Z_AXIS, 180, 0, 0, 0) self.set_rotation(clutter.Y_AXIS, 180, 0, 0, 0) self.set_position(self.get_abs_x(x), self.get_abs_y(y))
def __init__(self, x, y, width, height, content): Base.__init__(self) clutter.Group.__init__(self) self._motion_buffer = MotionBuffer() self._offset = 0 # Drives the content motion. self._offset_max = 0 # Maximum value of offset (equal on bottom). self._old_offset = 0 # Stores the old value of offset on motions. self._motion_handler = 0 self._active = None self.step_size = self.get_abs_y(self.STEP_SIZE_PERCENT) # Allowed area for the widget's scrolling content. self.area_width = self.get_abs_x(width) self.area_height = self.get_abs_y(height) # Create content position indicator self.indicator = ListIndicator(3 * width / 4, height, 0.2, 0.045, ListIndicator.VERTICAL) self.indicator.hide_position() self.indicator.set_maximum(2) self.add(self.indicator) # A clipped Group to receive the content. self._fixed_group = clutter.Group() self._fixed_group.set_clip(0, 0, self.area_width, self.area_height) self.add(self._fixed_group) self.content = None self._motion_timeline = clutter.Timeline(500) self._motion_timeline.connect('completed', self._motion_timeline_callback, None) self._motion_alpha = clutter.Alpha(self._motion_timeline, clutter.EASE_OUT_SINE) self._motion_behaviour = LoopedPathBehaviour(self._motion_alpha) self.set_content(content) self.active = None # Preparation to pointer events handling. self.set_reactive(True) self.connect('button-press-event', self._on_button_press_event) self.connect('button-release-event', self._on_button_release_event) self.connect('scroll-event', self._on_scroll_event) self.set_position(self.get_abs_x(x), self.get_abs_y(y))
def __init__(self, x, y, width, height, direction): Base.__init__(self) clutter.Group.__init__(self) self.config = Configuration() # Size self.width = self.get_abs_x(width) self.height = self.get_abs_y(height) self.direction = direction self.delimiter = " | " self.current = 1 self.maximum = 1 self.theme = self.config.theme self.fg = self.theme.get_color("arrow_foreground") self.bg = self.theme.get_color("arrow_background") if direction == ListIndicator.VERTICAL: text_x_pos = width / 3 else: text_x_pos = width / 2 self.text = Label( height * 0.8, "text", text_x_pos, height / 2, str(self.maximum) + self.delimiter + str(self.maximum)) self.text.set_anchor_point_from_gravity(clutter.GRAVITY_CENTER) self.add(self.text) # Create arrows and calculate positions on screen if direction == ListIndicator.VERTICAL: self.arrow1 = ArrowTexture(5 * width / 7, height / 2, height / 2, self.fg, self.bg, ArrowTexture.UP) self.arrow2 = ArrowTexture(6 * width / 7, height / 2, height / 2, self.fg, self.bg, ArrowTexture.DOWN) elif direction == ListIndicator.HORIZONTAL: self.arrow1 = ArrowTexture(height / 2, height / 2, height / 2, self.fg, self.bg, ArrowTexture.LEFT) self.arrow2 = ArrowTexture(6 * width / 7, height / 2, height / 2, self.fg, self.bg, ArrowTexture.RIGHT) self.add(self.arrow1) self.add(self.arrow2) self.set_position(self.get_abs_x(x), self.get_abs_y(y))
def __init__(self, x, y, width, height, direction): Base.__init__(self) clutter.Group.__init__(self) self.config = Configuration() # Size self.width = self.get_abs_x(width) self.height = self.get_abs_y(height) self.direction = direction self.delimiter = " | " self.current = 1 self.maximum = 1 self.theme = self.config.theme self.fg = self.theme.get_color("arrow_foreground") self.bg = self.theme.get_color("arrow_background") if direction == ListIndicator.VERTICAL: text_x_pos = width / 3 else: text_x_pos = width / 2 self.text = Label(height * 0.8, "text", text_x_pos, height / 2, str(self.maximum) + self.delimiter + str(self.maximum)) self.text.set_anchor_point_from_gravity(clutter.GRAVITY_CENTER) self.add(self.text) # Create arrows and calculate positions on screen if direction == ListIndicator.VERTICAL: self.arrow1 = ArrowTexture(5 * width / 7, height / 2, height / 2, self.fg, self.bg, ArrowTexture.UP) self.arrow2 = ArrowTexture(6 * width / 7, height / 2, height / 2, self.fg, self.bg, ArrowTexture.DOWN) elif direction == ListIndicator.HORIZONTAL: self.arrow1 = ArrowTexture(height / 2, height / 2, height / 2, self.fg, self.bg, ArrowTexture.LEFT) self.arrow2 = ArrowTexture(6 * width / 7, height / 2, height / 2, self.fg, self.bg, ArrowTexture.RIGHT) self.add(self.arrow1) self.add(self.arrow2) self.set_position(self.get_abs_x(x), self.get_abs_y(y))
def __init__(self, name='', callback=None, has_tabs=False, kind=None): """ You should never create a Screen object directly! This init is supposed to be called from child classes that inherit this class. """ Base.__init__(self) clutter.Group.__init__(self) self.name = name self.callback = callback self.has_tabs = has_tabs if has_tabs: self.tab_group = TabGroup(0.95, 0.13, 'title') self.tab_group.set_y(self.get_abs_y(0.1)) self.tab_group.set_anchor_point_from_gravity( clutter.GRAVITY_CENTER) self.tab_group.set_x(self.get_abs_x(0.5)) self.tab_group.active = True self.add(self.tab_group) if kind is None: self.kind = self.NORMAL else: self.kind = kind def handle_default(): '''Return the default handler method.''' return self._handle_default self.event_handlers = defaultdict( handle_default, { UserEvent.NAVIGATE_UP: self._handle_up, UserEvent.NAVIGATE_DOWN: self._handle_down, UserEvent.NAVIGATE_LEFT: self._handle_left, UserEvent.NAVIGATE_RIGHT: self._handle_right, UserEvent.NAVIGATE_SELECT: self._handle_select }) rect = clutter.Rectangle() rect.set_size(self.config.stage_width, self.config.stage_height) rect.hide() self.add(rect)
def __init__(self, name='', callback=None, has_tabs=False, kind=None): """ You should never create a Screen object directly! This init is supposed to be called from child classes that inherit this class. """ Base.__init__(self) clutter.Group.__init__(self) self.name = name self.callback = callback self.has_tabs = has_tabs if has_tabs: self.tab_group = TabGroup(0.95, 0.13, 'title') self.tab_group.set_y(self.get_abs_y(0.1)) self.tab_group.set_anchor_point_from_gravity(clutter.GRAVITY_CENTER) self.tab_group.set_x(self.get_abs_x(0.5)) self.tab_group.active = True self.add(self.tab_group) if kind is None: self.kind = self.NORMAL else: self.kind = kind def handle_default(): '''Return the default handler method.''' return self._handle_default self.event_handlers = defaultdict(handle_default, { UserEvent.NAVIGATE_UP : self._handle_up, UserEvent.NAVIGATE_DOWN : self._handle_down, UserEvent.NAVIGATE_LEFT : self._handle_left, UserEvent.NAVIGATE_RIGHT : self._handle_right, UserEvent.NAVIGATE_SELECT : self._handle_select }) rect = clutter.Rectangle() rect.set_size(self.config.stage_width, self.config.stage_height) rect.hide() self.add(rect)
def __init__( self, x, y, width, height, pixbuf, ref_height=0.3, opacity=0.3, round_corners=False, margin=1, radius=15 ): Base.__init__(self) abs_width = self.get_abs_x(width) abs_height = self.get_abs_y(height) clutter.CairoTexture.__init__(self, abs_width, abs_height) context = self.cairo_create() ct = gtk.gdk.CairoContext(context) # Round corners if round_corners: x = 0 + margin y = 0 + margin w1 = abs_width - (margin * 2) h1 = abs_height - (margin * 2) self.roundedCorners(context, x, y, w1, h1, radius, radius) # Scale context area wr = abs_width / float(pixbuf.get_width()) hr = abs_height / float(pixbuf.get_height()) context.scale(wr, hr) # Create gradient mask self.gradient = cairo.LinearGradient(0, 0, 0, pixbuf.get_height()) self.gradient.add_color_stop_rgba(1 - ref_height, 1, 1, 1, 0) self.gradient.add_color_stop_rgba(1, 0, 0, 0, opacity) ct.set_source_pixbuf(pixbuf, 0, 0) context.mask(self.gradient) del context # Update texture del ct self.set_anchor_point_from_gravity(clutter.GRAVITY_SOUTH_WEST) self.set_rotation(clutter.Z_AXIS, 180, 0, 0, 0) self.set_rotation(clutter.Y_AXIS, 180, 0, 0, 0) self.set_position(self.get_abs_x(x), self.get_abs_y(y))
class BaseTest(EntertainerTest): """Test for entertainerlib.gui.widgets.base""" def setUp(self): """Set up the test""" EntertainerTest.setUp(self) self.base = Base() def test_create(self): """Test Base object creation.""" self.assertTrue(isinstance(self.base, Base)) def test_get_abs_x(self): """Test getting the absolute size of x based on the stage width.""" self.assertEqual(self.base.get_abs_x(.25), 341) def test_get_abs_y(self): """Test getting the absolute size of y based on the stage height.""" self.assertEqual(self.base.get_abs_y(.25), 192) def test_y_for_x(self): """Test of the y_for_x method.""" self.assertAlmostEqual(self.base.y_for_x(.25), 0.44466145833333331)
def __init__(self): Base.__init__(self) clutter.Group.__init__(self) theme = self.config.theme filled = clutter.Texture(theme.getImage("volume_filled")) filled.hide() self.add(filled) unfilled = clutter.Texture(theme.getImage("volume_unfilled")) unfilled.hide() self.add(unfilled) volume = clutter.Texture(theme.getImage("volume")) self.add(volume) self._bars = [] bar_width = filled.get_width() for i in range(20): bar_filled = clutter.Clone(filled) bar_unfilled = clutter.Clone(unfilled) bar_filled.set_position(volume.get_width() + i * bar_width, 0) bar_unfilled.set_position(volume.get_width() + i * bar_width, 0) self.add(bar_filled) self.add(bar_unfilled) self._bars.append([bar_filled, bar_unfilled]) self._hide_timeout_key = None self.visible = False self.set_opacity(0) self.timeline = clutter.Timeline(200) self.alpha = clutter.Alpha(self.timeline, clutter.EASE_IN_OUT_SINE) self.behaviour = clutter.BehaviourOpacity(255, 0, self.alpha) self.behaviour.apply(self) self.set_position(self.get_abs_x(0.35), self.get_abs_y(0.1))
def __init__(self, width, height, color): Base.__init__(self) clutter.Group.__init__(self) self._active = None # Size self.stage_w = self.config.stage_width self.stage_h = self.config.stage_height self.width_factor = width self.height_factor = height # Label text colors self.color = color self.selected_color = self.config.theme.get_color(color) self.unselected_color = (self.selected_color[0], self.selected_color[1], self.selected_color[2], 96) # Size of the tab bar (This includes label texts) self.rect = clutter.Rectangle() self.rect.set_size( int(self.stage_w * self.width_factor), int(self.stage_h * self.height_factor)) self.rect.set_color(clutter.Color(255, 0, 0, 0)) self.add(self.rect) # Tab object dictionary that stores tab names as the keys. self._tabs = {} # Tab objects will be held in this list but should only be used for # internal calculations in the TabGroup class self.tabs_list = [] self.labels = [] self.timelines = [] # Contains tuples (timeline, alpha, behaviour) self.current_tab = None
def __init__(self): Base.__init__(self) clutter.Group.__init__(self) self._userdata = None
def __init__(self, x, y, size, fg_color, bg_color, direction): Base.__init__(self) abs_size = self.get_abs_x(size) clutter.CairoTexture.__init__(self, abs_size, abs_size) context = self.cairo_create() context.scale(abs_size, abs_size) fg_cairo = self._color_to_cairo_color(fg_color) bg_cairo = self._color_to_cairo_color(bg_color) # Draw background context.set_line_width(0.15) context.set_source_rgba(bg_cairo[0], bg_cairo[1], bg_cairo[2], bg_cairo[3]) self._roundedrec(context, 0, 0, 1, 1, 0.08, 0.1) context.fill() # Draw arrow context.set_source_rgba(fg_cairo[0], fg_cairo[1], fg_cairo[2], fg_cairo[3]) if direction == ArrowTexture.DOWN: context.move_to(0.25, 0.33) context.line_to(0.50, 0.66) context.line_to(0.75, 0.33) context.stroke() elif direction == ArrowTexture.UP: context.move_to(0.25, 0.66) context.line_to(0.50, 0.33) context.line_to(0.75, 0.66) context.stroke() elif direction == ArrowTexture.RIGHT: context.move_to(0.33, 0.25) context.line_to(0.66, 0.50) context.line_to(0.33, 0.75) context.stroke() elif direction == ArrowTexture.LEFT: context.move_to(0.66, 0.25) context.line_to(0.33, 0.50) context.line_to(0.66, 0.75) context.stroke() del (context) # Updates texture # Create bounce effect self.set_anchor_point_from_gravity(clutter.GRAVITY_CENTER) in_time = clutter.Timeline(300) in_alpha = clutter.Alpha(in_time, clutter.EASE_OUT_SINE) self.in_behaviour = clutter.BehaviourScale(1.0, 1.0, 1.5, 1.5, in_alpha) self.in_behaviour.apply(self) out_time = clutter.Timeline(300) out_alpha = clutter.Alpha(out_time, clutter.EASE_OUT_SINE) self.out_behaviour = clutter.BehaviourScale(1.5, 1.5, 1.0, 1.0, out_alpha) self.out_behaviour.apply(self) self.score = clutter.Score() self.score.append(timeline=in_time) self.score.append(timeline=out_time, parent=in_time) self.set_position(self.get_abs_x(x), self.get_abs_y(y))
def __init__(self, x=0, y=0, item_width=0.2, item_height=0.1): Base.__init__(self) clutter.Group.__init__(self) self.motion_duration = 100 # Default duration of animations ms. self.cursor_below = True # Is the cursor below items? self._active = None self._is_vertical = True self.items = [] # Items dimensions variable: relative, absolute, center self._item_width = item_width self._item_height = item_height self._item_width_abs = self.get_abs_x(item_width) self._item_height_abs = self.get_abs_y(item_height) self._dx = int(self._item_width_abs / 2) self._dy = int(self._item_height_abs / 2) # Default cursor's index. self._selected_index = 0 # Grid dimensions: real, visible. self.items_per_row = 10 self.items_per_col = 10 self._visible_rows = 3 self._visible_cols = 5 # The moving_group is a Clutter group containing all the items. self._moving_group_x = 0 self._moving_group_y = 0 self._moving_group = clutter.Group() self.add(self._moving_group) # The moving_group is translated using a `BehaviourPath`. self._moving_group_timeline = clutter.Timeline(200) moving_group_alpha = clutter.Alpha(self._moving_group_timeline, clutter.EASE_IN_OUT_SINE) moving_group_path = clutter.Path() self._moving_group_behaviour = clutter.BehaviourPath(moving_group_alpha, moving_group_path) self._moving_group_behaviour.apply(self._moving_group) # The cursor is an Actor that can be added and moved on the menu. # The cusor is always located in the visible (clipped) area of the menu. self._cursor_x = 0 self._cursor_y = 0 self._cursor = None self._cursor_timeline = clutter.Timeline(200) cursor_alpha = clutter.Alpha(self._cursor_timeline, clutter.EASE_IN_SINE) cursor_path = clutter.Path() self._cursor_behaviour = clutter.BehaviourPath(cursor_alpha, cursor_path) # A MotionBuffer is used to compute useful information about the # cursor's motion. It's used when moving the cursor with a pointer. self._motion_buffer = MotionBuffer() self._event_mode = self.MODE_NONE self._motion_handler = 0 self._seek_step_x = 0 self._seek_step_y = 0 gobject.timeout_add(200, self._internal_timer_callback) #XXX: Samuel Buffet # This rectangle is used to grab events as it turns out that their # might be a bug in clutter 0.8 or python-clutter 0.8. # It may be avoided with next release of clutter. self._event_rect = clutter.Rectangle() self._event_rect.set_opacity(0) self.add(self._event_rect) self._event_rect.set_reactive(True) self._event_rect.connect('button-press-event', self._on_button_press_event) self._event_rect.connect('button-release-event', self._on_button_release_event) self._event_rect.connect('scroll-event', self._on_scroll_event) self.set_position(self.get_abs_x(x), self.get_abs_y(y))
def setUp(self): """Set up the test""" EntertainerTest.setUp(self) self.base = Base()
def __init__(self, x=0, y=0, item_width=0.2, item_height=0.1): Base.__init__(self) clutter.Group.__init__(self) self.motion_duration = 100 # Default duration of animations ms. self.cursor_below = True # Is the cursor below items? self._active = None self._is_vertical = True self.items = [] # Items dimensions variable: relative, absolute, center self._item_width = item_width self._item_height = item_height self._item_width_abs = self.get_abs_x(item_width) self._item_height_abs = self.get_abs_y(item_height) self._dx = int(self._item_width_abs / 2) self._dy = int(self._item_height_abs / 2) # Default cursor's index. self._selected_index = 0 # Grid dimensions: real, visible. self.items_per_row = 10 self.items_per_col = 10 self._visible_rows = 3 self._visible_cols = 5 # The moving_group is a Clutter group containing all the items. self._moving_group_x = 0 self._moving_group_y = 0 self._moving_group = clutter.Group() self.add(self._moving_group) # The moving_group is translated using a `BehaviourPath`. self._moving_group_timeline = clutter.Timeline(200) moving_group_alpha = clutter.Alpha(self._moving_group_timeline, clutter.EASE_IN_OUT_SINE) moving_group_path = clutter.Path() self._moving_group_behaviour = clutter.BehaviourPath( moving_group_alpha, moving_group_path) self._moving_group_behaviour.apply(self._moving_group) # The cursor is an Actor that can be added and moved on the menu. # The cusor is always located in the visible (clipped) area of the menu. self._cursor_x = 0 self._cursor_y = 0 self._cursor = None self._cursor_timeline = clutter.Timeline(200) cursor_alpha = clutter.Alpha(self._cursor_timeline, clutter.EASE_IN_SINE) cursor_path = clutter.Path() self._cursor_behaviour = clutter.BehaviourPath(cursor_alpha, cursor_path) # A MotionBuffer is used to compute useful information about the # cursor's motion. It's used when moving the cursor with a pointer. self._motion_buffer = MotionBuffer() self._event_mode = self.MODE_NONE self._motion_handler = 0 self._seek_step_x = 0 self._seek_step_y = 0 gobject.timeout_add(200, self._internal_timer_callback) #XXX: Samuel Buffet # This rectangle is used to grab events as it turns out that their # might be a bug in clutter 0.8 or python-clutter 0.8. # It may be avoided with next release of clutter. self._event_rect = clutter.Rectangle() self._event_rect.set_opacity(0) self.add(self._event_rect) self._event_rect.set_reactive(True) self._event_rect.connect('button-press-event', self._on_button_press_event) self._event_rect.connect('button-release-event', self._on_button_release_event) self._event_rect.connect('scroll-event', self._on_scroll_event) self.set_position(self.get_abs_x(x), self.get_abs_y(y))