mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-29 06:51:10 +00:00
Add GtkConstraintLayout
A layout manager using GtkConstraintSolver to measure and allocate children.
This commit is contained in:
parent
e7b2c530c5
commit
cdf80f1d65
@ -82,6 +82,8 @@
|
||||
#include <gtk/gtkcolorutils.h>
|
||||
#include <gtk/gtkcombobox.h>
|
||||
#include <gtk/gtkcomboboxtext.h>
|
||||
#include <gtk/gtkconstraintlayout.h>
|
||||
#include <gtk/gtkconstraint.h>
|
||||
#include <gtk/gtkcontainer.h>
|
||||
#include <gtk/gtkcssprovider.h>
|
||||
#include <gtk/gtkcustomlayout.h>
|
||||
|
583
gtk/gtkconstraint.c
Normal file
583
gtk/gtkconstraint.c
Normal file
@ -0,0 +1,583 @@
|
||||
/* gtkconstraint.c: Constraint between two widgets
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Emmanuele Bassi
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gtkconstraint
|
||||
* @Title: GtkConstraint
|
||||
* @Short_description: The description of a constraint
|
||||
*
|
||||
* #GtkConstraint describes a constraint between an attribute on a widget
|
||||
* and another attribute on another widget, expressed as a linear equation
|
||||
* like:
|
||||
*
|
||||
* |[
|
||||
* target.attr1 = source.attr2 × multiplier + constant
|
||||
* ]|
|
||||
*
|
||||
* Each #GtkConstraint is part of a system that will be solved by a
|
||||
* #GtkConstraintLayout in order to allocate and position each child widget.
|
||||
*
|
||||
* The source and target widgets, as well as their attributes, of a
|
||||
* #GtkConstraint instance are immutable after creation.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkconstraintprivate.h"
|
||||
#include "gtkconstraintsolverprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkwidget.h"
|
||||
|
||||
enum {
|
||||
PROP_TARGET_WIDGET = 1,
|
||||
PROP_TARGET_ATTRIBUTE,
|
||||
PROP_RELATION,
|
||||
PROP_SOURCE_WIDGET,
|
||||
PROP_SOURCE_ATTRIBUTE,
|
||||
PROP_MULTIPLIER,
|
||||
PROP_CONSTANT,
|
||||
PROP_STRENGTH,
|
||||
|
||||
N_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[N_PROPERTIES];
|
||||
|
||||
G_DEFINE_TYPE (GtkConstraint, gtk_constraint, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gtk_constraint_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkConstraint *self = GTK_CONSTRAINT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TARGET_WIDGET:
|
||||
self->target_widget = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
case PROP_TARGET_ATTRIBUTE:
|
||||
self->target_attribute = g_value_get_enum (value);
|
||||
break;
|
||||
|
||||
case PROP_RELATION:
|
||||
self->relation = g_value_get_enum (value);
|
||||
break;
|
||||
|
||||
case PROP_SOURCE_WIDGET:
|
||||
self->source_widget = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
case PROP_SOURCE_ATTRIBUTE:
|
||||
self->source_attribute = g_value_get_enum (value);
|
||||
break;
|
||||
|
||||
case PROP_MULTIPLIER:
|
||||
self->multiplier = g_value_get_double (value);
|
||||
break;
|
||||
|
||||
case PROP_CONSTANT:
|
||||
self->constant = g_value_get_double (value);
|
||||
break;
|
||||
|
||||
case PROP_STRENGTH:
|
||||
self->strength = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_constraint_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkConstraint *self = GTK_CONSTRAINT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TARGET_WIDGET:
|
||||
g_value_set_object (value, self->target_widget);
|
||||
break;
|
||||
|
||||
case PROP_TARGET_ATTRIBUTE:
|
||||
g_value_set_enum (value, self->target_attribute);
|
||||
break;
|
||||
|
||||
case PROP_RELATION:
|
||||
g_value_set_enum (value, self->relation);
|
||||
break;
|
||||
|
||||
case PROP_SOURCE_WIDGET:
|
||||
g_value_set_object (value, self->source_widget);
|
||||
break;
|
||||
|
||||
case PROP_SOURCE_ATTRIBUTE:
|
||||
g_value_set_enum (value, self->source_attribute);
|
||||
break;
|
||||
|
||||
case PROP_MULTIPLIER:
|
||||
g_value_set_double (value, self->multiplier);
|
||||
break;
|
||||
|
||||
case PROP_CONSTANT:
|
||||
g_value_set_double (value, self->constant);
|
||||
break;
|
||||
|
||||
case PROP_STRENGTH:
|
||||
g_value_set_int (value, self->strength);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_constraint_finalize (GObject *gobject)
|
||||
{
|
||||
GtkConstraint *self = GTK_CONSTRAINT (gobject);
|
||||
|
||||
gtk_constraint_detach (self);
|
||||
|
||||
G_OBJECT_CLASS (gtk_constraint_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_constraint_class_init (GtkConstraintClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->set_property = gtk_constraint_set_property;
|
||||
gobject_class->get_property = gtk_constraint_get_property;
|
||||
gobject_class->finalize = gtk_constraint_finalize;
|
||||
|
||||
/**
|
||||
* GtkConstraint:target-widget:
|
||||
*
|
||||
* The target widget of the constraint.
|
||||
*
|
||||
* The constraint will set the #GtkConstraint:target-attribute of the
|
||||
* target widget using the #GtkConstraint:source-attribute of the source
|
||||
* widget.
|
||||
*/
|
||||
obj_props[PROP_TARGET_WIDGET] =
|
||||
g_param_spec_object ("target-widget",
|
||||
P_("Target Widget"),
|
||||
P_("The target widget of the constraint"),
|
||||
GTK_TYPE_WIDGET,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
/**
|
||||
* GtkConstraint:target-attribute:
|
||||
*
|
||||
* The attribute of the #GtkConstraint:target-widget set by the constraint.
|
||||
*/
|
||||
obj_props[PROP_TARGET_ATTRIBUTE] =
|
||||
g_param_spec_enum ("target-attribute",
|
||||
P_("Target Attribute"),
|
||||
P_("The attribute of the target widget set by the constraint"),
|
||||
GTK_TYPE_CONSTRAINT_ATTRIBUTE,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_NONE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
/**
|
||||
* GtkConstraint:relation:
|
||||
*
|
||||
* The relation order between the terms of the constraint.
|
||||
*/
|
||||
obj_props[PROP_RELATION] =
|
||||
g_param_spec_enum ("relation",
|
||||
P_("Relation"),
|
||||
P_("The relation between the source and target attributes"),
|
||||
GTK_TYPE_CONSTRAINT_RELATION,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
/**
|
||||
* GtkConstraint:source-widget:
|
||||
*
|
||||
* The source widget of the constraint.
|
||||
*
|
||||
* The constraint will set the #GtkConstraint:target-attribute of the
|
||||
* target widget using the #GtkConstraint:source-attribute of the source
|
||||
* widget.
|
||||
*/
|
||||
obj_props[PROP_SOURCE_WIDGET] =
|
||||
g_param_spec_object ("source-widget",
|
||||
P_("Source Widget"),
|
||||
P_("The source widget of the constraint"),
|
||||
GTK_TYPE_WIDGET,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
/**
|
||||
* GtkConstraint:source-attribute:
|
||||
*
|
||||
* The attribute of the #GtkConstraint:source-widget read by the constraint.
|
||||
*/
|
||||
obj_props[PROP_SOURCE_ATTRIBUTE] =
|
||||
g_param_spec_enum ("source-attribute",
|
||||
P_("Source Attribute"),
|
||||
P_("The attribute of the source widget set by the constraint"),
|
||||
GTK_TYPE_CONSTRAINT_ATTRIBUTE,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_NONE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
/**
|
||||
* GtkConstraint:multiplier:
|
||||
*
|
||||
* The multiplication factor to be applied to the
|
||||
* #GtkConstraint:source-attribue.
|
||||
*/
|
||||
obj_props[PROP_MULTIPLIER] =
|
||||
g_param_spec_double ("multiplier",
|
||||
P_("Multiplier"),
|
||||
P_("The multiplication factor to be applied to the source attribute"),
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 1.0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
/**
|
||||
* GtkConstraint:constant:
|
||||
*
|
||||
* The constant value to be added to the #GtkConstraint:source-attribute.
|
||||
*/
|
||||
obj_props[PROP_CONSTANT] =
|
||||
g_param_spec_double ("constant",
|
||||
P_("Constant"),
|
||||
P_("The constant to be added to the source attribute"),
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
/**
|
||||
* GtkConstraint:strength:
|
||||
*
|
||||
* The strength of the constraint.
|
||||
*
|
||||
* The strength can be expressed either using one of the symbolic values
|
||||
* of the #GtkConstraintStrength enumeration, or any positive integer
|
||||
* value.
|
||||
*/
|
||||
obj_props[PROP_STRENGTH] =
|
||||
g_param_spec_int ("strength",
|
||||
P_("Strength"),
|
||||
P_("The strength of the constraint"),
|
||||
GTK_CONSTRAINT_STRENGTH_WEAK, G_MAXINT,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPERTIES, obj_props);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_constraint_init (GtkConstraint *self)
|
||||
{
|
||||
self->multiplier = 1.0;
|
||||
self->constant = 0.0;
|
||||
|
||||
self->target_attribute = GTK_CONSTRAINT_ATTRIBUTE_NONE;
|
||||
self->source_attribute = GTK_CONSTRAINT_ATTRIBUTE_NONE;
|
||||
self->relation = GTK_CONSTRAINT_RELATION_EQ;
|
||||
self->strength = GTK_CONSTRAINT_STRENGTH_REQUIRED;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_new:
|
||||
* @target_widget: (nullable): a #GtkWidget
|
||||
* @target_attribute: the attribute of @target_widget to be set
|
||||
* @relation: the relation equivalence between @target_attribute and @source_attribute
|
||||
* @source_widget: (nullable): a #GtkWidget
|
||||
* @source_attribute: the attribute of @source_widget to be read
|
||||
* @multiplier: a multiplication factor to be applied to @source_attribute
|
||||
* @constant: a constant factor to be added to @source_attribute
|
||||
* @strength: the strength of the constraint
|
||||
*
|
||||
* Creates a new #GtkConstraint representing a relation between a layout
|
||||
* attribute on a source #GtkWidget and a layout attribute on a target
|
||||
* #GtkWidget.
|
||||
*
|
||||
* Returns: the newly created #GtkConstraint
|
||||
*/
|
||||
GtkConstraint *
|
||||
gtk_constraint_new (GtkWidget *target_widget,
|
||||
GtkConstraintAttribute target_attribute,
|
||||
GtkConstraintRelation relation,
|
||||
GtkWidget *source_widget,
|
||||
GtkConstraintAttribute source_attribute,
|
||||
double multiplier,
|
||||
double constant,
|
||||
int strength)
|
||||
{
|
||||
g_return_val_if_fail (target_widget == NULL || GTK_IS_WIDGET (target_widget), NULL);
|
||||
g_return_val_if_fail (source_widget == NULL || GTK_IS_WIDGET (source_widget), NULL);
|
||||
|
||||
return g_object_new (GTK_TYPE_CONSTRAINT,
|
||||
"target-widget", target_widget,
|
||||
"target-attribute", target_attribute,
|
||||
"relation", relation,
|
||||
"source-widget", source_widget,
|
||||
"source-attribute", source_attribute,
|
||||
"multiplier", multiplier,
|
||||
"constant", constant,
|
||||
"strength", strength,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_new_constant:
|
||||
* @target_widget: (nullable): a #GtkWidget
|
||||
* @target_attribute: the attribute of @target_widget to be set
|
||||
* @relation: the relation equivalence between @target_attribute and @constant
|
||||
* @constant: a constant factor to be set on @target_attribute
|
||||
* @strength: the strength of the constraint
|
||||
*
|
||||
* Creates a new #GtkConstraint representing a relation between a layout
|
||||
* attribute on a target #GtkWidget and a constant value.
|
||||
*
|
||||
* Returns: the newly created #GtkConstraint
|
||||
*/
|
||||
GtkConstraint *
|
||||
gtk_constraint_new_constant (GtkWidget *target_widget,
|
||||
GtkConstraintAttribute target_attribute,
|
||||
GtkConstraintRelation relation,
|
||||
double constant,
|
||||
int strength)
|
||||
{
|
||||
g_return_val_if_fail (target_widget == NULL || GTK_IS_WIDGET (target_widget), NULL);
|
||||
|
||||
return g_object_new (GTK_TYPE_CONSTRAINT,
|
||||
"target-widget", target_widget,
|
||||
"target-attribute", target_attribute,
|
||||
"relation", relation,
|
||||
"source-attribute", GTK_CONSTRAINT_ATTRIBUTE_NONE,
|
||||
"constant", constant,
|
||||
"strength", strength,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_get_target_widget:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Retrieves the target widget for the @constraint.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): a #GtkWidget
|
||||
*/
|
||||
GtkWidget *
|
||||
gtk_constraint_get_target_widget (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), NULL);
|
||||
|
||||
return constraint->target_widget;
|
||||
}
|
||||
|
||||
GtkConstraintAttribute
|
||||
gtk_constraint_get_target_attribute (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), GTK_CONSTRAINT_ATTRIBUTE_NONE);
|
||||
|
||||
return constraint->target_attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_get_source_widget:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Retrieves the source widget for the @constraint.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): a #GtkWidget
|
||||
*/
|
||||
GtkWidget *
|
||||
gtk_constraint_get_source_widget (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), NULL);
|
||||
|
||||
return constraint->source_widget;
|
||||
}
|
||||
|
||||
GtkConstraintAttribute
|
||||
gtk_constraint_get_source_attribute (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), GTK_CONSTRAINT_ATTRIBUTE_NONE);
|
||||
|
||||
return constraint->source_attribute;
|
||||
}
|
||||
|
||||
GtkConstraintRelation
|
||||
gtk_constraint_get_relation (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), GTK_CONSTRAINT_RELATION_EQ);
|
||||
|
||||
return constraint->relation;
|
||||
}
|
||||
|
||||
double
|
||||
gtk_constraint_get_multiplier (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), 1.0);
|
||||
|
||||
return constraint->multiplier;
|
||||
}
|
||||
|
||||
double
|
||||
gtk_constraint_get_constant (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), 0.0);
|
||||
|
||||
return constraint->constant;
|
||||
}
|
||||
|
||||
int
|
||||
gtk_constraint_get_strength (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
|
||||
return constraint->strength;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gtk_constraint_get_weight:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Computes the weight of the @constraint to be used with
|
||||
* #GtkConstraintSolver.
|
||||
*
|
||||
* Returns: the weight of the constraint
|
||||
*/
|
||||
double
|
||||
gtk_constraint_get_weight (GtkConstraint *constraint)
|
||||
{
|
||||
if (constraint->strength > 0)
|
||||
return constraint->strength;
|
||||
|
||||
switch (constraint->strength)
|
||||
{
|
||||
case GTK_CONSTRAINT_STRENGTH_REQUIRED:
|
||||
return GTK_CONSTRAINT_WEIGHT_REQUIRED;
|
||||
|
||||
case GTK_CONSTRAINT_STRENGTH_STRONG:
|
||||
return GTK_CONSTRAINT_WEIGHT_STRONG;
|
||||
|
||||
case GTK_CONSTRAINT_STRENGTH_MEDIUM:
|
||||
return GTK_CONSTRAINT_WEIGHT_MEDIUM;
|
||||
|
||||
case GTK_CONSTRAINT_STRENGTH_WEAK:
|
||||
return GTK_CONSTRAINT_WEIGHT_WEAK;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_is_required:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Checks whether the @constraint is a required relation for solving the
|
||||
* constraint layout.
|
||||
*
|
||||
* Returns: %TRUE if the constraint is required
|
||||
*/
|
||||
gboolean
|
||||
gtk_constraint_is_required (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), FALSE);
|
||||
|
||||
return constraint->strength == GTK_CONSTRAINT_STRENGTH_REQUIRED;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_is_attached:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Checks whether the @constraint is attached to a #GtkConstraintLayout,
|
||||
* and it is contributing to the layout.
|
||||
*
|
||||
* Returns: %TRUE if the constraint is attached
|
||||
*/
|
||||
gboolean
|
||||
gtk_constraint_is_attached (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), FALSE);
|
||||
|
||||
return constraint->constraint_ref != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_is_constant:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Checks whether the @constraint describes a relation between an attribute
|
||||
* on the #GtkConstraint:target-widget and a constant value.
|
||||
*
|
||||
* Returns: %TRUE if the constraint is a constant relation
|
||||
*/
|
||||
gboolean
|
||||
gtk_constraint_is_constant (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), FALSE);
|
||||
|
||||
return constraint->source_widget == NULL &&
|
||||
constraint->source_attribute == GTK_CONSTRAINT_ATTRIBUTE_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_constraint_attach (GtkConstraint *constraint,
|
||||
GtkConstraintSolver *solver,
|
||||
GtkConstraintRef *ref)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CONSTRAINT (constraint));
|
||||
g_return_if_fail (GTK_IS_CONSTRAINT_SOLVER (solver));
|
||||
g_return_if_fail (ref != NULL);
|
||||
|
||||
constraint->constraint_ref = ref;
|
||||
constraint->solver = solver;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_constraint_detach (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CONSTRAINT (constraint));
|
||||
|
||||
if (constraint->constraint_ref == NULL)
|
||||
return;
|
||||
|
||||
gtk_constraint_solver_remove_constraint (constraint->solver, constraint->constraint_ref);
|
||||
constraint->constraint_ref = NULL;
|
||||
constraint->solver = NULL;
|
||||
}
|
85
gtk/gtkconstraint.h
Normal file
85
gtk/gtkconstraint.h
Normal file
@ -0,0 +1,85 @@
|
||||
/* gtkconstraint.h: Constraint between two widgets
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Emmanuele Bassi
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtktypes.h>
|
||||
#include <gtk/gtkenums.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_CONSTRAINT (gtk_constraint_get_type ())
|
||||
|
||||
/**
|
||||
* GtkConstraint:
|
||||
*
|
||||
* An object describing the relation between two widget attributes.
|
||||
*
|
||||
* All relations are in the form:
|
||||
*
|
||||
* |[<!-- language=plain -->
|
||||
* target.attr_name = source.attr_name × multiplier + constant
|
||||
* ]|
|
||||
*
|
||||
* A #GtkConstraint is immutable once it's created.
|
||||
*/
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_FINAL_TYPE (GtkConstraint, gtk_constraint, GTK, CONSTRAINT, GObject)
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkConstraint * gtk_constraint_new (GtkWidget *target_widget,
|
||||
GtkConstraintAttribute target_attribute,
|
||||
GtkConstraintRelation relation,
|
||||
GtkWidget *source_widget,
|
||||
GtkConstraintAttribute source_attribute,
|
||||
double multiplier,
|
||||
double constant,
|
||||
int strength);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkConstraint * gtk_constraint_new_constant (GtkWidget *target_widget,
|
||||
GtkConstraintAttribute target_attribute,
|
||||
GtkConstraintRelation relation,
|
||||
double constant,
|
||||
int strength);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkWidget * gtk_constraint_get_target_widget (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkConstraintAttribute gtk_constraint_get_target_attribute (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkWidget * gtk_constraint_get_source_widget (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkConstraintAttribute gtk_constraint_get_source_attribute (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkConstraintRelation gtk_constraint_get_relation (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
double gtk_constraint_get_multiplier (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
double gtk_constraint_get_constant (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gtk_constraint_get_strength (GtkConstraint *constraint);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_constraint_is_required (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_constraint_is_attached (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_constraint_is_constant (GtkConstraint *constraint);
|
||||
|
||||
G_END_DECLS
|
1108
gtk/gtkconstraintlayout.c
Normal file
1108
gtk/gtkconstraintlayout.c
Normal file
File diff suppressed because it is too large
Load Diff
53
gtk/gtkconstraintlayout.h
Normal file
53
gtk/gtkconstraintlayout.h
Normal file
@ -0,0 +1,53 @@
|
||||
/* gtkconstraintlayout.h: Layout manager using constraints
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Emmanuele Bassi
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtklayoutmanager.h>
|
||||
#include <gtk/gtkconstraint.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_CONSTRAINT_LAYOUT (gtk_constraint_layout_get_type ())
|
||||
#define GTK_TYPE_CONSTRAINT_LAYOUT_CHILD (gtk_constraint_layout_child_get_type ())
|
||||
|
||||
/**
|
||||
* GtkConstraintLayout:
|
||||
*
|
||||
* A layout manager using #GtkConstraint to describe
|
||||
* relations between widgets.
|
||||
*/
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_FINAL_TYPE (GtkConstraintLayout, gtk_constraint_layout, GTK, CONSTRAINT_LAYOUT, GtkLayoutManager)
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkLayoutManager * gtk_constraint_layout_new (void);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_layout_add_constraint (GtkConstraintLayout *manager,
|
||||
GtkConstraint *constraint);
|
||||
|
||||
/**
|
||||
* GtkConstraintLayoutChild:
|
||||
*
|
||||
* A #GtkLayoutChild in a #GtkConstraintLayout.
|
||||
*/
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_FINAL_TYPE (GtkConstraintLayoutChild, gtk_constraint_layout_child, GTK, CONSTRAINT_LAYOUT_CHILD, GtkLayoutChild)
|
||||
|
||||
G_END_DECLS
|
62
gtk/gtkconstraintprivate.h
Normal file
62
gtk/gtkconstraintprivate.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* gtkconstraintprivate.h: Constraint between two widgets
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Emmanuele Bassi
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gtkconstraint.h"
|
||||
#include "gtkconstrainttypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct _GtkConstraint
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GtkConstraintAttribute target_attribute;
|
||||
GtkConstraintAttribute source_attribute;
|
||||
|
||||
GtkWidget *target_widget;
|
||||
GtkWidget *source_widget;
|
||||
|
||||
GtkConstraintRelation relation;
|
||||
|
||||
double multiplier;
|
||||
double constant;
|
||||
|
||||
int strength;
|
||||
|
||||
/* A reference to the real constraint inside the
|
||||
* GtkConstraintSolver, so we can remove it when
|
||||
* finalizing the GtkConstraint instance
|
||||
*/
|
||||
GtkConstraintRef *constraint_ref;
|
||||
|
||||
GtkConstraintSolver *solver;
|
||||
|
||||
guint active : 1;
|
||||
};
|
||||
|
||||
double gtk_constraint_get_weight (GtkConstraint *constraint);
|
||||
|
||||
void gtk_constraint_attach (GtkConstraint *constraint,
|
||||
GtkConstraintSolver *solver,
|
||||
GtkConstraintRef *ref);
|
||||
void gtk_constraint_detach (GtkConstraint *constraint);
|
||||
|
||||
G_END_DECLS
|
@ -348,37 +348,6 @@ gtk_constraint_solver_init (GtkConstraintSolver *self)
|
||||
self->auto_solve = TRUE;
|
||||
}
|
||||
|
||||
/* Symbolic weight thresholds
|
||||
*
|
||||
* Constraint weights live on a continuum, but we use thresholds for simplicity's
|
||||
* sake, so we don't have to necessarily reason in terms of numeric values.
|
||||
*
|
||||
* The public API has a similar approach, where the symbolic constants are negative
|
||||
* values, and positive values are explicit weights. We map those values into
|
||||
* numeric values that the GtkConstraintSolver can plug into the linear equations
|
||||
* tableau.
|
||||
*/
|
||||
#define GTK_CONSTRAINT_WEIGHT_REQUIRED (make_weight (1000, 1000, 1000, 1))
|
||||
#define GTK_CONSTRAINT_WEIGHT_STRONG (make_weight ( 1, 0, 0, 1))
|
||||
#define GTK_CONSTRAINT_WEIGHT_MEDIUM (make_weight ( 0, 1, 0, 1))
|
||||
#define GTK_CONSTRAINT_WEIGHT_WEAK (make_weight ( 0, 0, 1, 1))
|
||||
|
||||
G_GNUC_PURE
|
||||
static inline double
|
||||
make_weight (double a,
|
||||
double b,
|
||||
double c,
|
||||
double w)
|
||||
{
|
||||
double res = 0;
|
||||
|
||||
res += CLAMP (a * w, 0, 1000) * 1000000;
|
||||
res += CLAMP (b * w, 0, 1000) * 1000;
|
||||
res += CLAMP (c * w, 0, 1000);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_constraint_ref_free (GtkConstraintRef *self)
|
||||
{
|
||||
|
@ -29,6 +29,37 @@ G_BEGIN_DECLS
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GtkConstraintSolver, gtk_constraint_solver, GTK, CONSTRAINT_SOLVER, GObject)
|
||||
|
||||
/* Symbolic weight thresholds
|
||||
*
|
||||
* Constraint weights live on a continuum, but we use thresholds for simplicity's
|
||||
* sake, so we don't have to necessarily reason in terms of numeric values.
|
||||
*
|
||||
* The public API has a similar approach, where the symbolic constants are negative
|
||||
* values, and positive values are explicit weights. We map those values into
|
||||
* numeric values that the GtkConstraintSolver can plug into the linear equations
|
||||
* tableau.
|
||||
*/
|
||||
#define GTK_CONSTRAINT_WEIGHT_REQUIRED (make_weight (1000, 1000, 1000, 1))
|
||||
#define GTK_CONSTRAINT_WEIGHT_STRONG (make_weight ( 1, 0, 0, 1))
|
||||
#define GTK_CONSTRAINT_WEIGHT_MEDIUM (make_weight ( 0, 1, 0, 1))
|
||||
#define GTK_CONSTRAINT_WEIGHT_WEAK (make_weight ( 0, 0, 1, 1))
|
||||
|
||||
G_GNUC_PURE
|
||||
static inline double
|
||||
make_weight (double a,
|
||||
double b,
|
||||
double c,
|
||||
double w)
|
||||
{
|
||||
double res = 0;
|
||||
|
||||
res += CLAMP (a * w, 0, 1000) * 1000000;
|
||||
res += CLAMP (b * w, 0, 1000) * 1000;
|
||||
res += CLAMP (c * w, 0, 1000);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
GtkConstraintSolver *
|
||||
gtk_constraint_solver_new (void);
|
||||
|
||||
|
@ -1067,4 +1067,64 @@ typedef enum {
|
||||
GTK_CONSTRAINT_RELATION_GE = 1
|
||||
} GtkConstraintRelation;
|
||||
|
||||
/**
|
||||
* GtkConstraintStrength:
|
||||
* @GTK_CONSTRAINT_STRENGTH_REQUIRED: The constraint is required towards solving the layout
|
||||
* @GTK_CONSTRAINT_STRENGTH_STRONG: A strong constraint
|
||||
* @GTK_CONSTRAINT_STRENGTH_MEDIUM: A medium constraint
|
||||
* @GTK_CONSTRAINT_STRENGTH_WEAK: A weak constraint
|
||||
*
|
||||
* The strength of a constraint, expressed as a symbolic constant.
|
||||
*
|
||||
* The strength of a #GtkConstraint can be expressed with any positive
|
||||
* integer; the values of this enumeration can be used for readability.
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED = 0,
|
||||
GTK_CONSTRAINT_STRENGTH_STRONG = -1,
|
||||
GTK_CONSTRAINT_STRENGTH_MEDIUM = -2,
|
||||
GTK_CONSTRAINT_STRENGTH_WEAK = -3
|
||||
} GtkConstraintStrength;
|
||||
|
||||
/**
|
||||
* GtkConstraintAttribute:
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_NONE: No attribute, used for constant
|
||||
* relations
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_LEFT: The left edge of a widget, regardless of
|
||||
* text direction
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_RIGHT: The right edge of a widget, regardless
|
||||
* of text direction
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_TOP: The top edge of a widget
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_BOTTOM: The bottom edge of a widget
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_START: The leading edge of a widget, depending
|
||||
* on text direction; equivalent to %GTK_CONSTRAINT_ATTRIBUTE_LEFT for LTR
|
||||
* languages, and %GTK_CONSTRAINT_ATTRIBUTE_RIGHT for RTL ones
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_END: The trailing edge of a widget, depending
|
||||
* on text direction; equivalent to %GTK_CONSTRAINT_ATTRIBUTE_RIGHT for LTR
|
||||
* languages, and %GTK_CONSTRAINT_ATTRIBUTE_LEFT for RTL ones
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_WIDTH: The width of a widget
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_HEIGHT: The height of a widget
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_CENTER_X: The center of a widget, on the
|
||||
* horizontal axis
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y: The center of a widget, on the
|
||||
* vertical axis
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_BASELINE: The baseline of a widget
|
||||
*
|
||||
* The widget attributes that can be used when creating a #GtkConstraint.
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_CONSTRAINT_ATTRIBUTE_NONE,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_LEFT,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_RIGHT,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_CENTER_X,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BASELINE
|
||||
} GtkConstraintAttribute;
|
||||
|
||||
#endif /* __GTK_ENUMS_H__ */
|
||||
|
@ -202,6 +202,8 @@ gtk_public_sources = files([
|
||||
'gtkcombobox.c',
|
||||
'gtkcomboboxtext.c',
|
||||
'gtkcomposetable.c',
|
||||
'gtkconstraintlayout.c',
|
||||
'gtkconstraint.c',
|
||||
'gtkcontainer.c',
|
||||
'gtkcssprovider.c',
|
||||
'gtkdialog.c',
|
||||
@ -461,6 +463,8 @@ gtk_public_headers = files([
|
||||
'gtkcolorutils.h',
|
||||
'gtkcombobox.h',
|
||||
'gtkcomboboxtext.h',
|
||||
'gtkconstraintlayout.h',
|
||||
'gtkconstraint.h',
|
||||
'gtkcontainer.h',
|
||||
'gtkcssprovider.h',
|
||||
'gtkcustomlayout.h',
|
||||
|
Loading…
Reference in New Issue
Block a user