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);
}
Пример #2
0
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);
}
Пример #3
0
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);
    }
}