示例#1
0
/* GObject stuff */
static void
astro_applet_paint (ClutterActor *applet)
{
  AstroAppletPrivate *priv;
  GList *c;
  gint width = 0;

  g_return_if_fail (ASTRO_IS_APPLET (applet));
  priv = ASTRO_APPLET (applet)->priv;
  
  c = clutter_container_get_children (CLUTTER_CONTAINER (applet));
  
  for (c = c; c; c = c->next)
    {
      gint total = clutter_actor_get_y (c->data) + 
                   clutter_actor_get_width (c->data);
      if (total > width && c->data != priv->texture)
        width = total;
    }
  
  clutter_actor_set_size (priv->texture,
                          width,
                          clutter_actor_get_height (applet));

   c = clutter_container_get_children (CLUTTER_CONTAINER (applet));
   for (c = c; c; c = c->next)
    clutter_actor_paint (c->data);
    
}
示例#2
0
static void
clutter_bin_layout_get_preferred_height (ClutterLayoutManager *manager,
                                         ClutterContainer     *container,
                                         gfloat                for_width,
                                         gfloat               *min_height_p,
                                         gfloat               *nat_height_p)
{
  GList *children = clutter_container_get_children (container);
  GList *l;
  gfloat min_height, nat_height;

  min_height = nat_height = 0.0;

  for (l = children; l != NULL; l = l->next)
    {
      ClutterActor *child = l->data;
      gfloat minimum, natural;

      clutter_actor_get_preferred_height (child, for_width,
                                          &minimum,
                                          &natural);

      min_height = MAX (min_height, minimum);
      nat_height = MAX (nat_height, natural);
    }

  if (min_height_p)
    *min_height_p = min_height;

  if (nat_height_p)
    *nat_height_p = nat_height;
}
示例#3
0
NtfNotification *
ntf_tray_find_notification (NtfTray *tray, gint subsystem, gint id)
{
  NtfTrayPrivate  *priv;
  GList           *notifiers, *l;
  NtfNotification *ntf = NULL;

  g_return_val_if_fail (NTF_IS_TRAY (tray), NULL);

  priv = tray->priv;

  notifiers =
    clutter_container_get_children (CLUTTER_CONTAINER (priv->notifiers));

  for (l = notifiers; l; l = l->next)
    {
      gint s = ntf_notification_get_subsystem (NTF_NOTIFICATION (l->data));
      gint i = ntf_notification_get_id (NTF_NOTIFICATION (l->data));

      if (subsystem == s && id == i)
        {
          ntf = l->data;
          break;
        }
    }

  g_list_free (notifiers);

  return ntf;
}
示例#4
0
static void
ensure_visible (ClutterText *text,
                MxGrid      *grid)
{
  GList *children;
  ClutterActor *child;

  const gchar *string = clutter_text_get_text (text);
  gint number = atoi (string) - 1;

  children = clutter_container_get_children (CLUTTER_CONTAINER (grid));
  child = g_list_nth_data (children, number);
  if (child)
    {
      ClutterGeometry geom;
      MxScrollView *scroll = (MxScrollView *)
        clutter_actor_get_parent (CLUTTER_ACTOR (grid));
      clutter_actor_get_allocation_geometry (child, &geom);
      mx_scroll_view_ensure_visible (scroll, &geom);
      printf ("Making child %d visible\n", number);
    }
  else
    printf ("Couldn't make child %d visible\n", number);
  g_list_free (children);
}
示例#5
0
/**
 * mex_menu_clear_all:
 * @menu: A #MexMenu
 *
 * Removes all items from the menu.
 */
void
mex_menu_clear_all (MexMenu *menu)
{
  gboolean direction;
  GList *l, *children;
  MexMenuPrivate *priv;

  g_return_if_fail (MEX_IS_MENU (menu));

  priv = menu->priv;

  if (priv->depth == 0)
    return;

  children = clutter_container_get_children (CLUTTER_CONTAINER (menu));
  direction = (priv->depth >= 0);

  for (l = g_list_find (children, clutter_actor_get_parent (priv->layout)); l;
       l = direction ? l->next : l->prev)
    {
      ClutterActor *child = l->data;
      clutter_container_remove_actor (CLUTTER_CONTAINER (menu), child);
      if (--priv->depth == 0)
        break;
    }

  g_list_free (children);

  priv->layout = mex_menu_create_layout (menu, FALSE);

  g_object_notify (G_OBJECT (menu), "depth");
}
示例#6
0
static void
shell_overflow_list_get_preferred_height (ClutterActor *actor,
                                          gfloat for_width,
                                          gfloat *min_height_p,
                                          gfloat *natural_height_p)
{
  ShellOverflowList *self = SHELL_OVERFLOW_LIST (actor);
  ShellOverflowListPrivate *priv = self->priv;
  GList *children;

  if (min_height_p)
    *min_height_p = 0;

  if (natural_height_p)
    {
      int n_children;
      children = clutter_container_get_children (CLUTTER_CONTAINER (self));
      n_children = g_list_length (children);
      if (n_children == 0)
        *natural_height_p = 0;
      else
        *natural_height_p = (n_children - 1) * (priv->item_height + priv->spacing) + priv->item_height;
      g_list_free (children);
    }
}
示例#7
0
void
mex_menu_set_min_width (MexMenu *menu,
                        gfloat   min_width)
{
  MexMenuPrivate *priv;

  g_return_if_fail (MEX_IS_MENU (menu));

  priv = menu->priv;
  if (priv->min_width != min_width)
    {
      gint depth;
      gboolean direction;
      GList *l, *children;

      priv->min_width = min_width;

      children = clutter_container_get_children (CLUTTER_CONTAINER (menu));
      direction = (priv->depth >= 0);
      depth = priv->depth;

      for (l = g_list_find (children, clutter_actor_get_parent (priv->layout));
           l; l = direction ? l->next : l->prev)
        {
          g_object_set (G_OBJECT (l->data),
                        "min-width", priv->min_width, NULL);
          if (--depth == 0)
            break;
        }

      g_list_free (children);

      g_object_notify (G_OBJECT (menu), "min-menu-width");
    }
}
示例#8
0
static void
key_group_paint (ClutterActor *actor)
{
  KeyGroup *self = KEY_GROUP (actor);
  GList *children, *l;
  gint i;

  children = clutter_container_get_children (CLUTTER_CONTAINER (self));

  for (l = children, i = 0; l != NULL; l = l->next, i++)
    {
      ClutterActor *child = l->data;

      /* paint the selection rectangle */
      if (i == self->selected_index)
        {
          ClutterActorBox box = { 0, };

          clutter_actor_get_allocation_box (child, &box);

          box.x1 -= 2;
          box.y1 -= 2;
          box.x2 += 2;
          box.y2 += 2;

          cogl_set_source_color4ub (255, 255, 0, 224);
          cogl_rectangle (box.x1, box.y1, box.x2, box.y2);
        }

      clutter_actor_paint (child);
    }

  g_list_free (children);
}
示例#9
0
static void bar_pane_gps_update(PaneGPSData *pgd)
{
	GList *list;
	GList *work;

	/* The widget does not have a parent during bar_pane_gps_new, so calling gtk_widget_show_all there gives a
	 * "Gtk-CRITICAL **: gtk_widget_realize: assertion `GTK_WIDGET_ANCHORED (widget) || GTK_IS_INVISIBLE (widget)' failed"
	 * error. gtk_widget_show_all can be given after it has been added to the bar.
	 */
	if (gtk_widget_get_parent(pgd->widget) != NULL)
		gtk_widget_show_all(pgd->widget);

	/* If a create-marker background process is running, kill it
	 * and start again
	 */
	if (pgd->create_markers_id != 0)
		{
		if (g_idle_remove_by_data(pgd))
			{
			pgd->create_markers_id = 0;
			}
		else
			{
			return;
			}		
		}

	/* Delete any markers currently displayed
	 */
	work = clutter_container_get_children(CLUTTER_CONTAINER(pgd->icon_layer));
	while (work)
		{
		clutter_container_remove(CLUTTER_CONTAINER(pgd->icon_layer), work->data, NULL);
		work = work->next;
		}
	g_list_free(work);

	if (!pgd->enable_markers_checked)
		{
		return;
		}

	/* For each selected photo that has GPS data, create a marker containing
	 * a single, small text character the same colour as the marker background.
	 * Use a background process in case the user selects a large number of files.
	 */
	list = layout_selection_list(pgd->pane.lw);
	list = file_data_process_groups_in_selection(list, FALSE, NULL);

	if (list != NULL)
		{
		pgd->selection_list = g_list_copy(list);
		pgd->marker_list = g_ptr_array_new();
		pgd->selection_count = g_list_length(pgd->selection_list);
		pgd->create_markers_id = g_idle_add(bar_pane_gps_create_markers_cb, pgd);
		}

	g_list_free(list);
	g_list_free(work);
}
static MxFocusable *
mx_stack_accept_focus (MxFocusable *focusable, MxFocusHint hint)
{
  GList *c, *children;
  MxStackPrivate *priv = MX_STACK (focusable)->priv;
  ClutterContainer *container = CLUTTER_CONTAINER (focusable);

  focusable = NULL;

  switch (hint)
    {
    default:
    case MX_FOCUS_HINT_PRIOR:
      if (priv->current_focus &&
          (!MX_IS_WIDGET (priv->current_focus) ||
           !mx_widget_get_disabled ((MxWidget *)priv->current_focus)))
        {
          focusable =
            mx_focusable_accept_focus (MX_FOCUSABLE (priv->current_focus),
                                       hint);
          if (focusable)
            break;
        }
      /* This purposefully runs into the next case statement */

    case MX_FOCUS_HINT_FIRST:
    case MX_FOCUS_HINT_LAST:
      children = clutter_container_get_children (container);
      if (hint == MX_FOCUS_HINT_LAST)
        children = g_list_reverse (children);

      if (children)
        {
          c = children;
          while (c && !focusable)
            {
              ClutterActor *child = c->data;
              c = c->next;

              if (!MX_IS_FOCUSABLE (child))
                continue;

              if (MX_IS_WIDGET (child) &&
                  mx_widget_get_disabled ((MxWidget *)child))
                continue;

              priv->current_focus = child;
              focusable = mx_focusable_accept_focus (MX_FOCUSABLE (child),
                                                     hint);
            }
          g_list_free (children);
        }
      break;
    }

  return focusable;
}
示例#11
0
static void
mex_shell_destroy (ClutterActor *actor)
{
  GList *children = clutter_container_get_children (CLUTTER_CONTAINER (actor));

  g_list_foreach (children, (GFunc)clutter_actor_destroy, NULL);
  g_list_free (children);

  if (CLUTTER_ACTOR_CLASS (mex_shell_parent_class)->destroy)
    CLUTTER_ACTOR_CLASS (mex_shell_parent_class)->destroy (actor);
}
示例#12
0
static void
clutter_bin_layout_allocate (ClutterLayoutManager   *manager,
                             ClutterContainer       *container,
                             const ClutterActorBox  *allocation,
                             ClutterAllocationFlags  flags)
{
  GList *children = clutter_container_get_children (container);
  GList *l;
  gfloat available_w, available_h;

  available_w = clutter_actor_box_get_width (allocation);
  available_h = clutter_actor_box_get_height (allocation);

  for (l = children; l != NULL; l = l->next)
    {
      ClutterActor *child = l->data;
      ClutterLayoutMeta *meta;
      ClutterBinLayer *layer;
      ClutterActorBox child_alloc = { 0, };
      gdouble x_align, y_align;
      gboolean x_fill, y_fill;

      meta = clutter_layout_manager_get_child_meta (manager,
                                                    container,
                                                    child);
      layer = CLUTTER_BIN_LAYER (meta);

      if (layer->x_align == CLUTTER_BIN_ALIGNMENT_FIXED)
        child_alloc.x1 = clutter_actor_get_x (child);
      else
        child_alloc.x1 = 0.0f;

      if (layer->y_align == CLUTTER_BIN_ALIGNMENT_FIXED)
        child_alloc.y1 = clutter_actor_get_y (child);
      else
        child_alloc.y1 = 0.0f;

      child_alloc.x2 = available_w;
      child_alloc.y2 = available_h;

      x_fill = (layer->x_align == CLUTTER_BIN_ALIGNMENT_FILL);
      y_fill = (layer->y_align == CLUTTER_BIN_ALIGNMENT_FILL);
      x_align = get_bin_alignment_factor (layer->x_align);
      y_align = get_bin_alignment_factor (layer->y_align);

      clutter_actor_allocate_align_fill (child, &child_alloc,
                                         x_align, y_align,
                                         x_fill, y_fill,
                                         flags);
    }

  g_list_free (children);
}
示例#13
0
static void
shell_overflow_list_get_preferred_width (ClutterActor *actor,
                                         gfloat for_height,
                                         gfloat *min_width_p,
                                         gfloat *natural_width_p)
{
  ShellOverflowList *self = SHELL_OVERFLOW_LIST (actor);
  gboolean first = TRUE;
  float min = 0, natural = 0;
  GList *iter;
  GList *children;

  children = clutter_container_get_children (CLUTTER_CONTAINER (self));

  for (iter = children; iter; iter = iter->next)
    {
      ClutterActor *child = iter->data;
      float child_min, child_natural;

      clutter_actor_get_preferred_width (child,
                                         for_height,
                                         &child_min,
                                         &child_natural);

      if (first)
        {
          first = FALSE;
          min = child_min;
          natural = child_natural;
        }
      else
        {
          if (child_min > min)
            min = child_min;

          if (child_natural > natural)
            natural = child_natural;
        }
    }

  if (min_width_p)
    *min_width_p = min;

  if (natural_width_p)
    *natural_width_p = natural;
  g_list_free (children);
}
示例#14
0
static void
ntf_tray_dismiss_all_cb (ClutterActor *button, NtfTray *tray)
{
  NtfTrayPrivate *priv = tray->priv;
  GList *child, *children;

  clutter_actor_hide (CLUTTER_ACTOR (tray));

  child = children =
    clutter_container_get_children (CLUTTER_CONTAINER (priv->notifiers));
  while (child != NULL)
    {
      g_signal_emit_by_name (child->data, "closed", 0);
      child = child->next;
    }

  g_list_free (children);
}
示例#15
0
/**
 * test_conform_simple_fixture_setup:
 *
 * Initialise stuff before each test is run
 */
void
test_conform_simple_fixture_setup (TestConformSimpleFixture *fixture,
				   gconstpointer data)
{
  /* const TestConformSharedState *shared_state = data; */
  ClutterActor *stage = clutter_stage_get_default ();
  GList *actors = clutter_container_get_children (CLUTTER_CONTAINER (stage));
  GList *tmp;

  /* To help reduce leakage between unit tests, we destroy all children of the stage */
  for (tmp = actors; tmp != NULL; tmp = tmp->next)
    {
      ClutterActor *leaked_actor = tmp->data;
      
      if (g_test_verbose ())
	g_print ("Freeing leaked actor %p\n", leaked_actor);
      clutter_actor_destroy (leaked_actor);
    }
}
示例#16
0
/**
 * mex_menu_push:
 * @menu: A #MexMenu
 *
 * Increments the current depth of the menu. If the current depth is %0,
 * or positive, this will add a new menu level. If the depth is negative,
 * this will remove a menu level.
 *
 * Returns: The new menu depth
 */
gint
mex_menu_push (MexMenu *menu)
{
  MexMenuPrivate *priv;

  g_return_val_if_fail (MEX_IS_MENU (menu), 0);

  priv = menu->priv;
  if (priv->depth < 0)
    {
      GList *l;
      GList *children =
        clutter_container_get_children (CLUTTER_CONTAINER (menu));

      l = g_list_find (children, clutter_actor_get_parent (priv->layout));
      priv->layout = l->next->data;
      priv->action_layout = g_object_get_data (G_OBJECT (priv->layout),
                                               "action-layout");
      clutter_container_remove_actor (CLUTTER_CONTAINER (menu),
                                      CLUTTER_ACTOR (l->data));
      g_list_free (children);

      priv->depth ++;
      priv->focus_on_add = priv->has_focus;
      mex_menu_uncheck_buttons (menu);
    }
  else
    {
      priv->depth ++;
      priv->layout = mex_menu_create_layout (menu, FALSE);
      g_object_set_qdata (G_OBJECT (priv->layout),
                          mex_menu_depth_quark,
                          GINT_TO_POINTER (priv->depth));

      if (priv->has_focus)
        priv->focus_on_add = TRUE;
    }

  g_object_notify (G_OBJECT (menu), "depth");

  return priv->depth;
}
示例#17
0
/**
 * clutter_container_find_child_by_name:
 * @container: a #ClutterContainer
 * @child_name: the name of the requested child.
 *
 * Finds a child actor of a container by its name. Search recurses
 * into any child container.
 *
 * Return value: (transfer none): The child actor with the requested name,
 *   or %NULL if no actor with that name was found.
 *
 * Since: 0.6
 */
ClutterActor *
clutter_container_find_child_by_name (ClutterContainer *container,
                                      const gchar      *child_name)
{
  GList        *children;
  GList        *iter;
  ClutterActor *actor = NULL;

  g_return_val_if_fail (CLUTTER_IS_CONTAINER (container), NULL);
  g_return_val_if_fail (child_name != NULL, NULL);

  children = clutter_container_get_children (container);

  for (iter = children; iter; iter = g_list_next (iter))
    {
      ClutterActor *a;
      const gchar  *iter_name;

      a = CLUTTER_ACTOR (iter->data);
      iter_name = clutter_actor_get_name (a);

      if (iter_name && !strcmp (iter_name, child_name))
        {
          actor = a;
          break;
        }

      if (CLUTTER_IS_CONTAINER (a))
        {
          ClutterContainer *c = CLUTTER_CONTAINER (a);

          actor = clutter_container_find_child_by_name (c, child_name);
          if (actor)
            break;
	}
    }

  g_list_free (children);

  return actor;
}
示例#18
0
void
shell_overflow_list_paint (ClutterActor *actor)
{
  ShellOverflowList *self = SHELL_OVERFLOW_LIST (actor);
  ShellOverflowListPrivate *priv = self->priv;
  GList *children, *iter;
  int i;

  children = clutter_container_get_children (CLUTTER_CONTAINER (self));

  if (children == NULL)
    return;

  iter = g_list_nth (children, (priv->page) * priv->items_per_page);

  i = 0;
  for (;iter && i < priv->items_per_page; iter = iter->next, i++)
    {
      ClutterActor *actor = CLUTTER_ACTOR (iter->data);

      clutter_actor_paint (actor);
    }
  g_list_free (children);
}
示例#19
0
void
mex_media_controls_focus_content (MexMediaControls *self,
                                  MexContent       *content)
{
    MexMediaControlsPrivate *priv = self->priv;
    ClutterContainer *container;
    GList *children, *l;

    container = CLUTTER_CONTAINER (clutter_script_get_object (priv->script,
                                   "related-box"));

    children = clutter_container_get_children (container);

    for (l = children; l; l = g_list_next (l))
    {
        if (mex_content_view_get_content (l->data) == content)
        {
            mex_push_focus (l->data);
            return;
        }
    }

    return;
}
示例#20
0
static void
mex_menu_uncheck_buttons (MexMenu *menu)
{
  GList *children;

  MexMenuPrivate *priv = menu->priv;

  children = clutter_container_get_children (CLUTTER_CONTAINER (priv->action_layout));
  while (children)
    {
      if (g_object_get_qdata (children->data, mex_menu_item_quark))
        {
          mx_button_set_toggled (MX_BUTTON (children->data), FALSE);

          if (priv->focus_on_add)
            {
              mex_push_focus (MX_FOCUSABLE (children->data));
              priv->focus_on_add = FALSE;
            }
        }

      children = g_list_delete_link (children, children);
    }
}
示例#21
0
文件: compositor.c 项目: nkoep/muffin
static void
sync_actor_stacking (MetaCompScreen *info)
{
    GList *children;
    GList *tmp;
    GList *old;
    gboolean reordered;

    /* NB: The first entries in the lists are stacked the lowest */

    /* Restacking will trigger full screen redraws, so it's worth a
     * little effort to make sure we actually need to restack before
     * we go ahead and do it */

    children = clutter_container_get_children (CLUTTER_CONTAINER (info->window_group));
    reordered = FALSE;

    old = children;

    /* We allow for actors in the window group other than the actors we
     * know about, but it's up to a plugin to try and keep them stacked correctly
     * (we really need extra API to make that reliable.)
     */

    /* Of the actors we know, the bottom actor should be the background actor */

    while (old && old->data != info->background_actor && !META_IS_WINDOW_ACTOR (old->data))
        old = old->next;
    if (old == NULL || old->data != info->background_actor)
    {
        reordered = TRUE;
        goto done_with_check;
    }

    /* Then the window actors should follow in sequence */

    old = old->next;
    for (tmp = info->windows; tmp != NULL; tmp = tmp->next)
    {
        while (old && !META_IS_WINDOW_ACTOR (old->data))
            old = old->next;

        /* old == NULL: someone reparented a window out of the window group,
         * order undefined, always restack */
        if (old == NULL || old->data != tmp->data)
        {
            reordered = TRUE;
            goto done_with_check;
        }

        old = old->next;
    }

done_with_check:

    g_list_free (children);

    if (!reordered)
        return;

    for (tmp = g_list_last (info->windows); tmp != NULL; tmp = tmp->prev)
    {
        MetaWindowActor *window_actor = tmp->data;

        clutter_actor_lower_bottom (CLUTTER_ACTOR (window_actor));
    }

    clutter_actor_lower_bottom (info->background_actor);
}
示例#22
0
static void
ntf_tray_notification_closed_cb (NtfNotification *ntf, NtfTray *tray)
{
  NtfTrayPrivate   *priv = tray->priv;
  ClutterActor     *ntfa = CLUTTER_ACTOR (ntf);
  ClutterAnimation *anim;

  priv->n_notifiers--;

  if (priv->n_notifiers < 0)
    {
      g_warning ("Bug in notifier accounting, attempting to fix");
      priv->n_notifiers = 0;
    }

  /* fade out closed notifier */
  if (ntfa == priv->active_notifier)
    {
      anim = clutter_actor_animate (CLUTTER_ACTOR (ntfa),
                                    CLUTTER_EASE_IN_SINE,
                                    FADE_DURATION,
                                    "opacity", 0,
                                    NULL);

      g_signal_connect_after (anim,
                        "completed",
                        G_CALLBACK
                        (ntf_tray_hide_ntf_completed_cb),
                        tray);
    }
  else
    {
      clutter_actor_destroy (ntfa);
    }

  /* Fade in newer notifier from below stack */
  if (ntfa == priv->active_notifier && priv->n_notifiers > 0)
    {
      gint prev_height, new_height;
      GList *notifiers;

      prev_height = clutter_actor_get_height (ntfa);

      notifiers =
        clutter_container_get_children (CLUTTER_CONTAINER (priv->notifiers));

      priv->active_notifier = notifiers->next != NULL ?
        (ClutterActor *) notifiers->next->data : NULL;

      g_list_free (notifiers);

      if (priv->active_notifier)
        {
          clutter_actor_set_opacity (priv->active_notifier, 0);
          clutter_actor_show (CLUTTER_ACTOR (priv->active_notifier));
          clutter_actor_animate (CLUTTER_ACTOR (priv->active_notifier),
                                 CLUTTER_EASE_IN_SINE,
                                 FADE_DURATION,
                                 "opacity", 0xff,
                                 NULL);

          new_height = clutter_actor_get_height (priv->active_notifier);

          if (prev_height != new_height && priv->n_notifiers > 1)
            {
              gfloat new_y;

              new_y = clutter_actor_get_y (priv->control)
                - (prev_height - new_height);

              clutter_actor_animate (priv->control,
                                     CLUTTER_EASE_IN_SINE,
                                     FADE_DURATION,
                                     "y", new_y,
                                     NULL);
            }
        }
    }

  if (priv->n_notifiers == 0)
    {
      priv->active_notifier = NULL;
#pragma TODO
      /* mnb_notification_gtk_hide (); */
    }
  else if (priv->n_notifiers == 1)
    {
      /* slide the control out of view */
      ClutterAnimation *anim;

      anim = clutter_actor_animate (priv->control,
                                    CLUTTER_EASE_IN_SINE,
                                    FADE_DURATION,
                                    "opacity", 0x0,
                                    "y",
                                    clutter_actor_get_height (priv->active_notifier)
                                    - clutter_actor_get_height (priv->control),
                                    NULL);

      g_signal_connect_after (anim,
                        "completed",
                        G_CALLBACK
                        (ntf_tray_control_hide_completed_cb),
                        tray);
    }
  else
    {
      /* Just Update control text */
      gchar *msg;
      msg = g_strdup_printf (_("%i pending messages"), priv->n_notifiers);
      mx_label_set_text (MX_LABEL (priv->control_text), msg);
      g_free (msg);
    }
}
示例#23
0
static void
shell_overflow_list_allocate (ClutterActor           *actor,
                              const ClutterActorBox  *box,
                              ClutterAllocationFlags  flags)
{
  ShellOverflowList *self = SHELL_OVERFLOW_LIST (actor);
  ShellOverflowListPrivate *priv = self->priv;
  GList *children, *iter;
  int n_pages;
  int n_children;
  int n_fits;
  float width;
  float curheight;
  float avail_height;
  gboolean overflow;

  /* chain up to set actor->allocation */
  (CLUTTER_ACTOR_CLASS (g_type_class_peek (clutter_actor_get_type ())))->allocate (actor, box, flags);

  width = box->x2 - box->x1;
  curheight = 0;
  avail_height = box->y2 - box->y1;

  children = clutter_container_get_children (CLUTTER_CONTAINER (self));
  n_children = g_list_length (children);

  n_fits = 0;
  n_pages = 1;
  overflow = FALSE;
  for (iter = children; iter; iter = iter->next)
    {
      ClutterActor *actor = CLUTTER_ACTOR (iter->data);
      ClutterActorBox child_box;

      if ((curheight + priv->item_height) > avail_height)
        {
          overflow = TRUE;
          curheight = 0;
          n_pages++;
        }
      else if (!overflow)
        n_fits++;

      child_box.x1 = 0;
      child_box.x2 = width;
      child_box.y1 = curheight;
      child_box.y2 = child_box.y1 + priv->item_height;
      clutter_actor_allocate (actor, &child_box, flags);

      curheight += priv->item_height;
      if (iter != children)
        curheight += priv->spacing;
    }

  priv->items_per_page = n_fits;
  if (n_pages != priv->n_pages)
    {
      priv->n_pages = n_pages;
      g_object_notify (G_OBJECT (self), "n-pages");
    }

  g_list_free (children);
}
示例#24
0
static void
clutter_flow_layout_allocate (ClutterLayoutManager   *manager,
                              ClutterContainer       *container,
                              const ClutterActorBox  *allocation,
                              ClutterAllocationFlags  flags)
{
  ClutterFlowLayoutPrivate *priv = CLUTTER_FLOW_LAYOUT (manager)->priv;
  GList *l, *children = clutter_container_get_children (container);
  gfloat avail_width, avail_height;
  gfloat item_x, item_y;
  gint line_item_count;
  gint items_per_line;
  gint line_index;

  if (children == NULL)
    return;

  clutter_actor_box_get_size (allocation, &avail_width, &avail_height);

  items_per_line = compute_lines (CLUTTER_FLOW_LAYOUT (manager),
                                  avail_width, avail_height);

  item_x = item_y = 0;

  line_item_count = 0;
  line_index = 0;

  for (l = children; l != NULL; l = l->next)
    {
      ClutterActor *child = l->data;
      ClutterActorBox child_alloc;
      gfloat item_width, item_height;
      gfloat new_x, new_y;

      if (!CLUTTER_ACTOR_IS_VISIBLE (child))
        continue;

      new_x = new_y = 0;

      if (priv->orientation == CLUTTER_FLOW_HORIZONTAL)
        {
          if (line_item_count == items_per_line && line_item_count > 0)
            {
              item_y += g_array_index (priv->line_natural,
                                       gfloat,
                                       line_index);

              if (line_index >= 0)
                item_y += priv->row_spacing;

              line_item_count = 0;
              line_index += 1;

              item_x = 0;
            }

          new_x = ((line_item_count + 1) * (avail_width + priv->col_spacing))
                / items_per_line;
          item_width = new_x - item_x - priv->col_spacing;
          item_height = g_array_index (priv->line_natural,
                                       gfloat,
                                       line_index);

          if (!priv->is_homogeneous)
            {
              gfloat child_min, child_natural;

              clutter_actor_get_preferred_width (child, item_height,
                                                 &child_min,
                                                 &child_natural);
              item_width = MIN (item_width, child_natural);

              clutter_actor_get_preferred_height (child, item_width,
                                                  &child_min,
                                                  &child_natural);
              item_height = MIN (item_height, child_natural);
            }
        }
      else
        {
          if (line_item_count == items_per_line && line_item_count > 0)
            {
              item_x += g_array_index (priv->line_natural,
                                       gfloat,
                                       line_index);

              if (line_index >= 0)
                item_x += priv->col_spacing;

              line_item_count = 0;
              line_index += 1;

              item_y = 0;
            }

          new_y = ((line_item_count + 1) * (avail_height + priv->row_spacing))
                / items_per_line;
          item_height = new_y - item_y - priv->row_spacing;
          item_width = g_array_index (priv->line_natural,
                                      gfloat,
                                      line_index);

          if (!priv->is_homogeneous)
            {
              gfloat child_min, child_natural;

              clutter_actor_get_preferred_width (child, item_height,
                                                 &child_min,
                                                 &child_natural);
              item_width = MIN (item_width, child_natural);

              clutter_actor_get_preferred_height (child, item_width,
                                                  &child_min,
                                                  &child_natural);
              item_height = MIN (item_height, child_natural);
            }
        }

      CLUTTER_NOTE (LAYOUT,
                    "flow[line:%d, item:%d/%d] ="
                    "{ %.2f, %.2f, %.2f, %.2f }",
                    line_index, line_item_count + 1, items_per_line,
                    item_x, item_y, item_width, item_height);

      child_alloc.x1 = ceil (item_x);
      child_alloc.y1 = ceil (item_y);
      child_alloc.x2 = ceil (child_alloc.x1 + item_width);
      child_alloc.y2 = ceil (child_alloc.y1 + item_height);
      clutter_actor_allocate (child, &child_alloc, flags);

      if (priv->orientation == CLUTTER_FLOW_HORIZONTAL)
        item_x = new_x;
      else
        item_y = new_y;

      line_item_count += 1;
    }

  g_list_free (children);
}
示例#25
0
static void
clutter_flow_layout_get_preferred_height (ClutterLayoutManager *manager,
                                          ClutterContainer     *container,
                                          gfloat                for_width,
                                          gfloat               *min_height_p,
                                          gfloat               *nat_height_p)
{
  ClutterFlowLayoutPrivate *priv = CLUTTER_FLOW_LAYOUT (manager)->priv;
  GList *l, *children = clutter_container_get_children (container);
  gint n_columns, line_item_count, line_count;
  gfloat total_min_height, total_natural_height;
  gfloat line_min_height, line_natural_height;
  gfloat max_min_height, max_natural_height;
  gfloat item_x;

  n_columns = get_columns (CLUTTER_FLOW_LAYOUT (manager), for_width);

  total_min_height = 0;
  total_natural_height = 0;

  line_min_height = 0;
  line_natural_height = 0;

  line_item_count = 0;
  line_count = 0;

  item_x = 0;

  /* clear the line height arrays */
  if (priv->line_min != NULL)
    g_array_free (priv->line_min, TRUE);

  if (priv->line_natural != NULL)
    g_array_free (priv->line_natural, TRUE);

  priv->line_min = g_array_sized_new (FALSE, FALSE,
                                      sizeof (gfloat),
                                      16);
  priv->line_natural = g_array_sized_new (FALSE, FALSE,
                                          sizeof (gfloat),
                                          16);

  if (children)
    line_count = 1;

  max_min_height = max_natural_height = 0;

  for (l = children; l != NULL; l = l->next)
    {
      ClutterActor *child = l->data;
      gfloat child_min, child_natural;
      gfloat new_x, item_width;

      if (!CLUTTER_ACTOR_IS_VISIBLE (child))
        continue;

      if (priv->orientation == CLUTTER_FLOW_HORIZONTAL && for_width > 0)
        {
          if (line_item_count == n_columns)
            {
              total_min_height += line_min_height;
              total_natural_height += line_natural_height;

              g_array_append_val (priv->line_min,
                                  line_min_height);
              g_array_append_val (priv->line_natural,
                                  line_natural_height);

              line_min_height = line_natural_height = 0;

              line_item_count = 0;
              line_count += 1;
              item_x = 0;
            }

          new_x = ((line_item_count + 1) * (for_width + priv->col_spacing))
                / n_columns;
          item_width = new_x - item_x - priv->col_spacing;

          clutter_actor_get_preferred_height (child, item_width,
                                              &child_min,
                                              &child_natural);

          line_min_height = MAX (line_min_height, child_min);
          line_natural_height = MAX (line_natural_height, child_natural);

          item_x = new_x;
          line_item_count += 1;

          max_min_height = MAX (max_min_height, line_min_height);
          max_natural_height = MAX (max_natural_height, line_natural_height);
        }
      else
        {
          clutter_actor_get_preferred_height (child, for_width,
                                              &child_min,
                                              &child_natural);

          max_min_height = MAX (max_min_height, child_min);
          max_natural_height = MAX (max_natural_height, child_natural);

          total_min_height += max_min_height;
          total_natural_height += max_natural_height;

          line_count += 1;
        }
    }

  g_list_free (children);

  priv->row_height = max_natural_height;

  if (priv->max_row_height > 0 && priv->row_height > priv->max_row_height)
    priv->row_height = MAX (priv->max_row_height, max_min_height);

  if (priv->row_height < priv->min_row_height)
    priv->row_height = priv->min_row_height;

  if (priv->orientation == CLUTTER_FLOW_HORIZONTAL && for_width > 0)
    {
      /* if we have a non-full row we need to add it */
      if (line_item_count > 0)
        {
          total_min_height += line_min_height;
          total_natural_height += line_natural_height;

          g_array_append_val (priv->line_min,
                              line_min_height);
          g_array_append_val (priv->line_natural,
                              line_natural_height);
        }

      priv->line_count = line_count;
      if (priv->line_count > 0)
        {
          gfloat total_spacing;

          total_spacing = priv->row_spacing * (priv->line_count - 1);

          total_min_height += total_spacing;
          total_natural_height += total_spacing;
        }
    }
  else
    {
      g_array_append_val (priv->line_min, line_min_height);
      g_array_append_val (priv->line_natural, line_natural_height);

      priv->line_count = line_count;

      if (priv->line_count > 0)
        {
          gfloat total_spacing;

          total_spacing = priv->col_spacing * priv->line_count;

          total_min_height += total_spacing;
          total_natural_height += total_spacing;
        }
    }

  CLUTTER_NOTE (LAYOUT,
                "Flow[h]: %d lines (%d per line): w [ %.2f, %.2f ] for h %.2f",
                n_columns, priv->line_count,
                total_min_height,
                total_natural_height,
                for_width);

  if (min_height_p)
    *min_height_p = total_min_height;

  if (nat_height_p)
    *nat_height_p = total_natural_height;
}
示例#26
0
static void
meta_window_group_paint (ClutterActor *actor)
{
  cairo_region_t *visible_region;
  cairo_region_t *unredirected_window_region = NULL;
  ClutterActor *stage;
  cairo_rectangle_int_t visible_rect, unredirected_rect;
  GList *children, *l;

  MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
  MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen);
  if (info->unredirected_window != NULL)
    {
      meta_window_actor_get_shape_bounds (META_WINDOW_ACTOR (info->unredirected_window), &unredirected_rect);
      unredirected_window_region = cairo_region_create_rectangle (&unredirected_rect);
    }

  /* We walk the list from top to bottom (opposite of painting order),
   * and subtract the opaque area of each window out of the visible
   * region that we pass to the windows below.
   */
  children = clutter_container_get_children (CLUTTER_CONTAINER (actor));
  children = g_list_reverse (children);

  /* Get the clipped redraw bounds from Clutter so that we can avoid
   * painting shadows on windows that don't need to be painted in this
   * frame. In the case of a multihead setup with mismatched monitor
   * sizes, we could intersect this with an accurate union of the
   * monitors to avoid painting shadows that are visible only in the
   * holes. */
  stage = clutter_actor_get_stage (actor);
  clutter_stage_get_redraw_clip_bounds (CLUTTER_STAGE (stage),
                                        &visible_rect);

  visible_region = cairo_region_create_rectangle (&visible_rect);

  if (unredirected_window_region)
    cairo_region_subtract (visible_region, unredirected_window_region);

  for (l = children; l; l = l->next)
    {
      if (!CLUTTER_ACTOR_IS_VISIBLE (l->data))
        continue;

      /* If an actor has effects applied, then that can change the area
       * it paints and the opacity, so we no longer can figure out what
       * portion of the actor is obscured and what portion of the screen
       * it obscures, so we skip the actor.
       *
       * This has a secondary beneficial effect: if a ClutterOffscreenEffect
       * is applied to an actor, then our clipped redraws interfere with the
       * caching of the FBO - even if we only need to draw a small portion
       * of the window right now, ClutterOffscreenEffect may use other portions
       * of the FBO later. So, skipping actors with effects applied also
       * prevents these bugs.
       *
       * Theoretically, we should check clutter_actor_get_offscreen_redirect()
       * as well for the same reason, but omitted for simplicity in the
       * hopes that no-one will do that.
       */
      if (clutter_actor_has_effects (l->data))
        continue;

      if (META_IS_WINDOW_ACTOR (l->data))
        {
          MetaWindowActor *window_actor = l->data;
          int x, y;

          if (!actor_is_untransformed (CLUTTER_ACTOR (window_actor), &x, &y))
            continue;

          /* Temporarily move to the coordinate system of the actor */
          cairo_region_translate (visible_region, - x, - y);

          meta_window_actor_set_visible_region (window_actor, visible_region);

          if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (window_actor)) == 0xff)
            {
              cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (window_actor);
              if (obscured_region)
                cairo_region_subtract (visible_region, obscured_region);
            }

          meta_window_actor_set_visible_region_beneath (window_actor, visible_region);
          cairo_region_translate (visible_region, x, y);
        }
      else if (META_IS_BACKGROUND_ACTOR (l->data))
        {
          MetaBackgroundActor *background_actor = l->data;
          meta_background_actor_set_visible_region (background_actor, visible_region);
        }
    }

  cairo_region_destroy (visible_region);

  if (unredirected_window_region)
    cairo_region_destroy (unredirected_window_region);

  CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor);

  /* Now that we are done painting, unset the visible regions (they will
   * mess up painting clones of our actors)
   */
  for (l = children; l; l = l->next)
    {
      if (META_IS_WINDOW_ACTOR (l->data))
        {
          MetaWindowActor *window_actor = l->data;
          window_actor = l->data;
          meta_window_actor_reset_visible_regions (window_actor);
        }
      else if (META_IS_BACKGROUND_ACTOR (l->data))
        {
          MetaBackgroundActor *background_actor = l->data;
          meta_background_actor_set_visible_region (background_actor, NULL);
        }
    }

  g_list_free (children);
}
示例#27
0
static gboolean
manipulate_lasso_capture (ClutterActor *stage,
                          ClutterEvent *event,
                          gpointer      data)
{
  switch (event->any.type)
    {
      case CLUTTER_MOTION:
        {
          gfloat ex=event->motion.x;
          gfloat ey=event->motion.y;

          gint mx = MIN (ex, lx);
          gint my = MIN (ey, ly);
          gint mw = MAX (ex, lx) - mx;
          gint mh = MAX (ey, ly) - my;

          clutter_actor_set_position (lasso, mx - LASSO_BORDER, my - LASSO_BORDER);
          clutter_actor_set_size (lasso, mw + LASSO_BORDER*2, mh+LASSO_BORDER*2);

          manipulate_x=ex;
          manipulate_y=ey;

          {
            gint no;
            GList *j, *list;
            g_hash_table_remove_all (selection);
            list = clutter_container_get_children (CLUTTER_CONTAINER (cs_get_current_container ()));

            for (no = 0, j=list; j;no++,j=j->next)
              {
                gfloat cx, cy;
                gfloat cw, ch;
                clutter_actor_get_transformed_position (j->data, &cx, &cy);
                clutter_actor_get_transformed_size (j->data, &cw, &ch);

                if (contains (mx, mx + mw, cx, cx + cw) &&
                    contains (my, my + mh, cy, cy + ch))
                  {
                    g_hash_table_insert (selection, j->data, j->data);
                  }
              }
            g_list_free (list);
          }
        }
        break;
      case CLUTTER_BUTTON_RELEASE:
         {
          ClutterModifierType state = event->button.modifier_state;
          GHashTableIter      iter;
          gpointer            key, value;

          g_hash_table_iter_init (&iter, selection);
          while (g_hash_table_iter_next (&iter, &key, &value))
            {
              if (state & CLUTTER_CONTROL_MASK)
                {
                  if (cs_selected_has_actor (key))
                    cs_selected_remove (key);
                  else
                    cs_selected_add (key);
                }
              else
                {
                  cs_selected_add (key);
                }
            }
        }
        g_hash_table_remove_all (selection);

        g_signal_handlers_disconnect_by_func (stage, manipulate_lasso_capture, data);
        clutter_actor_destroy (lasso);
        clutter_actor_queue_redraw (stage);
        lasso = NULL;
        SELECT_ACTION_POST("select lasso");
      default:
        break;
    }
  return TRUE;
}
示例#28
0
/* snap size, as affected by resizing lower right corner,
 * will need extension if other corners are to be supported,
 * it seems possible to do all needed alignments through
 * simple workarounds when only snapping for lower right).
 */
static void snap_size (ClutterActor *actor,
                       gfloat        in_width,
                       gfloat        in_height,
                       gfloat       *out_width,
                       gfloat       *out_height)
{
  *out_width = in_width;
  *out_height = in_height;

  ClutterActor *parent;

  parent = clutter_actor_get_parent (actor);

  if (CLUTTER_IS_CONTAINER (parent))
    {
      gfloat in_x = clutter_actor_get_x (actor);
      gfloat in_y = clutter_actor_get_y (actor);
      gfloat in_end_x = in_x + in_width;
      gfloat in_end_y = in_y + in_height;


      gfloat best_x = 0;
      gfloat best_x_diff = 4096;
      gfloat best_y = 0;
      gfloat best_y_diff = 4096;
      GList *children, *c;
      children = clutter_container_get_children (CLUTTER_CONTAINER (parent));

      hor_pos = 0;
      ver_pos = 0;

      /* We only search our siblings for snapping...
       * perhaps we should search more.
       */

      for (c=children; c; c = c->next)
        {
          gfloat this_x = clutter_actor_get_x (c->data);
          gfloat this_width = clutter_actor_get_width (c->data);
          gfloat this_height = clutter_actor_get_height (c->data);
          gfloat this_end_x = this_x + this_width;
          gfloat this_y = clutter_actor_get_y (c->data);
          gfloat this_end_y = this_y + this_height;

          /* skip self */
          if (c->data == actor)
            continue;

/*
 end aligned with start
                    this_x     this_mid_x     this_end_x
in_x    in_mid_x    in_end_x
*/
          if (abs (this_x - in_end_x) < best_x_diff)
            {
              best_x_diff = abs (this_x - in_end_x);
              best_x = this_x;
              hor_pos=3;
            }
          if (abs (this_y - in_end_y) < best_y_diff)
            {
              best_y_diff = abs (this_y - in_end_y);
              best_y = this_y;
              ver_pos=3;
            }
/*
 ends aligned
                    this_x     this_mid_x     this_end_x
                          in_x    in_mid_x    in_end_x
*/
          if (abs (this_end_x - in_end_x) < best_x_diff)
            {
              best_x_diff = abs (this_end_x - in_end_x);
              best_x = this_end_x;
              hor_pos=3;
            }
          if (abs (this_end_y - in_end_y) < best_y_diff)
            {
              best_y_diff = abs (this_end_y - in_end_y);
              best_y = this_end_y;
              ver_pos=3;
            }
        }

        {
          if (best_x_diff < SNAP_THRESHOLD)
            {
              *out_width = best_x-in_x;
            }
          else
            {
              hor_pos = 0;
            }
          if (best_y_diff < SNAP_THRESHOLD)
            {
              *out_height = best_y-in_y;
            }
          else
            {
              ver_pos = 0;
            }
        }
    }
}
示例#29
0
/* Private functions */
static void
ensure_layout (AstroAppview *view)
{
  AstroAppviewPrivate *priv;
  GList *l;
  gint groupx = 0;
  gint center = 0;
  gint i = 0;
  
  priv = view->priv;

  groupx = clutter_actor_get_x (CLUTTER_ACTOR (view));
  center = CSW()/2;

  l = clutter_container_get_children (CLUTTER_CONTAINER (view));
  for (l = l; l; l = l->next)
    {
      ClutterActor *icon = l->data;
      gint realx, diff, y_diff;;
      gfloat scale;

      realx = clutter_actor_get_x (icon) + groupx;
      
      if (realx > center && realx < CSW ())
        {
          diff = center - (realx - center);
        }
      else if (realx > 0 && realx <= center)
        {
          diff = realx;
        }
      else
        {
          diff = 0;
        }
  
      scale = (gfloat)diff/center;
      scale = 0.2 + (0.8 * scale);
      clutter_actor_set_scale (icon, scale, scale);

      if (realx < center)
        {
          gfloat angle, sine;

          angle = scale * (3.14*2);
          sine = sin (0.5 *angle);
          
          y_diff = (CSH()/2) + (VARIANCE * sine);
        }
      else
        {
          gfloat angle, sine;

          angle = scale * (3.14*2);
          sine = sin (0.5*angle);
          
          y_diff = (CSH()/2) - (VARIANCE * sine);

        }
      clutter_actor_set_y (icon, y_diff);
      
      astro_appicon_set_blur (ASTRO_APPICON (icon), (1.0 - scale) * MAX_BLUR);

      i++;
    }
}