static void move_slider (MxScrollBar *bar, gfloat x, gfloat y) { MxScrollBarPrivate *priv = bar->priv; gdouble position, lower, upper, page_size; gfloat ux, uy, pos, size; if (!priv->adjustment) return; if (!clutter_actor_transform_stage_point (priv->trough, x, y, &ux, &uy)) return; if (priv->orientation == MX_ORIENTATION_VERTICAL) size = clutter_actor_get_height (priv->trough) - clutter_actor_get_height (priv->handle); else size = clutter_actor_get_width (priv->trough) - clutter_actor_get_width (priv->handle); if (size == 0) return; if (priv->orientation == MX_ORIENTATION_VERTICAL) pos = uy - priv->y_origin; else pos = ux - priv->x_origin; pos = CLAMP (pos, 0, size); mx_adjustment_get_values (priv->adjustment, NULL, &lower, &upper, NULL, NULL, &page_size); position = ((pos / size) * (upper - lower - page_size)) + lower; mx_adjustment_set_value (priv->adjustment, position); }
static void mex_media_controls_replace_content (MexMediaControls *self, MexContent *content) { MexPlayer *player; MxScrollable *related_box; MxAdjustment *adjustment; gdouble upper; MexMediaControlsPrivate *priv = self->priv; if (priv->content == content) return; player = mex_player_get_default (); mex_content_view_set_content (MEX_CONTENT_VIEW (player), content); if (priv->content) g_object_unref (priv->content); priv->content = g_object_ref_sink (content); mex_media_controls_update_header (self); mex_content_view_set_content (MEX_CONTENT_VIEW (priv->queue_button), content); mex_push_focus ((MxFocusable*) clutter_script_get_object (priv->script, "play-pause-button")); related_box = (MxScrollable *)clutter_script_get_object (priv->script, "related-box"); mx_scrollable_get_adjustments (MX_SCROLLABLE (related_box), &adjustment, NULL); mx_adjustment_get_values (adjustment, NULL, NULL, &upper, NULL, NULL, NULL); mx_adjustment_set_value (adjustment, upper); mx_scrollable_set_adjustments (MX_SCROLLABLE (related_box), adjustment, NULL); }
static void child_adjustment_changed_cb (MxAdjustment *adjustment, ClutterActor *bar) { MxScrollView *scroll; gdouble lower, upper, page_size; scroll = MX_SCROLL_VIEW (clutter_actor_get_parent (bar)); /* Determine if this scroll-bar should be visible */ mx_adjustment_get_values (adjustment, NULL, &lower, &upper, NULL, NULL, &page_size); if ((upper - lower) > page_size) clutter_actor_show (bar); else clutter_actor_hide (bar); /* Request a resize */ clutter_actor_queue_relayout (CLUTTER_ACTOR (scroll)); }
static gboolean trough_paging_cb (MxScrollBar *self) { gfloat handle_pos, event_pos, tx, ty; gdouble value; gdouble page_increment; gboolean ret; gulong mode; if (self->priv->paging_event_no == 0) { /* Scroll on after initial timeout. */ mode = CLUTTER_EASE_OUT_CUBIC; ret = FALSE; self->priv->paging_event_no = 1; self->priv->paging_source_id = g_timeout_add ( PAGING_INITIAL_REPEAT_TIMEOUT, (GSourceFunc) trough_paging_cb, self); } else if (self->priv->paging_event_no == 1) { /* Scroll on after subsequent timeout. */ ret = FALSE; mode = CLUTTER_EASE_IN_CUBIC; self->priv->paging_event_no = 2; self->priv->paging_source_id = g_timeout_add ( PAGING_SUBSEQUENT_REPEAT_TIMEOUT, (GSourceFunc) trough_paging_cb, self); } else { /* Keep scrolling. */ ret = TRUE; mode = CLUTTER_LINEAR; self->priv->paging_event_no++; } /* Do the scrolling */ mx_adjustment_get_values (self->priv->adjustment, &value, NULL, NULL, NULL, &page_increment, NULL); if (self->priv->orientation == MX_ORIENTATION_VERTICAL) handle_pos = clutter_actor_get_y (self->priv->handle); else handle_pos = clutter_actor_get_x (self->priv->handle); clutter_actor_transform_stage_point (CLUTTER_ACTOR (self->priv->trough), self->priv->move_x, self->priv->move_y, &tx, &ty); if (self->priv->orientation == MX_ORIENTATION_VERTICAL) event_pos = ty; else event_pos = tx; if (event_pos > handle_pos) { if (self->priv->paging_direction == NONE) { /* Remember direction. */ self->priv->paging_direction = DOWN; } if (self->priv->paging_direction == UP) { /* Scrolled far enough. */ return FALSE; } value += page_increment; } else { if (self->priv->paging_direction == NONE) { /* Remember direction. */ self->priv->paging_direction = UP; } if (self->priv->paging_direction == DOWN) { /* Scrolled far enough. */ return FALSE; } value -= page_increment; } mx_adjustment_interpolate (self->priv->adjustment, value, 250, mode); return ret; }
static void mx_scroll_bar_allocate (ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { MxScrollBarPrivate *priv = MX_SCROLL_BAR (actor)->priv; MxPadding padding; ClutterActorBox bw_box, fw_box, trough_box; gfloat x, y, width, height, stepper_size; /* Chain up */ CLUTTER_ACTOR_CLASS (mx_scroll_bar_parent_class)->allocate (actor, box, flags); mx_widget_get_padding (MX_WIDGET (actor), &padding); /* calculate the child area */ x = padding.left; y = padding.top; width = (box->x2 - box->x1) - padding.left - padding.right; height = (box->y2 - box->y1) - padding.top - padding.bottom; if (priv->orientation == MX_ORIENTATION_VERTICAL) { stepper_size = width; /* Backward stepper */ bw_box.x1 = x; bw_box.y1 = y; bw_box.x2 = bw_box.x1 + stepper_size; bw_box.y2 = bw_box.y1 + stepper_size; clutter_actor_allocate (priv->bw_stepper, &bw_box, flags); /* Forward stepper */ fw_box.x1 = x; fw_box.y1 = y + height - stepper_size; fw_box.x2 = fw_box.x1 + stepper_size; fw_box.y2 = fw_box.y1 + stepper_size; clutter_actor_allocate (priv->fw_stepper, &fw_box, flags); /* Trough */ trough_box.x1 = x; trough_box.y1 = y + stepper_size; trough_box.x2 = x + width; trough_box.y2 = y + height - stepper_size; clutter_actor_allocate (priv->trough, &trough_box, flags); } else { stepper_size = height; /* Backward stepper */ bw_box.x1 = x; bw_box.y1 = y; bw_box.x2 = bw_box.x1 + stepper_size; bw_box.y2 = bw_box.y1 + stepper_size; clutter_actor_allocate (priv->bw_stepper, &bw_box, flags); /* Forward stepper */ fw_box.x1 = x + width - stepper_size; fw_box.y1 = y; fw_box.x2 = fw_box.x1 + stepper_size; fw_box.y2 = fw_box.y1 + stepper_size; clutter_actor_allocate (priv->fw_stepper, &fw_box, flags); /* Trough */ trough_box.x1 = x + stepper_size; trough_box.y1 = y; trough_box.x2 = x + width - stepper_size; trough_box.y2 = y + height; clutter_actor_allocate (priv->trough, &trough_box, flags); } if (priv->adjustment) { gfloat handle_size, position, avail_size, handle_pos; gdouble value, lower, upper, page_size, increment; ClutterActorBox handle_box = { 0, }; guint min_size, max_size; mx_adjustment_get_values (priv->adjustment, &value, &lower, &upper, NULL, NULL, &page_size); value = mx_adjustment_get_value (priv->adjustment); if ((upper == lower) || (page_size >= (upper - lower))) increment = 1.0; else increment = page_size / (upper - lower); min_size = priv->handle_min_size; mx_stylable_get (MX_STYLABLE (actor), "mx-max-size", &max_size, NULL); if (upper - lower - page_size <= 0) position = 0; else position = (value - lower) / (upper - lower - page_size); if (priv->orientation == MX_ORIENTATION_VERTICAL) { avail_size = height - stepper_size * 2; handle_size = increment * avail_size; handle_size = CLAMP (handle_size, min_size, max_size); handle_box.x1 = x; handle_pos = bw_box.y2 + position * (avail_size - handle_size); handle_box.y1 = CLAMP (handle_pos, bw_box.y2, fw_box.y1 - min_size); handle_box.x2 = handle_box.x1 + width; handle_box.y2 = CLAMP (handle_pos + handle_size, bw_box.y2 + min_size, fw_box.y1); } else { avail_size = width - stepper_size * 2; handle_size = increment * avail_size; handle_size = CLAMP (handle_size, min_size, max_size); handle_pos = bw_box.x2 + position * (avail_size - handle_size); handle_box.x1 = CLAMP (handle_pos, bw_box.x2, fw_box.x1 - min_size); handle_box.y1 = y; handle_box.x2 = CLAMP (handle_pos + handle_size, bw_box.x2 + min_size, fw_box.x1); handle_box.y2 = handle_box.y1 + height; } /* snap to pixel */ handle_box.x1 = (int) handle_box.x1; handle_box.y1 = (int) handle_box.y1; handle_box.x2 = (int) handle_box.x2; handle_box.y2 = (int) handle_box.y2; clutter_actor_allocate (priv->handle, &handle_box, flags); } }