/* Find requested selection target depending of current selection */ static ClutterActor* _xfdashboard_workspace_selector_focusable_find_selection(XfdashboardFocusable *inFocusable, ClutterActor *inSelection, XfdashboardSelectionTarget inDirection) { XfdashboardWorkspaceSelector *self; XfdashboardWorkspaceSelectorPrivate *priv; XfdashboardLiveWorkspace *selection; ClutterActor *newSelection; g_return_val_if_fail(XFDASHBOARD_IS_FOCUSABLE(inFocusable), NULL); g_return_val_if_fail(XFDASHBOARD_IS_WORKSPACE_SELECTOR(inFocusable), NULL); g_return_val_if_fail(!inSelection || XFDASHBOARD_IS_LIVE_WORKSPACE(inSelection), NULL); self=XFDASHBOARD_WORKSPACE_SELECTOR(inFocusable); priv=self->priv; newSelection=NULL; selection=NULL; /* Find actor for current active workspace which is also the current selection */ if(priv->activeWorkspace) { selection=_xfdashboard_workspace_selector_find_actor_for_workspace(self, priv->activeWorkspace); } if(!selection) return(NULL); /* If there is nothing selected return currently determined actor which is * the current active workspace. */ if(!inSelection) { g_debug("No selection at %s, so select first child %s for direction %u", G_OBJECT_TYPE_NAME(self), selection ? G_OBJECT_TYPE_NAME(selection) : "<nil>", inDirection); return(CLUTTER_ACTOR(selection)); } /* Check that selection is a child of this actor otherwise return NULL */ if(!xfdashboard_actor_contains_child_deep(CLUTTER_ACTOR(self), inSelection)) { ClutterActor *parent; parent=clutter_actor_get_parent(inSelection); g_warning(_("Cannot lookup selection target at %s because %s is a child of %s"), G_OBJECT_TYPE_NAME(self), G_OBJECT_TYPE_NAME(inSelection), parent ? G_OBJECT_TYPE_NAME(parent) : "<nil>"); return(NULL); } /* Find target selection */ switch(inDirection) { case XFDASHBOARD_SELECTION_TARGET_LEFT: if(priv->orientation==CLUTTER_ORIENTATION_HORIZONTAL) { newSelection=clutter_actor_get_previous_sibling(CLUTTER_ACTOR(selection)); } break; case XFDASHBOARD_SELECTION_TARGET_UP: if(priv->orientation==CLUTTER_ORIENTATION_VERTICAL) { newSelection=clutter_actor_get_previous_sibling(CLUTTER_ACTOR(selection)); } break; case XFDASHBOARD_SELECTION_TARGET_RIGHT: if(priv->orientation==CLUTTER_ORIENTATION_HORIZONTAL) { newSelection=clutter_actor_get_next_sibling(CLUTTER_ACTOR(selection)); } break; case XFDASHBOARD_SELECTION_TARGET_DOWN: if(priv->orientation==CLUTTER_ORIENTATION_VERTICAL) { newSelection=clutter_actor_get_next_sibling(CLUTTER_ACTOR(selection)); } break; case XFDASHBOARD_SELECTION_TARGET_FIRST: case XFDASHBOARD_SELECTION_TARGET_PAGE_UP: case XFDASHBOARD_SELECTION_TARGET_PAGE_LEFT: if(inDirection==XFDASHBOARD_SELECTION_TARGET_FIRST || (inDirection==XFDASHBOARD_SELECTION_TARGET_PAGE_UP && priv->orientation==CLUTTER_ORIENTATION_VERTICAL) || (inDirection==XFDASHBOARD_SELECTION_TARGET_PAGE_LEFT && priv->orientation==CLUTTER_ORIENTATION_HORIZONTAL)) { newSelection=clutter_actor_get_first_child(CLUTTER_ACTOR(self)); } break; case XFDASHBOARD_SELECTION_TARGET_LAST: case XFDASHBOARD_SELECTION_TARGET_PAGE_DOWN: case XFDASHBOARD_SELECTION_TARGET_PAGE_RIGHT: if(inDirection==XFDASHBOARD_SELECTION_TARGET_LAST || (inDirection==XFDASHBOARD_SELECTION_TARGET_PAGE_DOWN && priv->orientation==CLUTTER_ORIENTATION_VERTICAL) || (inDirection==XFDASHBOARD_SELECTION_TARGET_PAGE_RIGHT && priv->orientation==CLUTTER_ORIENTATION_HORIZONTAL)) { newSelection=clutter_actor_get_last_child(CLUTTER_ACTOR(self)); } break; case XFDASHBOARD_SELECTION_TARGET_NEXT: newSelection=clutter_actor_get_next_sibling(CLUTTER_ACTOR(selection)); if(!newSelection) newSelection=clutter_actor_get_previous_sibling(CLUTTER_ACTOR(selection)); break; default: { gchar *valueName; valueName=xfdashboard_get_enum_value_name(XFDASHBOARD_TYPE_SELECTION_TARGET, inDirection); g_critical(_("Focusable object %s does not handle selection direction of type %s."), G_OBJECT_TYPE_NAME(self), valueName); g_free(valueName); } break; } /* If new selection could be found override current selection with it */ if(newSelection && XFDASHBOARD_IS_LIVE_WORKSPACE(newSelection)) { selection=XFDASHBOARD_LIVE_WORKSPACE(newSelection); } /* Return new selection found */ g_debug("Selecting %s at %s for current selection %s in direction %u", selection ? G_OBJECT_TYPE_NAME(selection) : "<nil>", G_OBJECT_TYPE_NAME(self), inSelection ? G_OBJECT_TYPE_NAME(inSelection) : "<nil>", inDirection); return(CLUTTER_ACTOR(selection)); }
static void st_box_layout_allocate (ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { StBoxLayoutPrivate *priv = ST_BOX_LAYOUT (actor)->priv; StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor)); ClutterActorBox content_box; gfloat avail_width, avail_height, min_width, natural_width, min_height, natural_height; gfloat position, next_position; gint n_expand_children = 0, i; gfloat expand_amount, shrink_amount; BoxChildShrink *shrinks = NULL; // Home-made logical xor gboolean flip = (!(st_widget_get_direction (ST_WIDGET (actor)) == ST_TEXT_DIRECTION_RTL) != !priv->is_align_end); gboolean reverse_order = (!priv->is_align_end != !priv->is_pack_start); ClutterActor *child; clutter_actor_set_allocation (actor, box, flags); st_theme_node_get_content_box (theme_node, box, &content_box); avail_width = content_box.x2 - content_box.x1; avail_height = content_box.y2 - content_box.y1; get_content_preferred_width (ST_BOX_LAYOUT (actor), avail_height, &min_width, &natural_width); get_content_preferred_height (ST_BOX_LAYOUT (actor), MAX (avail_width, min_width), &min_height, &natural_height); /* update adjustments for scrolling */ if (priv->vadjustment) { gdouble prev_value; g_object_set (G_OBJECT (priv->vadjustment), "lower", 0.0, "upper", MAX (min_height, avail_height), "page-size", avail_height, "step-increment", avail_height / 6, "page-increment", avail_height - avail_height / 6, NULL); prev_value = st_adjustment_get_value (priv->vadjustment); st_adjustment_set_value (priv->vadjustment, prev_value); } if (priv->hadjustment) { gdouble prev_value; g_object_set (G_OBJECT (priv->hadjustment), "lower", 0.0, "upper", MAX (min_width, avail_width), "page-size", avail_width, "step-increment", avail_width / 6, "page-increment", avail_width - avail_width / 6, NULL); prev_value = st_adjustment_get_value (priv->hadjustment); st_adjustment_set_value (priv->hadjustment, prev_value); } if (avail_height < min_height) { avail_height = min_height; content_box.y2 = content_box.y1 + avail_height; } if (avail_width < min_width) { avail_width = min_width; content_box.x2 = content_box.x1 + avail_width; } if (priv->is_vertical) { expand_amount = MAX (0, avail_height - natural_height); shrink_amount = MAX (0, natural_height - avail_height); } else { expand_amount = MAX (0, avail_width - natural_width); shrink_amount = MAX (0, natural_width - avail_width); } if (expand_amount > 0) { /* count the number of children with expand set to TRUE */ n_expand_children = 0; for (child = clutter_actor_get_first_child (actor); child != NULL; child = clutter_actor_get_next_sibling (child)) { gboolean expand; if (!CLUTTER_ACTOR_IS_VISIBLE (child) || clutter_actor_get_fixed_position_set (child)) continue; clutter_container_child_get ((ClutterContainer *) actor, child, "expand", &expand, NULL); if (expand) n_expand_children++; } if (n_expand_children == 0) expand_amount = 0; } else if (shrink_amount > 0) { shrinks = compute_shrinks (ST_BOX_LAYOUT (actor), priv->is_vertical ? avail_width : avail_height, shrink_amount); } if (priv->is_vertical) { if (flip) { position = content_box.y2; } else { position = content_box.y1; } } else { if (flip) { position = content_box.x2; } else { position = content_box.x1; } } if (reverse_order) { child = clutter_actor_get_last_child (actor); i = clutter_actor_get_n_children (actor) - 1; } else { child = clutter_actor_get_first_child (actor); i = 0; } gfloat init_padding = (avail_width/2) - (natural_width/2); while (child != NULL) { ClutterActorBox child_box; gfloat child_min, child_nat, child_allocated; gboolean xfill, yfill, expand, fixed; StAlign xalign, yalign; if (!CLUTTER_ACTOR_IS_VISIBLE (child)) goto next_child; fixed = clutter_actor_get_fixed_position_set (child); if (fixed) { clutter_actor_allocate_preferred_size (child, flags); goto next_child; } clutter_container_child_get ((ClutterContainer*) actor, child, "x-fill", &xfill, "y-fill", &yfill, "x-align", &xalign, "y-align", &yalign, "expand", &expand, NULL); if (priv->is_vertical) { _st_actor_get_preferred_height (child, avail_width, xfill, &child_min, &child_nat); } else { _st_actor_get_preferred_width (child, avail_height, yfill, &child_min, &child_nat); } child_allocated = child_nat; if (expand_amount > 0 && expand) child_allocated += expand_amount / n_expand_children; else if (shrink_amount > 0) child_allocated -= shrinks[i].shrink_amount; if (flip) { next_position = position - child_allocated; } else { next_position = position + child_allocated; } if (priv->is_vertical) { if (flip) { child_box.y1 = (int)(0.5 + next_position); child_box.y2 = (int)(0.5 + position); } else { child_box.y1 = (int)(0.5 + position); child_box.y2 = (int)(0.5 + next_position); } child_box.x1 = content_box.x1; child_box.x2 = content_box.x2; _st_allocate_fill (ST_WIDGET (actor), child, &child_box, xalign, yalign, xfill, yfill); clutter_actor_allocate (child, &child_box, flags); } else { if (flip) { child_box.x1 = (int)(0.5 + next_position); child_box.x2 = (int)(0.5 + position); } else { child_box.x1 = (int)(0.5 + position); child_box.x2 = (int)(0.5 + next_position); } child_box.y1 = content_box.y1; child_box.y2 = content_box.y2; _st_allocate_fill (ST_WIDGET (actor), child, &child_box, xalign, yalign, xfill, yfill); clutter_actor_allocate (child, &child_box, flags); } if (flip) position = next_position - priv->spacing; else position = next_position + priv->spacing; next_child: if (reverse_order) { child = clutter_actor_get_previous_sibling (child); i--; } else { child = clutter_actor_get_next_sibling (child); i++; } } if (shrinks) g_free (shrinks); }