Compare commits
107 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4eb28908b8 | |||
| 138195998d | |||
| 0468238871 | |||
| b5aee936a9 | |||
| aa8687316f | |||
| 5a3cf5a194 | |||
| c5e1b00994 | |||
| 377f0c1a0a | |||
| a442e6e8de | |||
| 274c47e5ba | |||
| b2f15a622d | |||
| 04aaf02881 | |||
| d5f8e1bf29 | |||
| 33bd7051f2 | |||
| 61345b3216 | |||
| 129691f3a6 | |||
| 4eaf860e86 | |||
| 72814c54a8 | |||
| 4d4e02c9d0 | |||
| 8ab609e4e7 | |||
| 6bc156c237 | |||
| b435dc4366 | |||
| 4dd1de4129 | |||
| 48e6cd4255 | |||
| 658397fad0 | |||
| 670fc5bb94 | |||
| b224df8109 | |||
| c88e7c180d | |||
| 2aabd64f1a | |||
| 7990b24287 | |||
| c76c1a46e4 | |||
| 68fed63eac | |||
| 46403bac12 | |||
| 74c626f835 | |||
| d45a662679 | |||
| f6019f1a16 | |||
| 514de0b91a | |||
| 9a463056d0 | |||
| 035baa092c | |||
| 499738c903 | |||
| f2d7433bf6 | |||
| 405121bccc | |||
| cb96b34315 | |||
| 9edf6fb6cb | |||
| e3c4fb67ca | |||
| a9dfca04e4 | |||
| 71b52f485e | |||
| f62fc4e2f2 | |||
| 511e2b435e | |||
| 3f36340921 | |||
| b1f0f4478e | |||
| 90f8dcc5e1 | |||
| 5a019bfccd | |||
| b39a5fe5dc | |||
| c7ef8411bd | |||
| dab8a8b5c5 | |||
| 8b9c5e3a04 | |||
| 3d3a672deb | |||
| 2f97134a08 | |||
| 47237d32eb | |||
| 139a59cae3 | |||
| 60fb9092fe | |||
| 61b4febbaf | |||
| 4f4ba8c4f6 | |||
| 651adbfb39 | |||
| 3204347bb0 | |||
| b929846cc1 | |||
| fe65da05be | |||
| 06c825df90 | |||
| 46430ea85b | |||
| 859c95b435 | |||
| 5ea8167802 | |||
| 92d3d55164 | |||
| ba2125d8e1 | |||
| 7c96326c18 | |||
| 38d353dc1a | |||
| 7ae04ba36b | |||
| 39c284c490 | |||
| 895e8e25a8 | |||
| 04562a76e3 | |||
| b6781e06c1 | |||
| 54104b6676 | |||
| 21450d5f23 | |||
| a39bbb2041 | |||
| 176d9c6baf | |||
| 64afa765c8 | |||
| a246d8c926 | |||
| 0531e663ee | |||
| bd2349c0a0 | |||
| 636fbc0f1a | |||
| cdf80f1d65 | |||
| e7b2c530c5 | |||
| e07098da03 | |||
| 98a21bf498 | |||
| c694dd6049 | |||
| 6b308cd71e | |||
| 3b6ee32f83 | |||
| 3bc3e140dd | |||
| a6a9853676 | |||
| 6b42e5b433 | |||
| 99c01607f1 | |||
| 071748592d | |||
| 8dd74eac2e | |||
| f6a2678486 | |||
| e28ec2a3eb | |||
| c4fd786866 | |||
| 8fa7de5563 |
+1
-1
@@ -105,7 +105,7 @@ pages:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v6
|
||||
stage: deploy
|
||||
script:
|
||||
- meson -Ddocumentation=true _build .
|
||||
- meson -Dgtk_doc=true _build .
|
||||
- ninja -C _build
|
||||
- ninja -C _build gdk4-doc gsk4-doc gtk4-doc
|
||||
|
||||
|
||||
@@ -56,12 +56,6 @@
|
||||
/* Define if GStreamer support is available */
|
||||
#mesondefine HAVE_GSTREAMER
|
||||
|
||||
/* Define to 1 if you have the `httpGetAuthString' function. */
|
||||
#mesondefine HAVE_HTTPGETAUTHSTRING
|
||||
|
||||
/* Define if cups http_t authstring field is accessible */
|
||||
#mesondefine HAVE_HTTP_AUTHSTRING
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#mesondefine HAVE_INTTYPES_H
|
||||
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "constraint-editor-application.h"
|
||||
#include "constraint-editor-window.h"
|
||||
|
||||
struct _ConstraintEditorApplication
|
||||
{
|
||||
GtkApplication parent_instance;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(ConstraintEditorApplication, constraint_editor_application, GTK_TYPE_APPLICATION);
|
||||
|
||||
static void
|
||||
constraint_editor_application_init (ConstraintEditorApplication *app)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
quit_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer data)
|
||||
{
|
||||
g_application_quit (G_APPLICATION (data));
|
||||
}
|
||||
|
||||
static GActionEntry app_entries[] =
|
||||
{
|
||||
{ "quit", quit_activated, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
constraint_editor_application_startup (GApplication *app)
|
||||
{
|
||||
const char *quit_accels[2] = { "<Ctrl>Q", NULL };
|
||||
const char *open_accels[2] = { "<Ctrl>O", NULL };
|
||||
GtkCssProvider *provider;
|
||||
|
||||
G_APPLICATION_CLASS (constraint_editor_application_parent_class)->startup (app);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
||||
app_entries, G_N_ELEMENTS (app_entries),
|
||||
app);
|
||||
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.quit", quit_accels);
|
||||
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "win.open", open_accels);
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider, "/org/gtk/gtk4/constraint-editor/constraint-editor.css");
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_application_activate (GApplication *app)
|
||||
{
|
||||
ConstraintEditorWindow *win;
|
||||
|
||||
win = constraint_editor_window_new (CONSTRAINT_EDITOR_APPLICATION (app));
|
||||
gtk_window_present (GTK_WINDOW (win));
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_application_open (GApplication *app,
|
||||
GFile **files,
|
||||
gint n_files,
|
||||
const gchar *hint)
|
||||
{
|
||||
ConstraintEditorWindow *win;
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < n_files; i++)
|
||||
{
|
||||
win = constraint_editor_window_new (CONSTRAINT_EDITOR_APPLICATION (app));
|
||||
constraint_editor_window_load (win, files[i]);
|
||||
gtk_window_present (GTK_WINDOW (win));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_application_class_init (ConstraintEditorApplicationClass *class)
|
||||
{
|
||||
GApplicationClass *application_class = G_APPLICATION_CLASS (class);
|
||||
|
||||
application_class->startup = constraint_editor_application_startup;
|
||||
application_class->activate = constraint_editor_application_activate;
|
||||
application_class->open = constraint_editor_application_open;
|
||||
}
|
||||
|
||||
ConstraintEditorApplication *
|
||||
constraint_editor_application_new (void)
|
||||
{
|
||||
return g_object_new (CONSTRAINT_EDITOR_APPLICATION_TYPE,
|
||||
"application-id", "org.gtk.gtk4.ConstraintEditor",
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
NULL);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define CONSTRAINT_EDITOR_APPLICATION_TYPE (constraint_editor_application_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintEditorApplication, constraint_editor_application, CONSTRAINT, EDITOR_APPLICATION, GtkApplication)
|
||||
|
||||
ConstraintEditorApplication *constraint_editor_application_new (void);
|
||||
@@ -0,0 +1,639 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "constraint-editor-window.h"
|
||||
#include "constraint-view.h"
|
||||
#include "constraint-editor.h"
|
||||
#include "guide-editor.h"
|
||||
|
||||
struct _ConstraintEditorWindow
|
||||
{
|
||||
GtkApplicationWindow parent_instance;
|
||||
|
||||
GtkWidget *paned;
|
||||
GtkWidget *view;
|
||||
GtkWidget *list;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(ConstraintEditorWindow, constraint_editor_window, GTK_TYPE_APPLICATION_WINDOW);
|
||||
|
||||
static GtkConstraintTarget *
|
||||
find_target (GListModel *model,
|
||||
GtkConstraintTarget *orig)
|
||||
{
|
||||
const char *name;
|
||||
const char *model_name;
|
||||
gpointer item;
|
||||
int i;
|
||||
|
||||
if (orig == NULL)
|
||||
return NULL;
|
||||
|
||||
if (GTK_IS_LABEL (orig))
|
||||
name = gtk_label_get_label (GTK_LABEL (orig));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (orig))
|
||||
name = gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (orig));
|
||||
else
|
||||
{
|
||||
g_warning ("Don't know how to handle %s targets", G_OBJECT_TYPE_NAME (orig));
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < g_list_model_get_n_items (model); i++)
|
||||
{
|
||||
item = g_list_model_get_item (model, i);
|
||||
g_object_unref (item);
|
||||
if (GTK_IS_WIDGET (item))
|
||||
model_name = gtk_widget_get_name (GTK_WIDGET (item));
|
||||
else
|
||||
model_name = gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (item));
|
||||
|
||||
if (strcmp (name, model_name) == 0)
|
||||
return GTK_CONSTRAINT_TARGET (item);
|
||||
}
|
||||
g_warning ("Failed to find target '%s'", name);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
constraint_editor_window_load (ConstraintEditorWindow *self,
|
||||
GFile *file)
|
||||
{
|
||||
char *path;
|
||||
GtkBuilder *builder;
|
||||
GError *error = NULL;
|
||||
GtkWidget *view;
|
||||
GtkLayoutManager *layout;
|
||||
GtkWidget *child;
|
||||
const char *name;
|
||||
gpointer item;
|
||||
int i;
|
||||
GListModel *list;
|
||||
|
||||
path = g_file_get_path (file);
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
if (!gtk_builder_add_from_file (builder, path, &error))
|
||||
{
|
||||
g_print ("Could not load %s: %s", path, error->message);
|
||||
g_error_free (error);
|
||||
g_free (path);
|
||||
g_object_unref (builder);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
view = GTK_WIDGET (gtk_builder_get_object (builder, "view"));
|
||||
if (!GTK_IS_BOX (view))
|
||||
{
|
||||
g_print ("Could not load %s: No GtkBox named 'view'", path);
|
||||
g_free (path);
|
||||
g_object_unref (builder);
|
||||
return FALSE;
|
||||
}
|
||||
layout = gtk_widget_get_layout_manager (view);
|
||||
if (!GTK_IS_CONSTRAINT_LAYOUT (layout))
|
||||
{
|
||||
g_print ("Could not load %s: Widget 'view' does not use GtkConstraintLayout", path);
|
||||
g_free (path);
|
||||
g_object_unref (builder);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (child = gtk_widget_get_first_child (view);
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
if (!GTK_IS_LABEL (child))
|
||||
{
|
||||
g_print ("Skipping non-GtkLabel child\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
name = gtk_label_get_label (GTK_LABEL (child));
|
||||
constraint_view_add_child (CONSTRAINT_VIEW (self->view), name);
|
||||
}
|
||||
|
||||
list = gtk_constraint_layout_observe_guides (GTK_CONSTRAINT_LAYOUT (layout));
|
||||
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||
{
|
||||
GtkConstraintGuide *guide, *clone;
|
||||
int w, h;
|
||||
|
||||
item = g_list_model_get_item (list, i);
|
||||
guide = GTK_CONSTRAINT_GUIDE (item);
|
||||
|
||||
/* need to clone here, to attach to the right targets */
|
||||
clone = gtk_constraint_guide_new ();
|
||||
gtk_constraint_guide_set_name (clone, gtk_constraint_guide_get_name (guide));
|
||||
gtk_constraint_guide_set_strength (clone, gtk_constraint_guide_get_strength (guide));
|
||||
gtk_constraint_guide_get_min_size (guide, &w, &h);
|
||||
gtk_constraint_guide_set_min_size (clone, w, h);
|
||||
gtk_constraint_guide_get_nat_size (guide, &w, &h);
|
||||
gtk_constraint_guide_set_nat_size (clone, w, h);
|
||||
gtk_constraint_guide_get_max_size (guide, &w, &h);
|
||||
gtk_constraint_guide_set_max_size (clone, w, h);
|
||||
constraint_view_add_guide (CONSTRAINT_VIEW (self->view), clone);
|
||||
g_object_unref (guide);
|
||||
g_object_unref (clone);
|
||||
}
|
||||
g_object_unref (list);
|
||||
|
||||
list = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (layout));
|
||||
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||
{
|
||||
GtkConstraint *constraint;
|
||||
GtkConstraint *clone;
|
||||
GtkConstraintTarget *target;
|
||||
GtkConstraintTarget *source;
|
||||
|
||||
item = g_list_model_get_item (list, i);
|
||||
constraint = GTK_CONSTRAINT (item);
|
||||
|
||||
target = gtk_constraint_get_target (constraint);
|
||||
source = gtk_constraint_get_source (constraint);
|
||||
clone = gtk_constraint_new (find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), target),
|
||||
gtk_constraint_get_target_attribute (constraint),
|
||||
gtk_constraint_get_relation (constraint),
|
||||
find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), source),
|
||||
gtk_constraint_get_target_attribute (constraint),
|
||||
gtk_constraint_get_multiplier (constraint),
|
||||
gtk_constraint_get_constant (constraint),
|
||||
gtk_constraint_get_strength (constraint));
|
||||
|
||||
constraint_view_add_constraint (CONSTRAINT_VIEW (self->view), clone);
|
||||
|
||||
g_object_unref (constraint);
|
||||
g_object_unref (clone);
|
||||
}
|
||||
g_object_unref (list);
|
||||
|
||||
g_free (path);
|
||||
g_object_unref (builder);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
open_response_cb (GtkNativeDialog *dialog,
|
||||
gint response,
|
||||
ConstraintEditorWindow *self)
|
||||
{
|
||||
gtk_native_dialog_hide (dialog);
|
||||
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
||||
constraint_editor_window_load (self, file);
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
gtk_native_dialog_destroy (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
open_cb (GtkWidget *button,
|
||||
ConstraintEditorWindow *self)
|
||||
{
|
||||
GtkFileChooserNative *dialog;
|
||||
|
||||
dialog = gtk_file_chooser_native_new ("Open file",
|
||||
GTK_WINDOW (self),
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
"_Load",
|
||||
"_Cancel");
|
||||
|
||||
gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (dialog), TRUE);
|
||||
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), ".");
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (open_response_cb), self);
|
||||
gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
serialize_child (GString *str,
|
||||
int indent,
|
||||
GtkWidget *child)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
name = gtk_widget_get_name (child);
|
||||
g_string_append_printf (str, "%*s<child>\n", indent, "");
|
||||
g_string_append_printf (str, "%*s <object class=\"GtkLabel\" id=\"%s\">\n", indent, "", name);
|
||||
g_string_append_printf (str, "%*s <property name=\"label\">%s</property>\n", indent, "", name);
|
||||
g_string_append_printf (str, "%*s </object>\n", indent, "");
|
||||
g_string_append_printf (str, "%*s</child>\n", indent, "");
|
||||
}
|
||||
|
||||
static char *
|
||||
serialize_model (GListModel *list)
|
||||
{
|
||||
GString *str = g_string_new ("");
|
||||
int i;
|
||||
|
||||
g_string_append (str, "<interface>\n");
|
||||
g_string_append (str, " <object class=\"GtkBox\" id=\"view\">\n");
|
||||
g_string_append (str, " <property name=\"layout-manager\">\n");
|
||||
g_string_append (str, " <object class=\"GtkConstraintLayout\">\n");
|
||||
g_string_append (str, " <constraints>\n");
|
||||
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||
{
|
||||
gpointer item = g_list_model_get_item (list, i);
|
||||
g_object_unref (item);
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
constraint_editor_serialize_constraint (str, 10, GTK_CONSTRAINT (item));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
guide_editor_serialize_guide (str, 10, GTK_CONSTRAINT_GUIDE (item));
|
||||
}
|
||||
g_string_append (str, " </constraints>\n");
|
||||
g_string_append (str, " </object>\n");
|
||||
g_string_append (str, " </property>\n");
|
||||
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||
{
|
||||
gpointer item = g_list_model_get_item (list, i);
|
||||
g_object_unref (item);
|
||||
if (GTK_IS_WIDGET (item))
|
||||
serialize_child (str, 4, GTK_WIDGET (item));
|
||||
}
|
||||
g_string_append (str, " </object>\n");
|
||||
g_string_append (str, "</interface>\n");
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
save_response_cb (GtkNativeDialog *dialog,
|
||||
gint response,
|
||||
ConstraintEditorWindow *self)
|
||||
{
|
||||
gtk_native_dialog_hide (dialog);
|
||||
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
GListModel *model;
|
||||
char *text, *filename;
|
||||
GError *error = NULL;
|
||||
|
||||
model = constraint_view_get_model (CONSTRAINT_VIEW (self->view));
|
||||
text = serialize_model (model);
|
||||
|
||||
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
|
||||
if (!g_file_set_contents (filename, text, -1, &error))
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (self))),
|
||||
GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_INFO,
|
||||
GTK_BUTTONS_OK,
|
||||
"Saving failed");
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||
"%s", error->message);
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
gtk_widget_show (dialog);
|
||||
g_error_free (error);
|
||||
}
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
gtk_native_dialog_destroy (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
save_cb (GtkWidget *button,
|
||||
ConstraintEditorWindow *self)
|
||||
{
|
||||
GtkFileChooserNative *dialog;
|
||||
|
||||
dialog = gtk_file_chooser_native_new ("Save constraints",
|
||||
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
|
||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
"_Save",
|
||||
"_Cancel");
|
||||
|
||||
gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (dialog), TRUE);
|
||||
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), ".");
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (save_response_cb), self);
|
||||
gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_window_finalize (GObject *object)
|
||||
{
|
||||
//ConstraintEditorWindow *self = (ConstraintEditorWindow *)object;
|
||||
|
||||
G_OBJECT_CLASS (constraint_editor_window_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static int child_counter;
|
||||
static int guide_counter;
|
||||
|
||||
static void
|
||||
add_child (ConstraintEditorWindow *win)
|
||||
{
|
||||
char *name;
|
||||
|
||||
child_counter++;
|
||||
name = g_strdup_printf ("Child %d", child_counter);
|
||||
constraint_view_add_child (CONSTRAINT_VIEW (win->view), name);
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
static void
|
||||
add_guide (ConstraintEditorWindow *win)
|
||||
{
|
||||
char *name;
|
||||
GtkConstraintGuide *guide;
|
||||
|
||||
guide_counter++;
|
||||
name = g_strdup_printf ("Guide %d", guide_counter);
|
||||
guide = gtk_constraint_guide_new ();
|
||||
gtk_constraint_guide_set_name (guide, name);
|
||||
g_free (name);
|
||||
|
||||
constraint_view_add_guide (CONSTRAINT_VIEW (win->view), guide);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_done (ConstraintEditor *editor,
|
||||
GtkConstraint *constraint,
|
||||
ConstraintEditorWindow *win)
|
||||
{
|
||||
GtkConstraint *old_constraint;
|
||||
|
||||
g_object_get (editor, "constraint", &old_constraint, NULL);
|
||||
|
||||
if (old_constraint)
|
||||
constraint_view_remove_constraint (CONSTRAINT_VIEW (win->view), old_constraint);
|
||||
|
||||
constraint_view_add_constraint (CONSTRAINT_VIEW (win->view), constraint);
|
||||
|
||||
g_clear_object (&old_constraint);
|
||||
|
||||
gtk_widget_destroy (gtk_widget_get_ancestor (GTK_WIDGET (editor), GTK_TYPE_WINDOW));
|
||||
}
|
||||
|
||||
static void
|
||||
edit_constraint (ConstraintEditorWindow *win,
|
||||
GtkConstraint *constraint)
|
||||
{
|
||||
GtkWidget *window;
|
||||
ConstraintEditor *editor;
|
||||
GListModel *model;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (win));
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
if (constraint)
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Edit Constraint");
|
||||
else
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Create Constraint");
|
||||
|
||||
model = constraint_view_get_model (CONSTRAINT_VIEW (win->view));
|
||||
|
||||
editor = constraint_editor_new (model, constraint);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (editor));
|
||||
|
||||
g_signal_connect (editor, "done", G_CALLBACK (constraint_editor_done), win);
|
||||
|
||||
gtk_widget_show (window);
|
||||
}
|
||||
|
||||
static void
|
||||
add_constraint (ConstraintEditorWindow *win)
|
||||
{
|
||||
edit_constraint (win, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_done (GuideEditor *editor,
|
||||
GtkConstraintGuide *guide,
|
||||
ConstraintEditorWindow *win)
|
||||
{
|
||||
gtk_widget_destroy (gtk_widget_get_ancestor (GTK_WIDGET (editor), GTK_TYPE_WINDOW));
|
||||
}
|
||||
|
||||
static void
|
||||
edit_guide (ConstraintEditorWindow *win,
|
||||
GtkConstraintGuide *guide)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GuideEditor *editor;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (win));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Edit Guide");
|
||||
|
||||
editor = guide_editor_new (guide);
|
||||
gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (editor));
|
||||
|
||||
g_signal_connect (editor, "done", G_CALLBACK (guide_editor_done), win);
|
||||
gtk_widget_show (window);
|
||||
}
|
||||
|
||||
static void
|
||||
row_activated (GtkListBox *list,
|
||||
GtkListBoxRow *row,
|
||||
ConstraintEditorWindow *win)
|
||||
{
|
||||
GObject *item;
|
||||
|
||||
item = G_OBJECT (g_object_get_data (G_OBJECT (row), "item"));
|
||||
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
edit_constraint (win, GTK_CONSTRAINT (item));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
edit_guide (win, GTK_CONSTRAINT_GUIDE (item));
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_window_class_init (ConstraintEditorWindowClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
g_type_ensure (CONSTRAINT_VIEW_TYPE);
|
||||
|
||||
object_class->finalize = constraint_editor_window_finalize;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
"/org/gtk/gtk4/constraint-editor/constraint-editor-window.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, paned);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, view);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, list);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, open_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, save_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, add_child);
|
||||
gtk_widget_class_bind_template_callback (widget_class, add_guide);
|
||||
gtk_widget_class_bind_template_callback (widget_class, add_constraint);
|
||||
gtk_widget_class_bind_template_callback (widget_class, row_activated);
|
||||
}
|
||||
|
||||
static void
|
||||
row_edit (GtkButton *button,
|
||||
ConstraintEditorWindow *win)
|
||||
{
|
||||
GtkWidget *row;
|
||||
GObject *item;
|
||||
|
||||
row = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_LIST_BOX_ROW);
|
||||
item = (GObject *)g_object_get_data (G_OBJECT (row), "item");
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
edit_constraint (win, GTK_CONSTRAINT (item));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
edit_guide (win, GTK_CONSTRAINT_GUIDE (item));
|
||||
}
|
||||
|
||||
static void
|
||||
mark_constraints_invalid (ConstraintEditorWindow *win,
|
||||
gpointer removed)
|
||||
{
|
||||
GtkWidget *child;
|
||||
GObject *item;
|
||||
|
||||
for (child = gtk_widget_get_first_child (win->list);
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
item = (GObject *)g_object_get_data (G_OBJECT (child), "item");
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
{
|
||||
GtkConstraint *constraint = GTK_CONSTRAINT (item);
|
||||
|
||||
if (gtk_constraint_get_target (constraint) == (GtkConstraintTarget *)removed ||
|
||||
gtk_constraint_get_source (constraint) == (GtkConstraintTarget *)removed)
|
||||
{
|
||||
GtkWidget *button;
|
||||
button = (GtkWidget *)g_object_get_data (G_OBJECT (child), "edit");
|
||||
gtk_button_set_icon_name (GTK_BUTTON (button), "dialog-warning-symbolic");
|
||||
gtk_widget_set_tooltip_text (button, "Constraint is invalid");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
row_delete (GtkButton *button,
|
||||
ConstraintEditorWindow *win)
|
||||
{
|
||||
GtkWidget *row;
|
||||
GObject *item;
|
||||
|
||||
row = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_LIST_BOX_ROW);
|
||||
item = (GObject *)g_object_get_data (G_OBJECT (row), "item");
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
constraint_view_remove_constraint (CONSTRAINT_VIEW (win->view),
|
||||
GTK_CONSTRAINT (item));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
{
|
||||
mark_constraints_invalid (win, item);
|
||||
constraint_view_remove_guide (CONSTRAINT_VIEW (win->view),
|
||||
GTK_CONSTRAINT_GUIDE (item));
|
||||
}
|
||||
else if (GTK_IS_WIDGET (item))
|
||||
{
|
||||
mark_constraints_invalid (win, item);
|
||||
constraint_view_remove_child (CONSTRAINT_VIEW (win->view),
|
||||
GTK_WIDGET (item));
|
||||
}
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_widget_func (gpointer item,
|
||||
gpointer user_data)
|
||||
{
|
||||
ConstraintEditorWindow *win = user_data;
|
||||
const char *name;
|
||||
char *freeme = NULL;
|
||||
GtkWidget *row, *box, *label, *button;
|
||||
|
||||
if (GTK_IS_WIDGET (item))
|
||||
name = gtk_widget_get_name (GTK_WIDGET (item));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
name = gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (item));
|
||||
else if (GTK_IS_CONSTRAINT (item))
|
||||
name = freeme = constraint_editor_constraint_to_string (GTK_CONSTRAINT (item));
|
||||
else
|
||||
name = "";
|
||||
|
||||
row = gtk_list_box_row_new ();
|
||||
g_object_set_data_full (G_OBJECT (row), "item", g_object_ref (item), g_object_unref);
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
label = gtk_label_new (name);
|
||||
if (GTK_IS_WIDGET (item) || GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
g_object_bind_property (item, "name",
|
||||
label, "label",
|
||||
G_BINDING_DEFAULT);
|
||||
g_object_set (label, "margin", 10, NULL);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (row), box);
|
||||
gtk_container_add (GTK_CONTAINER (box), label);
|
||||
|
||||
if (GTK_IS_CONSTRAINT (item) || GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
{
|
||||
button = gtk_button_new_from_icon_name ("document-edit-symbolic");
|
||||
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (row_edit), win);
|
||||
g_object_set_data (G_OBJECT (row), "edit", button);
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
|
||||
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
}
|
||||
else if (GTK_IS_WIDGET (item))
|
||||
{
|
||||
button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
|
||||
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
}
|
||||
|
||||
g_free (freeme);
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_window_init (ConstraintEditorWindow *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
gtk_list_box_bind_model (GTK_LIST_BOX (self->list),
|
||||
constraint_view_get_model (CONSTRAINT_VIEW (self->view)),
|
||||
create_widget_func,
|
||||
self,
|
||||
NULL);
|
||||
}
|
||||
|
||||
ConstraintEditorWindow *
|
||||
constraint_editor_window_new (ConstraintEditorApplication *application)
|
||||
{
|
||||
return g_object_new (CONSTRAINT_EDITOR_WINDOW_TYPE,
|
||||
"application", application,
|
||||
NULL);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "constraint-editor-application.h"
|
||||
|
||||
|
||||
#define CONSTRAINT_EDITOR_WINDOW_TYPE (constraint_editor_window_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintEditorWindow, constraint_editor_window, CONSTRAINT, EDITOR_WINDOW, GtkApplicationWindow)
|
||||
|
||||
ConstraintEditorWindow * constraint_editor_window_new (ConstraintEditorApplication *application);
|
||||
|
||||
gboolean constraint_editor_window_load (ConstraintEditorWindow *self,
|
||||
GFile *file);
|
||||
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="ConstraintEditorWindow" parent="GtkApplicationWindow">
|
||||
<style>
|
||||
<class name="devel"/>
|
||||
</style>
|
||||
<property name="title" translatable="yes">GTK Constraint Editor</property>
|
||||
<property name="default-width">1024</property>
|
||||
<property name="default-height">768</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="title" translatable="yes">GTK Constraint Editor</property>
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="start">
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">document-open-symbolic</property>
|
||||
<property name="tooltip-text">Open ui file</property>
|
||||
<signal name="clicked" handler="open_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
<child type="start">
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">document-save-symbolic</property>
|
||||
<property name="tooltip-text">Save to ui file</property>
|
||||
<signal name="clicked" handler="save_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPaned" id="paned">
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Add Child</property>
|
||||
<signal name="clicked" handler="add_child" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Add Guide</property>
|
||||
<signal name="clicked" handler="add_guide" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Add Constraint</property>
|
||||
<signal name="clicked" handler="add_constraint" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="vscrollbar-policy">automatic</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkListBox" id="list">
|
||||
<property name="show-separators">1</property>
|
||||
<property name="selection-mode">none</property>
|
||||
<signal name="row-activated" handler="row_activated"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="ConstraintView" id="view">
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -0,0 +1,656 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "constraint-editor.h"
|
||||
|
||||
struct _ConstraintEditor
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *grid;
|
||||
GtkWidget *target;
|
||||
GtkWidget *target_attr;
|
||||
GtkWidget *relation;
|
||||
GtkWidget *source;
|
||||
GtkWidget *source_attr;
|
||||
GtkWidget *multiplier;
|
||||
GtkWidget *constant;
|
||||
GtkWidget *strength;
|
||||
GtkWidget *preview;
|
||||
GtkWidget *button;
|
||||
|
||||
GtkConstraint *constraint;
|
||||
GListModel *model;
|
||||
|
||||
gboolean constructed;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_MODEL = 1,
|
||||
PROP_CONSTRAINT,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static GParamSpec *pspecs[LAST_PROP];
|
||||
|
||||
enum {
|
||||
DONE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
G_DEFINE_TYPE(ConstraintEditor, constraint_editor, GTK_TYPE_WIDGET);
|
||||
|
||||
static const char *
|
||||
get_target_name (GtkConstraintTarget *target)
|
||||
{
|
||||
if (target == NULL)
|
||||
return "super";
|
||||
else if (GTK_IS_WIDGET (target))
|
||||
return gtk_widget_get_name (GTK_WIDGET (target));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (target))
|
||||
return gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (target));
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_target_combo (GListModel *model,
|
||||
GtkWidget *combo,
|
||||
gboolean is_source)
|
||||
{
|
||||
int i;
|
||||
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "super", "Super");
|
||||
|
||||
if (model)
|
||||
{
|
||||
for (i = 0; i < g_list_model_get_n_items (model); i++)
|
||||
{
|
||||
GObject *item = g_list_model_get_object (model, i);
|
||||
const char *name;
|
||||
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
continue;
|
||||
|
||||
name = get_target_name (GTK_CONSTRAINT_TARGET (item));
|
||||
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), name, name);
|
||||
g_object_unref (item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_attribute_combo (GtkWidget *combo,
|
||||
gboolean is_source)
|
||||
{
|
||||
if (is_source)
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "none", "None");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "left", "Left");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "right", "Right");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "top", "Top");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "bottom", "Bottom");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "start", "Start");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "end", "End");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "width", "Width");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "height", "Height");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "center-x", "Center X");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "center-y", "Center Y");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "baseline", "Baseline");
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_relation_combo (GtkWidget *combo)
|
||||
{
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "le", "≤");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "eq", "=");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "ge", "≥");
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_strength_combo (GtkWidget *combo)
|
||||
{
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "weak", "Weak");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "medium", "Medium");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "strong", "Strong");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "required", "Required");
|
||||
}
|
||||
|
||||
static gpointer
|
||||
get_target (GListModel *model,
|
||||
const char *id)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (strcmp ("super", id) == 0)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < g_list_model_get_n_items (model); i++)
|
||||
{
|
||||
GObject *item = g_list_model_get_object (model, i);
|
||||
g_object_unref (item);
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
continue;
|
||||
else if (GTK_IS_WIDGET (item))
|
||||
{
|
||||
if (strcmp (id, gtk_widget_get_name (GTK_WIDGET (item))) == 0)
|
||||
return item;
|
||||
}
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
{
|
||||
if (strcmp (id, gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (item))) == 0)
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GtkConstraintAttribute
|
||||
get_target_attr (const char *id)
|
||||
{
|
||||
GtkConstraintAttribute attr;
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_ATTRIBUTE);
|
||||
GEnumValue *value = g_enum_get_value_by_nick (class, id);
|
||||
attr = value->value;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return attr;
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_attr_nick (GtkConstraintAttribute attr)
|
||||
{
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_ATTRIBUTE);
|
||||
GEnumValue *value = g_enum_get_value (class, attr);
|
||||
const char *nick = value->value_nick;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return nick;
|
||||
}
|
||||
|
||||
static GtkConstraintRelation
|
||||
get_relation (const char *id)
|
||||
{
|
||||
GtkConstraintRelation relation;
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_RELATION);
|
||||
GEnumValue *value = g_enum_get_value_by_nick (class, id);
|
||||
relation = value->value;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return relation;
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_relation_nick (GtkConstraintRelation relation)
|
||||
{
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_RELATION);
|
||||
GEnumValue *value = g_enum_get_value (class, relation);
|
||||
const char *nick = value->value_nick;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return nick;
|
||||
}
|
||||
|
||||
static GtkConstraintStrength
|
||||
get_strength (const char *id)
|
||||
{
|
||||
GtkConstraintStrength strength;
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
|
||||
GEnumValue *value = g_enum_get_value_by_nick (class, id);
|
||||
strength = value->value;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return strength;
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_strength_nick (GtkConstraintStrength strength)
|
||||
{
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
|
||||
GEnumValue *value = g_enum_get_value (class, strength);
|
||||
const char *nick = value->value_nick;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return nick;
|
||||
}
|
||||
|
||||
void
|
||||
constraint_editor_serialize_constraint (GString *str,
|
||||
int indent,
|
||||
GtkConstraint *constraint)
|
||||
{
|
||||
const char *target;
|
||||
const char *target_attr;
|
||||
const char *relation;
|
||||
const char *source;
|
||||
const char *source_attr;
|
||||
double multiplier;
|
||||
double constant;
|
||||
const char *strength;
|
||||
|
||||
target = get_target_name (gtk_constraint_get_target (constraint));
|
||||
target_attr = get_attr_nick (gtk_constraint_get_target_attribute (constraint));
|
||||
relation = get_relation_nick (gtk_constraint_get_relation (constraint));
|
||||
source = get_target_name (gtk_constraint_get_source (constraint));
|
||||
source_attr = get_attr_nick (gtk_constraint_get_source_attribute (constraint));
|
||||
multiplier = gtk_constraint_get_multiplier (constraint);
|
||||
constant = gtk_constraint_get_constant (constraint);
|
||||
strength = get_strength_nick (gtk_constraint_get_strength (constraint));
|
||||
|
||||
g_string_append_printf (str, "%*s<constraint target=\"%s\" target-attribute=\"%s\"\n", indent, "", target, target_attr);
|
||||
g_string_append_printf (str, "%*s relation=\"%s\"\n", indent, "", relation);
|
||||
if (strcmp (source_attr, "none") != 0)
|
||||
{
|
||||
g_string_append_printf (str, "%*s source=\"%s\" source-attribute=\"%s\"\n", indent, "", source, source_attr);
|
||||
g_string_append_printf (str, "%*s multiplier=\"%g\"\n", indent, "", multiplier);
|
||||
}
|
||||
g_string_append_printf (str, "%*s constant=\"%g\"\n", indent, "", constant);
|
||||
g_string_append_printf (str, "%*s strength=\"%s\" />\n", indent, "", strength);
|
||||
}
|
||||
|
||||
static void
|
||||
create_constraint (GtkButton *button,
|
||||
ConstraintEditor *editor)
|
||||
{
|
||||
const char *id;
|
||||
gpointer target;
|
||||
GtkConstraintAttribute target_attr;
|
||||
gpointer source;
|
||||
GtkConstraintAttribute source_attr;
|
||||
GtkConstraintRelation relation;
|
||||
double multiplier;
|
||||
double constant;
|
||||
int strength;
|
||||
GtkConstraint *constraint;
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target));
|
||||
target = get_target (editor->model, id);
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target_attr));
|
||||
target_attr = get_target_attr (id);
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source));
|
||||
source = get_target (editor->model, id);
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
|
||||
source_attr = get_target_attr (id);
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->relation));
|
||||
relation = get_relation (id);
|
||||
|
||||
multiplier = g_ascii_strtod (gtk_editable_get_text (GTK_EDITABLE (editor->multiplier)), NULL);
|
||||
|
||||
constant = g_ascii_strtod (gtk_editable_get_text (GTK_EDITABLE (editor->constant)), NULL);
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->strength));
|
||||
strength = get_strength (id);
|
||||
|
||||
constraint = gtk_constraint_new (target, target_attr,
|
||||
relation,
|
||||
source, source_attr,
|
||||
multiplier,
|
||||
constant,
|
||||
strength);
|
||||
g_signal_emit (editor, signals[DONE], 0, constraint);
|
||||
g_object_unref (constraint);
|
||||
}
|
||||
|
||||
static void
|
||||
source_attr_changed (ConstraintEditor *editor)
|
||||
{
|
||||
const char *id;
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
|
||||
if (strcmp (id, "none") == 0)
|
||||
{
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (editor->source), -1);
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), "");
|
||||
gtk_widget_set_sensitive (editor->source, FALSE);
|
||||
gtk_widget_set_sensitive (editor->multiplier, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_set_sensitive (editor->source, TRUE);
|
||||
gtk_widget_set_sensitive (editor->multiplier, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
constraint_editor_constraint_to_string (GtkConstraint *constraint)
|
||||
{
|
||||
GString *str;
|
||||
const char *name;
|
||||
const char *attr;
|
||||
const char *relation;
|
||||
double c, m;
|
||||
|
||||
str = g_string_new ("");
|
||||
|
||||
name = get_target_name (gtk_constraint_get_target (constraint));
|
||||
attr = get_attr_nick (gtk_constraint_get_target_attribute (constraint));
|
||||
relation = get_relation_nick (gtk_constraint_get_relation (constraint));
|
||||
|
||||
if (name == NULL)
|
||||
name = "[ ]";
|
||||
|
||||
g_string_append_printf (str, "%s.%s %s ", name, attr, relation);
|
||||
|
||||
c = gtk_constraint_get_constant (constraint);
|
||||
|
||||
attr = get_attr_nick (gtk_constraint_get_source_attribute (constraint));
|
||||
if (strcmp (attr, "none") != 0)
|
||||
{
|
||||
name = get_target_name (gtk_constraint_get_source (constraint));
|
||||
m = gtk_constraint_get_multiplier (constraint);
|
||||
|
||||
if (name == NULL)
|
||||
name = "[ ]";
|
||||
|
||||
g_string_append_printf (str, "%s.%s", name, attr);
|
||||
|
||||
if (m != 1.0)
|
||||
g_string_append_printf (str, " × %g", m);
|
||||
|
||||
if (c > 0.0)
|
||||
g_string_append_printf (str, " + %g", c);
|
||||
else if (c < 0.0)
|
||||
g_string_append_printf (str, " - %g", -c);
|
||||
}
|
||||
else
|
||||
g_string_append_printf (str, "%g", c);
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
update_preview (ConstraintEditor *editor)
|
||||
{
|
||||
GString *str;
|
||||
const char *name;
|
||||
const char *attr;
|
||||
char *relation;
|
||||
const char *multiplier;
|
||||
const char *constant;
|
||||
double c, m;
|
||||
|
||||
if (!editor->constructed)
|
||||
return;
|
||||
|
||||
str = g_string_new ("");
|
||||
|
||||
name = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target));
|
||||
attr = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target_attr));
|
||||
relation = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (editor->relation));
|
||||
|
||||
if (name == NULL)
|
||||
name = "[ ]";
|
||||
|
||||
g_string_append_printf (str, "%s.%s %s ", name, attr, relation);
|
||||
g_free (relation);
|
||||
|
||||
constant = gtk_editable_get_text (GTK_EDITABLE (editor->constant));
|
||||
c = g_ascii_strtod (constant, NULL);
|
||||
|
||||
attr = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
|
||||
if (strcmp (attr, "none") != 0)
|
||||
{
|
||||
name = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source));
|
||||
multiplier = gtk_editable_get_text (GTK_EDITABLE (editor->multiplier));
|
||||
m = g_ascii_strtod (multiplier, NULL);
|
||||
|
||||
if (name == NULL)
|
||||
name = "[ ]";
|
||||
|
||||
g_string_append_printf (str, "%s.%s", name, attr);
|
||||
|
||||
if (m != 1.0)
|
||||
g_string_append_printf (str, " × %g", m);
|
||||
|
||||
if (c > 0.0)
|
||||
g_string_append_printf (str, " + %g", c);
|
||||
else if (c < 0.0)
|
||||
g_string_append_printf (str, " - %g", -c);
|
||||
}
|
||||
else
|
||||
g_string_append_printf (str, "%g", c);
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (editor->preview), str->str);
|
||||
|
||||
g_string_free (str, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
update_button (ConstraintEditor *editor)
|
||||
{
|
||||
if (gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target)) != NULL &&
|
||||
gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source)) != NULL)
|
||||
gtk_widget_set_sensitive (editor->button, TRUE);
|
||||
else
|
||||
gtk_widget_set_sensitive (editor->button, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_init (ConstraintEditor *editor)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (editor));
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_constructed (GObject *object)
|
||||
{
|
||||
ConstraintEditor *editor = CONSTRAINT_EDITOR (object);
|
||||
|
||||
constraint_target_combo (editor->model, editor->target, FALSE);
|
||||
constraint_attribute_combo (editor->target_attr, FALSE);
|
||||
constraint_relation_combo (editor->relation);
|
||||
constraint_target_combo (editor->model, editor->source, TRUE);
|
||||
constraint_attribute_combo (editor->source_attr, TRUE);
|
||||
|
||||
constraint_strength_combo (editor->strength);
|
||||
|
||||
if (editor->constraint)
|
||||
{
|
||||
GtkConstraintTarget *target;
|
||||
GtkConstraintAttribute attr;
|
||||
GtkConstraintRelation relation;
|
||||
GtkConstraintStrength strength;
|
||||
const char *nick;
|
||||
char *val;
|
||||
double multiplier;
|
||||
double constant;
|
||||
|
||||
target = gtk_constraint_get_target (editor->constraint);
|
||||
nick = get_target_name (target);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->target), nick);
|
||||
|
||||
attr = gtk_constraint_get_target_attribute (editor->constraint);
|
||||
nick = get_attr_nick (attr);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->target_attr), nick);
|
||||
|
||||
target = gtk_constraint_get_source (editor->constraint);
|
||||
nick = get_target_name (target);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->source), nick);
|
||||
|
||||
attr = gtk_constraint_get_source_attribute (editor->constraint);
|
||||
nick = get_attr_nick (attr);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->source_attr), nick);
|
||||
|
||||
relation = gtk_constraint_get_relation (editor->constraint);
|
||||
nick = get_relation_nick (relation);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->relation), nick);
|
||||
|
||||
multiplier = gtk_constraint_get_multiplier (editor->constraint);
|
||||
val = g_strdup_printf ("%g", multiplier);
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), val);
|
||||
g_free (val);
|
||||
|
||||
constant = gtk_constraint_get_constant (editor->constraint);
|
||||
val = g_strdup_printf ("%g", constant);
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->constant), val);
|
||||
g_free (val);
|
||||
|
||||
strength = gtk_constraint_get_strength (editor->constraint);
|
||||
nick = get_strength_nick (strength);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), nick);
|
||||
|
||||
gtk_button_set_label (GTK_BUTTON (editor->button), "Apply");
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->target_attr), "left");
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->source_attr), "left");
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->relation), "eq");
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), "required");
|
||||
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), "1.0");
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->constant), "0.0");
|
||||
|
||||
gtk_button_set_label (GTK_BUTTON (editor->button), "Create");
|
||||
}
|
||||
|
||||
editor->constructed = TRUE;
|
||||
update_preview (editor);
|
||||
update_button (editor);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ConstraintEditor *self = CONSTRAINT_EDITOR (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_MODEL:
|
||||
self->model = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
case PROP_CONSTRAINT:
|
||||
self->constraint = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ConstraintEditor *self = CONSTRAINT_EDITOR (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_MODEL:
|
||||
g_value_set_object (value, self->model);
|
||||
break;
|
||||
|
||||
case PROP_CONSTRAINT:
|
||||
g_value_set_object (value, self->constraint);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_dispose (GObject *object)
|
||||
{
|
||||
ConstraintEditor *self = (ConstraintEditor *)object;
|
||||
|
||||
g_clear_pointer (&self->grid, gtk_widget_unparent);
|
||||
g_clear_object (&self->model);
|
||||
g_clear_object (&self->constraint);
|
||||
|
||||
G_OBJECT_CLASS (constraint_editor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_class_init (ConstraintEditorClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
object_class->constructed = constraint_editor_constructed;
|
||||
object_class->dispose = constraint_editor_dispose;
|
||||
object_class->set_property = constraint_editor_set_property;
|
||||
object_class->get_property = constraint_editor_get_property;
|
||||
|
||||
pspecs[PROP_CONSTRAINT] =
|
||||
g_param_spec_object ("constraint", "constraint", "constraint",
|
||||
GTK_TYPE_CONSTRAINT,
|
||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
pspecs[PROP_MODEL] =
|
||||
g_param_spec_object ("model", "model", "model",
|
||||
G_TYPE_LIST_MODEL,
|
||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, pspecs);
|
||||
|
||||
signals[DONE] =
|
||||
g_signal_new ("done",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 1, GTK_TYPE_CONSTRAINT);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
"/org/gtk/gtk4/constraint-editor/constraint-editor.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, grid);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, target);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, target_attr);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, relation);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, source);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, source_attr);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, multiplier);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, constant);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, strength);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, preview);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, button);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, update_preview);
|
||||
gtk_widget_class_bind_template_callback (widget_class, update_button);
|
||||
gtk_widget_class_bind_template_callback (widget_class, create_constraint);
|
||||
gtk_widget_class_bind_template_callback (widget_class, source_attr_changed);
|
||||
}
|
||||
|
||||
ConstraintEditor *
|
||||
constraint_editor_new (GListModel *model,
|
||||
GtkConstraint *constraint)
|
||||
{
|
||||
return g_object_new (CONSTRAINT_EDITOR_TYPE,
|
||||
"model", model,
|
||||
"constraint", constraint,
|
||||
NULL);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
constraintview {
|
||||
background: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
constraintview .child {
|
||||
background: red;
|
||||
}
|
||||
|
||||
constraintview .guide {
|
||||
background: blue;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/org/gtk/gtk4/constraint-editor">
|
||||
<file preprocess="xml-stripblanks">constraint-editor-window.ui</file>
|
||||
<file preprocess="xml-stripblanks">constraint-editor.ui</file>
|
||||
<file preprocess="xml-stripblanks">guide-editor.ui</file>
|
||||
<file>constraint-editor.css</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019 Red Hat, inc.
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -14,34 +14,21 @@
|
||||
* 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: Matthias Clasen
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "gtkgridconstraint.h"
|
||||
#include "gtkconstraintsolverprivate.h"
|
||||
#pragma once
|
||||
|
||||
typedef struct {
|
||||
GtkWidget *child;
|
||||
int left;
|
||||
int right;
|
||||
int top;
|
||||
int bottom;
|
||||
} GtkGridConstraintChild;
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
struct _GtkGridConstraint {
|
||||
GObject parent;
|
||||
#define CONSTRAINT_EDITOR_TYPE (constraint_editor_get_type ())
|
||||
|
||||
gboolean row_homogeneous;
|
||||
gboolean column_homogeneous;
|
||||
G_DECLARE_FINAL_TYPE (ConstraintEditor, constraint_editor, CONSTRAINT, EDITOR, GtkWidget)
|
||||
|
||||
GPtrArray *children;
|
||||
ConstraintEditor * constraint_editor_new (GListModel *model,
|
||||
GtkConstraint *constraint);
|
||||
|
||||
GtkConstraintSolver *solver;
|
||||
GPtrArray *refs;
|
||||
};
|
||||
|
||||
gboolean gtk_grid_constraint_is_attached (GtkGridConstraint *constraint);
|
||||
void gtk_grid_constraint_attach (GtkGridConstraint *constraint,
|
||||
GtkConstraintSolver *solver,
|
||||
GPtrArray *refs);
|
||||
void gtk_grid_constraint_detach (GtkGridConstraint *constraint);
|
||||
void constraint_editor_serialize_constraint (GString *str,
|
||||
int indent,
|
||||
GtkConstraint *constraint);
|
||||
char *constraint_editor_constraint_to_string (GtkConstraint *constraint);
|
||||
@@ -0,0 +1,163 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="ConstraintEditor" parent="GtkWidget">
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid">
|
||||
<property name="margin">20</property>
|
||||
<property name="row-spacing">10</property>
|
||||
<property name="column-spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Target</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="target">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<signal name="changed" handler="update_button" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="target_attr">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Relation</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="relation">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Source</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="source">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<signal name="changed" handler="update_button" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="source_attr">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<signal name="changed" handler="source_attr_changed" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Multiplier</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="multiplier">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Constant</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">5</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="constant">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">5</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Strength</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">6</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="strength">
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">6</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="preview">
|
||||
<property name="xalign">0</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">7</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
<attributes>
|
||||
<attribute name="scale" value="1.44"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button">
|
||||
<property name="label">Create</property>
|
||||
<signal name="clicked" handler="create_constraint"/>
|
||||
<layout>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">8</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "constraint-view-child.h"
|
||||
|
||||
struct _ConstraintViewChild
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
char *name;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_NAME = 1,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static GParamSpec props[LAST_PROP];
|
||||
|
||||
G_DEFINE_TYPE (ConstraintViewChild, constraint_view_child, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
constraint_view_child_init (ConstraintViewChild *child)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_view_child_finalize (GObject *object)
|
||||
{
|
||||
ConstraintViewChild *child = CONSTRAINT_VIEW_CHILD (object);
|
||||
|
||||
g_free (child->name);
|
||||
|
||||
G_OBJECT_CLASS (constraint_view_child_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_view_child_set_property (GObject *object,
|
||||
|
||||
static void
|
||||
constraint_view_child_class_init (ConstraintViewChildClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = constraint_view_child_finalize;
|
||||
object_class->get_property = constraint_view_child_get_property;
|
||||
object_class->set_property = constraint_view_child_set_property;
|
||||
|
||||
props[PROP_NAME] =
|
||||
g_param_spec_string ("name", "name", "name",
|
||||
NULL,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, props);
|
||||
}
|
||||
|
||||
#define CONSTRAINT_VIEW_CHILD_TYPE (constraint_view_get_type ())
|
||||
|
||||
G_DECLARE_TYPE (ConstraintViewChild, constraint_view_child, CONSTRAINT, VIEW_CHILD, GObject)
|
||||
|
||||
#define CONSTRAINT_VIEW_WIDGET_TYPE (constraint_view_widget_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintViewWidget, constraint_view_widget, CONSTRAINT, VIEW_WIDGET, ConstraintViewChild)
|
||||
|
||||
ConstraintViewWidget * constraint_view_widget_new (void);
|
||||
|
||||
#define CONSTRAINT_VIEW_GUIDE_TYPE (constraint_view_guide_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintViewGuide, constraint_view_guide, CONSTRAINT, VIEW_GUIDE, ConstraintViewChild)
|
||||
|
||||
ConstraintViewGuide * constraint_view_guide_new (void);
|
||||
|
||||
#define CONSTRAINT_VIEW_CONSTRAINT_TYPE (constraint_view_constraint_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintViewConstraint, constraint_view_constraint, CONSTRAINT, VIEW_CONSTRAINT, ConstraintViewChild)
|
||||
|
||||
ConstraintViewGuide * constraint_view_constraint_new (void);
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define CONSTRAINT_VIEW_CHILD_TYPE (constraint_view_get_type ())
|
||||
|
||||
G_DECLARE_TYPE (ConstraintViewChild, constraint_view_child, CONSTRAINT, VIEW_CHILD, GObject)
|
||||
|
||||
#define CONSTRAINT_VIEW_WIDGET_TYPE (constraint_view_widget_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintViewWidget, constraint_view_widget, CONSTRAINT, VIEW_WIDGET, ConstraintViewChild)
|
||||
|
||||
ConstraintViewWidget * constraint_view_widget_new (void);
|
||||
|
||||
#define CONSTRAINT_VIEW_GUIDE_TYPE (constraint_view_guide_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintViewGuide, constraint_view_guide, CONSTRAINT, VIEW_GUIDE, ConstraintViewChild)
|
||||
|
||||
ConstraintViewGuide * constraint_view_guide_new (void);
|
||||
|
||||
#define CONSTRAINT_VIEW_CONSTRAINT_TYPE (constraint_view_constraint_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintViewConstraint, constraint_view_constraint, CONSTRAINT, VIEW_CONSTRAINT, ConstraintViewChild)
|
||||
|
||||
ConstraintViewGuide * constraint_view_constraint_new (void);
|
||||
@@ -0,0 +1,343 @@
|
||||
/* Copyright (C) 2019 Red Hat, Inc.
|
||||
*
|
||||
* 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 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/>.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "constraint-view.h"
|
||||
|
||||
struct _ConstraintView
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GListModel *model;
|
||||
|
||||
GtkWidget *drag_widget;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ConstraintView, constraint_view, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
constraint_view_dispose (GObject *object)
|
||||
{
|
||||
ConstraintView *view = CONSTRAINT_VIEW (object);
|
||||
GtkWidget *child;
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (view))) != NULL)
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
g_clear_object (&view->model);
|
||||
|
||||
G_OBJECT_CLASS (constraint_view_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_view_class_init (ConstraintViewClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = constraint_view_dispose;
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "constraintview");
|
||||
}
|
||||
|
||||
static void
|
||||
update_weak_position (ConstraintView *self,
|
||||
GtkWidget *child,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
GtkLayoutManager *manager;
|
||||
GtkConstraint *constraint;
|
||||
|
||||
manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
||||
constraint = (GtkConstraint *)g_object_get_data (G_OBJECT (child), "x-constraint");
|
||||
if (constraint)
|
||||
{
|
||||
gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||
constraint);
|
||||
g_object_set_data (G_OBJECT (child), "x-constraint", NULL);
|
||||
}
|
||||
if (x != -100)
|
||||
{
|
||||
constraint = gtk_constraint_new_constant (child,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_CENTER_X,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
x,
|
||||
GTK_CONSTRAINT_STRENGTH_WEAK);
|
||||
g_object_set_data (G_OBJECT (constraint), "internal", "yes");
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||
constraint);
|
||||
g_object_set_data (G_OBJECT (child), "x-constraint", constraint);
|
||||
}
|
||||
|
||||
constraint = (GtkConstraint *)g_object_get_data (G_OBJECT (child), "y-constraint");
|
||||
if (constraint)
|
||||
{
|
||||
gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||
constraint);
|
||||
g_object_set_data (G_OBJECT (child), "y-constraint", NULL);
|
||||
}
|
||||
if (y != -100)
|
||||
{
|
||||
constraint = gtk_constraint_new_constant (child,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
y,
|
||||
GTK_CONSTRAINT_STRENGTH_WEAK);
|
||||
g_object_set_data (G_OBJECT (constraint), "internal", "yes");
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||
constraint);
|
||||
g_object_set_data (G_OBJECT (child), "y-constraint", constraint);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin (GtkGestureDrag *drag,
|
||||
double start_x,
|
||||
double start_y,
|
||||
ConstraintView *self)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_widget_pick (GTK_WIDGET (self), start_x, start_y, GTK_PICK_DEFAULT);
|
||||
|
||||
if (GTK_IS_LABEL (widget))
|
||||
{
|
||||
widget = gtk_widget_get_ancestor (widget, GTK_TYPE_FRAME);
|
||||
if (widget &&
|
||||
gtk_widget_get_parent (widget) == (GtkWidget *)self)
|
||||
{
|
||||
self->drag_widget = widget;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drag_update (GtkGestureDrag *drag,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
ConstraintView *self)
|
||||
{
|
||||
double x, y;
|
||||
|
||||
if (!self->drag_widget)
|
||||
return;
|
||||
|
||||
gtk_gesture_drag_get_start_point (drag, &x, &y);
|
||||
update_weak_position (self, self->drag_widget, x + offset_x, y + offset_y);
|
||||
}
|
||||
|
||||
static void
|
||||
drag_end (GtkGestureDrag *drag,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
ConstraintView *self)
|
||||
{
|
||||
self->drag_widget = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
omit_internal (gpointer item, gpointer user_data)
|
||||
{
|
||||
if (g_object_get_data (G_OBJECT (item), "internal"))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_view_init (ConstraintView *self)
|
||||
{
|
||||
GtkLayoutManager *manager;
|
||||
GtkEventController *controller;
|
||||
GListStore *list;
|
||||
GListModel *all_children;
|
||||
GListModel *all_constraints;
|
||||
GListModel *guides;
|
||||
GListModel *children;
|
||||
GListModel *constraints;
|
||||
|
||||
manager = gtk_constraint_layout_new ();
|
||||
gtk_widget_set_layout_manager (GTK_WIDGET (self), manager);
|
||||
|
||||
all_children = gtk_widget_observe_children (GTK_WIDGET (self));
|
||||
all_constraints = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (manager));
|
||||
guides = gtk_constraint_layout_observe_guides (GTK_CONSTRAINT_LAYOUT (manager));
|
||||
constraints = (GListModel *)gtk_filter_list_model_new (all_constraints, omit_internal, NULL, NULL);
|
||||
children = (GListModel *)gtk_filter_list_model_new (all_children, omit_internal, NULL, NULL);
|
||||
|
||||
list = g_list_store_new (G_TYPE_LIST_MODEL);
|
||||
g_list_store_append (list, children);
|
||||
g_list_store_append (list, guides);
|
||||
g_list_store_append (list, constraints);
|
||||
self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (list)));
|
||||
g_object_unref (children);
|
||||
g_object_unref (guides);
|
||||
g_object_unref (constraints);
|
||||
g_object_unref (all_children);
|
||||
g_object_unref (all_constraints);
|
||||
g_object_unref (list);
|
||||
|
||||
|
||||
controller = (GtkEventController *)gtk_gesture_drag_new ();
|
||||
g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self);
|
||||
g_signal_connect (controller, "drag-update", G_CALLBACK (drag_update), self);
|
||||
g_signal_connect (controller, "drag-end", G_CALLBACK (drag_end), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
}
|
||||
|
||||
ConstraintView *
|
||||
constraint_view_new (void)
|
||||
{
|
||||
return g_object_new (CONSTRAINT_VIEW_TYPE, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
constraint_view_add_child (ConstraintView *view,
|
||||
const char *name)
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *label;
|
||||
|
||||
label = gtk_label_new (name);
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (frame), "child");
|
||||
gtk_widget_set_name (frame, name);
|
||||
gtk_container_add (GTK_CONTAINER (frame), label);
|
||||
gtk_widget_set_parent (frame, GTK_WIDGET (view));
|
||||
|
||||
update_weak_position (view, frame, 100, 100);
|
||||
}
|
||||
|
||||
void
|
||||
constraint_view_remove_child (ConstraintView *view,
|
||||
GtkWidget *child)
|
||||
{
|
||||
update_weak_position (view, child, -100, -100);
|
||||
gtk_widget_unparent (child);
|
||||
}
|
||||
|
||||
void
|
||||
constraint_view_add_guide (ConstraintView *view,
|
||||
GtkConstraintGuide *guide)
|
||||
{
|
||||
GtkConstraintLayout *layout;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *label;
|
||||
const char *name;
|
||||
GtkConstraint *constraint;
|
||||
struct {
|
||||
const char *name;
|
||||
GtkConstraintAttribute attr;
|
||||
} names[] = {
|
||||
{ "left-constraint", GTK_CONSTRAINT_ATTRIBUTE_LEFT },
|
||||
{ "top-constraint", GTK_CONSTRAINT_ATTRIBUTE_TOP },
|
||||
{ "width-constraint", GTK_CONSTRAINT_ATTRIBUTE_WIDTH },
|
||||
{ "height-constraint", GTK_CONSTRAINT_ATTRIBUTE_HEIGHT },
|
||||
};
|
||||
int i;
|
||||
|
||||
name = gtk_constraint_guide_get_name (guide);
|
||||
label = gtk_label_new (name);
|
||||
g_object_bind_property (guide, "name",
|
||||
label, "label",
|
||||
G_BINDING_DEFAULT);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (frame), "guide");
|
||||
g_object_set_data (G_OBJECT (frame), "internal", "yes");
|
||||
gtk_container_add (GTK_CONTAINER (frame), label);
|
||||
gtk_widget_insert_after (frame, GTK_WIDGET (view), NULL);
|
||||
|
||||
g_object_set_data (G_OBJECT (guide), "frame", frame);
|
||||
|
||||
layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (view)));
|
||||
gtk_constraint_layout_add_guide (layout, g_object_ref (guide));
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (names); i++)
|
||||
{
|
||||
constraint = gtk_constraint_new (frame,
|
||||
names[i].attr,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
guide,
|
||||
names[i].attr,
|
||||
1.0, 0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
g_object_set_data (G_OBJECT (constraint), "internal", "yes");
|
||||
gtk_constraint_layout_add_constraint (layout, constraint);
|
||||
g_object_set_data (G_OBJECT (guide), names[i].name, constraint);
|
||||
}
|
||||
|
||||
update_weak_position (view, frame, 150, 150);
|
||||
}
|
||||
|
||||
void
|
||||
constraint_view_remove_guide (ConstraintView *view,
|
||||
GtkConstraintGuide *guide)
|
||||
{
|
||||
GtkConstraintLayout *layout;
|
||||
GtkWidget *frame;
|
||||
GtkConstraint *constraint;
|
||||
const char *names[] = {
|
||||
"left-constraint",
|
||||
"top-constraint",
|
||||
"width-constraint",
|
||||
"height-constraint"
|
||||
};
|
||||
int i;
|
||||
|
||||
layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (view)));
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (names); i++)
|
||||
{
|
||||
constraint = (GtkConstraint*)g_object_get_data (G_OBJECT (guide), names[i]);
|
||||
gtk_constraint_layout_remove_constraint (layout, constraint);
|
||||
}
|
||||
|
||||
frame = (GtkWidget *)g_object_get_data (G_OBJECT (guide), "frame");
|
||||
update_weak_position (view, frame, -100, -100);
|
||||
gtk_widget_unparent (frame);
|
||||
|
||||
gtk_constraint_layout_remove_guide (layout, guide);
|
||||
}
|
||||
|
||||
void
|
||||
constraint_view_add_constraint (ConstraintView *view,
|
||||
GtkConstraint *constraint)
|
||||
{
|
||||
GtkLayoutManager *manager;
|
||||
|
||||
manager = gtk_widget_get_layout_manager (GTK_WIDGET (view));
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||
g_object_ref (constraint));
|
||||
}
|
||||
|
||||
void
|
||||
constraint_view_remove_constraint (ConstraintView *view,
|
||||
GtkConstraint *constraint)
|
||||
{
|
||||
GtkLayoutManager *manager;
|
||||
|
||||
manager = gtk_widget_get_layout_manager (GTK_WIDGET (view));
|
||||
gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||
constraint);
|
||||
}
|
||||
|
||||
GListModel *
|
||||
constraint_view_get_model (ConstraintView *view)
|
||||
{
|
||||
return view->model;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define CONSTRAINT_VIEW_TYPE (constraint_view_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintView, constraint_view, CONSTRAINT, VIEW, GtkWidget)
|
||||
|
||||
ConstraintView * constraint_view_new (void);
|
||||
|
||||
void constraint_view_add_child (ConstraintView *view,
|
||||
const char *name);
|
||||
void constraint_view_remove_child (ConstraintView *view,
|
||||
GtkWidget *child);
|
||||
void constraint_view_add_guide (ConstraintView *view,
|
||||
GtkConstraintGuide *guide);
|
||||
void constraint_view_remove_guide (ConstraintView *view,
|
||||
GtkConstraintGuide *guide);
|
||||
void constraint_view_guide_changed (ConstraintView *view,
|
||||
GtkConstraintGuide *guide);
|
||||
void constraint_view_add_constraint (ConstraintView *view,
|
||||
GtkConstraint *constraint);
|
||||
void constraint_view_remove_constraint (ConstraintView *view,
|
||||
GtkConstraint *constraint);
|
||||
GListModel * constraint_view_get_model (ConstraintView *view);
|
||||
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "guide-editor.h"
|
||||
|
||||
struct _GuideEditor
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *grid;
|
||||
GtkWidget *name;
|
||||
GtkWidget *min_width;
|
||||
GtkWidget *min_height;
|
||||
GtkWidget *nat_width;
|
||||
GtkWidget *nat_height;
|
||||
GtkWidget *max_width;
|
||||
GtkWidget *max_height;
|
||||
GtkWidget *strength;
|
||||
GtkWidget *button;
|
||||
|
||||
GtkConstraintGuide *guide;
|
||||
|
||||
gboolean constructed;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_GUIDE = 1,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static GParamSpec *pspecs[LAST_PROP];
|
||||
|
||||
enum {
|
||||
DONE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
G_DEFINE_TYPE(GuideEditor, guide_editor, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
guide_strength_combo (GtkWidget *combo)
|
||||
{
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "weak", "Weak");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "medium", "Medium");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "strong", "Strong");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "required", "Required");
|
||||
}
|
||||
|
||||
static GtkConstraintStrength
|
||||
get_strength (const char *id)
|
||||
{
|
||||
GtkConstraintStrength strength;
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
|
||||
GEnumValue *value = g_enum_get_value_by_nick (class, id);
|
||||
strength = value->value;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return strength;
|
||||
}
|
||||
|
||||
const char *
|
||||
get_strength_nick (GtkConstraintStrength strength)
|
||||
{
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
|
||||
GEnumValue *value = g_enum_get_value (class, strength);
|
||||
const char *nick = value->value_nick;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return nick;
|
||||
}
|
||||
|
||||
void
|
||||
guide_editor_serialize_guide (GString *str,
|
||||
int indent,
|
||||
GtkConstraintGuide *guide)
|
||||
{
|
||||
int min_width, min_height;
|
||||
int nat_width, nat_height;
|
||||
int max_width, max_height;
|
||||
const char *name;
|
||||
const char *strength;
|
||||
|
||||
gtk_constraint_guide_get_min_size (guide, &min_width, &min_height);
|
||||
gtk_constraint_guide_get_nat_size (guide, &nat_width, &nat_height);
|
||||
gtk_constraint_guide_get_max_size (guide, &max_width, &max_height);
|
||||
name = gtk_constraint_guide_get_name (guide);
|
||||
strength = get_strength_nick (gtk_constraint_guide_get_strength (guide));
|
||||
|
||||
g_string_append_printf (str, "%*s<guide min-width=\"%d\" min-height=\"%d\"\n", indent, "", min_width, min_height);
|
||||
g_string_append_printf (str, "%*s nat-width=\"%d\" nat-height=\"%d\"\n", indent, "", nat_width, nat_height);
|
||||
g_string_append_printf (str, "%*s max-width=\"%d\" max-height=\"%d\"\n", indent, "", max_width, max_height);
|
||||
g_string_append_printf (str, "%*s name=\"%s\" strength=\"%s\" />\n", indent, "", name, strength);
|
||||
}
|
||||
|
||||
static void
|
||||
create_guide (GtkButton *button,
|
||||
GuideEditor *editor)
|
||||
{
|
||||
const char *id;
|
||||
int strength;
|
||||
const char *name;
|
||||
int w, h;
|
||||
GtkConstraintGuide *guide;
|
||||
|
||||
if (editor->guide)
|
||||
guide = g_object_ref (editor->guide);
|
||||
else
|
||||
guide = gtk_constraint_guide_new ();
|
||||
|
||||
name = gtk_editable_get_text (GTK_EDITABLE (editor->name));
|
||||
gtk_constraint_guide_set_name (guide, name);
|
||||
|
||||
w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->min_width));
|
||||
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->min_height));
|
||||
gtk_constraint_guide_set_min_size (guide, w, h);
|
||||
|
||||
w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->nat_width));
|
||||
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->nat_height));
|
||||
gtk_constraint_guide_set_nat_size (guide, w, h);
|
||||
|
||||
w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->max_width));
|
||||
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->max_height));
|
||||
gtk_constraint_guide_set_max_size (guide, w, h);
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->strength));
|
||||
strength = get_strength (id);
|
||||
gtk_constraint_guide_set_strength (guide, strength);
|
||||
|
||||
g_signal_emit (editor, signals[DONE], 0, guide);
|
||||
g_object_unref (guide);
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_init (GuideEditor *editor)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (editor));
|
||||
}
|
||||
|
||||
static int guide_counter;
|
||||
|
||||
static int
|
||||
min_input (GtkSpinButton *spin_button,
|
||||
double *new_val)
|
||||
{
|
||||
if (strcmp (gtk_editable_get_text (GTK_EDITABLE (spin_button)), "") == 0)
|
||||
{
|
||||
*new_val = 0.0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
max_input (GtkSpinButton *spin_button,
|
||||
double *new_val)
|
||||
{
|
||||
if (strcmp (gtk_editable_get_text (GTK_EDITABLE (spin_button)), "") == 0)
|
||||
{
|
||||
*new_val = G_MAXINT;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
min_output (GtkSpinButton *spin_button)
|
||||
{
|
||||
GtkAdjustment *adjustment;
|
||||
double value;
|
||||
GtkWidget *box, *text;
|
||||
|
||||
adjustment = gtk_spin_button_get_adjustment (spin_button);
|
||||
value = gtk_adjustment_get_value (adjustment);
|
||||
|
||||
box = gtk_widget_get_first_child (GTK_WIDGET (spin_button));
|
||||
text = gtk_widget_get_first_child (box);
|
||||
|
||||
if (value == 0.0)
|
||||
{
|
||||
gtk_editable_set_text (GTK_EDITABLE (spin_button), "");
|
||||
gtk_text_set_placeholder_text (GTK_TEXT (text), "unset");
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_text_set_placeholder_text (GTK_TEXT (text), "");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
max_output (GtkSpinButton *spin_button)
|
||||
{
|
||||
GtkAdjustment *adjustment;
|
||||
double value;
|
||||
GtkWidget *box, *text;
|
||||
|
||||
adjustment = gtk_spin_button_get_adjustment (spin_button);
|
||||
value = gtk_adjustment_get_value (adjustment);
|
||||
|
||||
box = gtk_widget_get_first_child (GTK_WIDGET (spin_button));
|
||||
text = gtk_widget_get_first_child (box);
|
||||
|
||||
if (value == (double)G_MAXINT)
|
||||
{
|
||||
gtk_editable_set_text (GTK_EDITABLE (spin_button), "");
|
||||
gtk_text_set_placeholder_text (GTK_TEXT (text), "unset");
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_text_set_placeholder_text (GTK_TEXT (text), "");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_constructed (GObject *object)
|
||||
{
|
||||
GuideEditor *editor = GUIDE_EDITOR (object);
|
||||
|
||||
guide_strength_combo (editor->strength);
|
||||
|
||||
g_signal_connect (editor->min_width, "input", G_CALLBACK (min_input), NULL);
|
||||
g_signal_connect (editor->min_width, "output", G_CALLBACK (min_output), NULL);
|
||||
|
||||
g_signal_connect (editor->min_height, "input", G_CALLBACK (min_input), NULL);
|
||||
g_signal_connect (editor->min_height, "output", G_CALLBACK (min_output), NULL);
|
||||
|
||||
g_signal_connect (editor->max_width, "input", G_CALLBACK (max_input), NULL);
|
||||
g_signal_connect (editor->max_width, "output", G_CALLBACK (max_output), NULL);
|
||||
|
||||
g_signal_connect (editor->max_height, "input", G_CALLBACK (max_input), NULL);
|
||||
g_signal_connect (editor->max_height, "output", G_CALLBACK (max_output), NULL);
|
||||
|
||||
if (editor->guide)
|
||||
{
|
||||
GtkConstraintStrength strength;
|
||||
const char *nick;
|
||||
int w, h;
|
||||
|
||||
nick = gtk_constraint_guide_get_name (editor->guide);
|
||||
if (nick)
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->name), nick);
|
||||
|
||||
gtk_constraint_guide_get_min_size (editor->guide, &w, &h);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_width), w);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_height), h);
|
||||
|
||||
gtk_constraint_guide_get_nat_size (editor->guide, &w, &h);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_width), w);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_height), h);
|
||||
|
||||
gtk_constraint_guide_get_max_size (editor->guide, &w, &h);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_width), w);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_height), h);
|
||||
|
||||
strength = gtk_constraint_guide_get_strength (editor->guide);
|
||||
nick = get_strength_nick (strength);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), nick);
|
||||
|
||||
gtk_button_set_label (GTK_BUTTON (editor->button), "Apply");
|
||||
}
|
||||
else
|
||||
{
|
||||
char *name;
|
||||
|
||||
guide_counter++;
|
||||
name = g_strdup_printf ("Guide %d", guide_counter);
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->name), name);
|
||||
g_free (name);
|
||||
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_width), 0.0);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_height), 0.0);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_width), 0.0);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_height), 0.0);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_width), G_MAXINT);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_height), G_MAXINT);
|
||||
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), "medium");
|
||||
|
||||
gtk_button_set_label (GTK_BUTTON (editor->button), "Create");
|
||||
}
|
||||
|
||||
editor->constructed = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GuideEditor *self = GUIDE_EDITOR (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_GUIDE:
|
||||
self->guide = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GuideEditor *self = GUIDE_EDITOR (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_GUIDE:
|
||||
g_value_set_object (value, self->guide);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_dispose (GObject *object)
|
||||
{
|
||||
GuideEditor *self = (GuideEditor *)object;
|
||||
|
||||
g_clear_pointer (&self->grid, gtk_widget_unparent);
|
||||
g_clear_object (&self->guide);
|
||||
|
||||
G_OBJECT_CLASS (guide_editor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_class_init (GuideEditorClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
object_class->constructed = guide_editor_constructed;
|
||||
object_class->dispose = guide_editor_dispose;
|
||||
object_class->set_property = guide_editor_set_property;
|
||||
object_class->get_property = guide_editor_get_property;
|
||||
|
||||
pspecs[PROP_GUIDE] =
|
||||
g_param_spec_object ("guide", "guide", "guide",
|
||||
GTK_TYPE_CONSTRAINT_GUIDE,
|
||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, pspecs);
|
||||
|
||||
signals[DONE] =
|
||||
g_signal_new ("done",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 1, GTK_TYPE_CONSTRAINT_GUIDE);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
"/org/gtk/gtk4/constraint-editor/guide-editor.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, grid);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, name);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, min_width);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, min_height);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, nat_width);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, nat_height);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, max_width);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, max_height);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, strength);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, button);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, create_guide);
|
||||
}
|
||||
|
||||
GuideEditor *
|
||||
guide_editor_new (GtkConstraintGuide *guide)
|
||||
{
|
||||
return g_object_new (GUIDE_EDITOR_TYPE,
|
||||
"guide", guide,
|
||||
NULL);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define GUIDE_EDITOR_TYPE (guide_editor_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GuideEditor, guide_editor, GUIDE, EDITOR, GtkWidget)
|
||||
|
||||
GuideEditor * guide_editor_new (GtkConstraintGuide *guide);
|
||||
|
||||
void guide_editor_serialize_guide (GString *str,
|
||||
int indent,
|
||||
GtkConstraintGuide *guide);
|
||||
@@ -0,0 +1,188 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkAdjustment" id="min_width_adj">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">2147483647</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
<property name="page-size">0</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="min_height_adj">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">2147483647</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
<property name="page-size">0</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="nat_width_adj">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">2147483647</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
<property name="page-size">0</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="nat_height_adj">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">2147483647</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
<property name="page-size">0</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="max_width_adj">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">2147483647</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
<property name="page-size">0</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="max_height_adj">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">2147483647</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
<property name="page-size">0</property>
|
||||
</object>
|
||||
<template class="GuideEditor" parent="GtkWidget">
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid">
|
||||
<property name="margin">20</property>
|
||||
<property name="row-spacing">10</property>
|
||||
<property name="column-spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Name</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="name">
|
||||
<property name="max-width-chars">20</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Min Size</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="min_width">
|
||||
<property name="adjustment">min_width_adj</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="min_height">
|
||||
<property name="adjustment">min_height_adj</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<layout>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Nat Size</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="nat_width">
|
||||
<property name="adjustment">nat_width_adj</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="nat_height">
|
||||
<property name="adjustment">nat_height_adj</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<layout>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Max Size</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="max_width">
|
||||
<property name="adjustment">max_width_adj</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="max_height">
|
||||
<property name="adjustment">max_height_adj</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<layout>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Strength</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="strength">
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">4</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button">
|
||||
<property name="label">Create</property>
|
||||
<signal name="clicked" handler="create_guide"/>
|
||||
<layout>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">5</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen <mclasen@redhat.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <constraint-editor-application.h>
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
return g_application_run (G_APPLICATION (constraint_editor_application_new ()), argc, argv);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
constraint_editor_sources = [
|
||||
'main.c',
|
||||
'constraint-editor-application.c',
|
||||
'constraint-editor-window.c',
|
||||
'constraint-view.c',
|
||||
'constraint-editor.c',
|
||||
'guide-editor.c',
|
||||
]
|
||||
|
||||
constraint_editor_resources = gnome.compile_resources('constraint_editor_resources',
|
||||
'constraint-editor.gresource.xml',
|
||||
source_dir: '.')
|
||||
|
||||
executable('gtk4-constraint-editor',
|
||||
constraint_editor_sources, constraint_editor_resources,
|
||||
dependencies: libgtk_dep,
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
install: false)
|
||||
@@ -1,128 +1,110 @@
|
||||
/* Constraints/Grid
|
||||
/* Constraints/VFL
|
||||
*
|
||||
* GtkConstraintLayout lets you define complex layouts
|
||||
* like grids.
|
||||
* GtkConstraintLayout allows defining constraints using a
|
||||
* compact syntax called Visual Format Language, or VFL.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ComplexGrid, complex_grid, COMPLEX, GRID, GtkWidget)
|
||||
G_DECLARE_FINAL_TYPE (VflGrid, vfl_grid, VFL, GRID, GtkWidget)
|
||||
|
||||
struct _ComplexGrid
|
||||
struct _VflGrid
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *button1, *button2, *button3;
|
||||
GtkWidget *button4, *button5;
|
||||
GtkWidget *button1, *button2;
|
||||
GtkWidget *button3;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ComplexGrid, complex_grid, GTK_TYPE_WIDGET)
|
||||
G_DEFINE_TYPE (VflGrid, vfl_grid, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
complex_grid_destroy (GtkWidget *widget)
|
||||
vfl_grid_destroy (GtkWidget *widget)
|
||||
{
|
||||
ComplexGrid *self = COMPLEX_GRID (widget);
|
||||
VflGrid *self = VFL_GRID (widget);
|
||||
|
||||
g_clear_pointer (&self->button1, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button2, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button3, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button4, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button5, gtk_widget_destroy);
|
||||
|
||||
GTK_WIDGET_CLASS (complex_grid_parent_class)->destroy (widget);
|
||||
GTK_WIDGET_CLASS (vfl_grid_parent_class)->destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
complex_grid_class_init (ComplexGridClass *klass)
|
||||
vfl_grid_class_init (VflGridClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
widget_class->destroy = complex_grid_destroy;
|
||||
widget_class->destroy = vfl_grid_destroy;
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
|
||||
}
|
||||
|
||||
/* Layout:
|
||||
*
|
||||
* +--------------------------------------+
|
||||
* | +-----------+ |
|
||||
* | | Child 4 | |
|
||||
* | +-----------+-----------+----------+ |
|
||||
* | | Child 1 | Child 2 | Child 3 | |
|
||||
* | +-----------+-----------+----------+ |
|
||||
* | | Child 5 | |
|
||||
* | +-----------+ |
|
||||
* +--------------------------------------+
|
||||
* +-----------------------------+
|
||||
* | +-----------+ +-----------+ |
|
||||
* | | Child 1 | | Child 2 | |
|
||||
* | +-----------+ +-----------+ |
|
||||
* | +-------------------------+ |
|
||||
* | | Child 3 | |
|
||||
* | +-------------------------+ |
|
||||
* +-----------------------------+
|
||||
*
|
||||
* Constraints:
|
||||
*
|
||||
* super.start = child1.start - 8
|
||||
* child1.width = child2.width
|
||||
* child1.end = child2.start - 12
|
||||
* child2.end = super.end - 8
|
||||
* super.start = child3.start - 8
|
||||
* child3.end = super.end - 8
|
||||
* super.top = child1.top - 8
|
||||
* super.top = child2.top - 8
|
||||
* child1.bottom = child3.top - 12
|
||||
* child2.bottom = child3.top - 12
|
||||
* child3.height = child1.height
|
||||
* child3.height = child2.height
|
||||
* child3.bottom = super.bottom - 8
|
||||
*
|
||||
* Visual format:
|
||||
*
|
||||
* H:|-8-[view1(==view2)-12-[view2]-8-|
|
||||
* H:|-8-[view3]-8-|
|
||||
* V:|-8-[view1]-12-[view3(==view1)]-8-|
|
||||
* V:|-8-[view2]-12-[view3(==view2)]-8-|
|
||||
*/
|
||||
static void
|
||||
build_constraints (ComplexGrid *self,
|
||||
build_constraints (VflGrid *self,
|
||||
GtkConstraintLayout *manager)
|
||||
{
|
||||
GtkGridConstraint *constraint;
|
||||
GtkConstraint *s;
|
||||
const char * const vfl[] = {
|
||||
"H:|-[button1(==button2)]-12-[button2]-|",
|
||||
"H:|-[button3]-|",
|
||||
"V:|-[button1]-12-[button3(==button1)]-|",
|
||||
"V:|-[button2]-12-[button3(==button2)]-|",
|
||||
};
|
||||
GError *error = NULL;
|
||||
|
||||
s = gtk_constraint_new (NULL, GTK_CONSTRAINT_ATTRIBUTE_LEFT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button1, GTK_CONSTRAINT_ATTRIBUTE_LEFT,
|
||||
1.0, 0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (manager, s);
|
||||
|
||||
s = gtk_constraint_new (self->button3, GTK_CONSTRAINT_ATTRIBUTE_RIGHT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
NULL, GTK_CONSTRAINT_ATTRIBUTE_RIGHT,
|
||||
1.0, 0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (manager, s);
|
||||
|
||||
s = gtk_constraint_new (NULL, GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button4, GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0, 0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (manager, s);
|
||||
|
||||
s = gtk_constraint_new (NULL, GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button5, GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
1.0, 0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (manager, s);
|
||||
|
||||
constraint = gtk_grid_constraint_new ();
|
||||
g_object_set (constraint, "column-homogeneous", TRUE, NULL);
|
||||
gtk_grid_constraint_add (constraint,
|
||||
self->button1,
|
||||
0, 1, 0, 1);
|
||||
gtk_grid_constraint_add (constraint,
|
||||
self->button2,
|
||||
1, 2, 0, 1);
|
||||
gtk_grid_constraint_add (constraint,
|
||||
self->button3,
|
||||
2, 3, 0, 1);
|
||||
gtk_constraint_layout_add_grid_constraint (manager, constraint);
|
||||
|
||||
constraint = gtk_grid_constraint_new ();
|
||||
g_object_set (constraint, "row-homogeneous", TRUE, NULL);
|
||||
gtk_grid_constraint_add (constraint,
|
||||
self->button4,
|
||||
0, 1, 0, 1);
|
||||
gtk_grid_constraint_add (constraint,
|
||||
self->button2,
|
||||
0, 1, 1, 2);
|
||||
gtk_grid_constraint_add (constraint,
|
||||
self->button5,
|
||||
0, 1, 2, 3);
|
||||
gtk_constraint_layout_add_grid_constraint (manager, constraint);
|
||||
gtk_constraint_layout_add_constraints_from_description (manager, vfl, G_N_ELEMENTS (vfl),
|
||||
8, 8,
|
||||
&error,
|
||||
"button1", self->button1,
|
||||
"button2", self->button2,
|
||||
"button3", self->button3,
|
||||
NULL);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_printerr ("VFL parsing error:\n%s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
complex_grid_init (ComplexGrid *self)
|
||||
vfl_grid_init (VflGrid *self)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (self);
|
||||
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
||||
|
||||
self->button1 = gtk_button_new_with_label ("Child 1");
|
||||
gtk_widget_set_parent (self->button1, widget);
|
||||
@@ -136,14 +118,7 @@ complex_grid_init (ComplexGrid *self)
|
||||
gtk_widget_set_parent (self->button3, widget);
|
||||
gtk_widget_set_name (self->button3, "button3");
|
||||
|
||||
self->button4 = gtk_button_new_with_label ("Child 4");
|
||||
gtk_widget_set_parent (self->button4, widget);
|
||||
gtk_widget_set_name (self->button4, "button4");
|
||||
|
||||
self->button5 = gtk_button_new_with_label ("Child 5");
|
||||
gtk_widget_set_parent (self->button5, widget);
|
||||
gtk_widget_set_name (self->button5, "button5");
|
||||
|
||||
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
||||
build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
|
||||
}
|
||||
|
||||
@@ -169,7 +144,7 @@ do_constraints3 (GtkWidget *do_widget)
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
|
||||
grid = g_object_new (complex_grid_get_type (), NULL);
|
||||
grid = g_object_new (vfl_grid_get_type (), NULL);
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
gtk_widget_set_vexpand (grid, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (box), grid);
|
||||
|
||||
+112
-289
@@ -1,296 +1,138 @@
|
||||
/* Constraints/Words
|
||||
/* Constraints/Grid
|
||||
*
|
||||
* GtkConstraintLayout lets you define big grids.
|
||||
* GtkConstraintLayout lets you define complex layouts
|
||||
* like grids.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define WORDS_TYPE_BASE (words_base_get_type ())
|
||||
#define WORDS_TYPE_GRID (words_grid_get_type ())
|
||||
#define WORDS_TYPE_CONSTRAINT (words_constraint_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (ComplexGrid, complex_grid, COMPLEX, GRID, GtkWidget)
|
||||
|
||||
typedef struct
|
||||
struct _ComplexGrid
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
} WordsBase;
|
||||
|
||||
typedef WordsBase WordsGrid;
|
||||
typedef WordsBase WordsConstraint;
|
||||
GtkWidget *button1, *button2, *button3;
|
||||
GtkWidget *button4, *button5;
|
||||
};
|
||||
|
||||
typedef GtkWidgetClass WordsBaseClass;
|
||||
typedef GtkWidgetClass WordsGridClass;
|
||||
typedef GtkWidgetClass WordsConstraintClass;
|
||||
|
||||
G_DEFINE_TYPE (WordsBase, words_base, GTK_TYPE_WIDGET)
|
||||
G_DEFINE_TYPE (WordsGrid, words_grid, WORDS_TYPE_BASE)
|
||||
G_DEFINE_TYPE (WordsConstraint, words_constraint, WORDS_TYPE_BASE)
|
||||
G_DEFINE_TYPE (ComplexGrid, complex_grid, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
words_grid_init (WordsGrid *words)
|
||||
complex_grid_destroy (GtkWidget *widget)
|
||||
{
|
||||
ComplexGrid *self = COMPLEX_GRID (widget);
|
||||
|
||||
g_clear_pointer (&self->button1, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button2, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button3, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button4, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button5, gtk_widget_destroy);
|
||||
|
||||
GTK_WIDGET_CLASS (complex_grid_parent_class)->destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
words_grid_class_init (WordsGridClass *class)
|
||||
complex_grid_class_init (ComplexGridClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_GRID_LAYOUT);
|
||||
}
|
||||
|
||||
static void
|
||||
words_constraint_init (WordsGrid *words)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
words_constraint_class_init (WordsConstraintClass *class)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
widget_class->destroy = complex_grid_destroy;
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
|
||||
}
|
||||
|
||||
/* Layout:
|
||||
*
|
||||
* +--------------------------------------+
|
||||
* | +-----------+ |
|
||||
* | | Child 4 | |
|
||||
* | +-----------+-----------+----------+ |
|
||||
* | | Child 1 | Child 2 | Child 3 | |
|
||||
* | +-----------+-----------+----------+ |
|
||||
* | | Child 5 | |
|
||||
* | +-----------+ |
|
||||
* +--------------------------------------+
|
||||
*
|
||||
*/
|
||||
static void
|
||||
word_base_dispose (GObject *object)
|
||||
build_constraints (ComplexGrid *self,
|
||||
GtkConstraintLayout *manager)
|
||||
{
|
||||
GtkWidget *self = GTK_WIDGET (object);
|
||||
GtkWidget *child;
|
||||
GtkGridConstraint *constraint;
|
||||
GtkConstraint *s;
|
||||
|
||||
while ((child = gtk_widget_get_first_child (self)) != NULL)
|
||||
gtk_widget_unparent (child);
|
||||
s = gtk_constraint_new (NULL, GTK_CONSTRAINT_ATTRIBUTE_LEFT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button1, GTK_CONSTRAINT_ATTRIBUTE_LEFT,
|
||||
1.0, 0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (manager, s);
|
||||
|
||||
G_OBJECT_CLASS (words_base_parent_class)->dispose (object);
|
||||
s = gtk_constraint_new (self->button3, GTK_CONSTRAINT_ATTRIBUTE_RIGHT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
NULL, GTK_CONSTRAINT_ATTRIBUTE_RIGHT,
|
||||
1.0, 0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (manager, s);
|
||||
|
||||
s = gtk_constraint_new (NULL, GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button4, GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0, 0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (manager, s);
|
||||
|
||||
s = gtk_constraint_new (NULL, GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button5, GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
1.0, 0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (manager, s);
|
||||
|
||||
constraint = gtk_grid_constraint_new ();
|
||||
g_object_set (constraint, "column-homogeneous", TRUE, NULL);
|
||||
gtk_grid_constraint_add (constraint, self->button1, 0, 1, 0, 1);
|
||||
gtk_grid_constraint_add (constraint, self->button2, 1, 2, 0, 1);
|
||||
gtk_grid_constraint_add (constraint, self->button3, 2, 3, 0, 1);
|
||||
gtk_grid_constraint_attach (constraint, manager);
|
||||
|
||||
constraint = gtk_grid_constraint_new ();
|
||||
g_object_set (constraint, "row-homogeneous", TRUE, NULL);
|
||||
gtk_grid_constraint_add (constraint, self->button4, 0, 1, 0, 1);
|
||||
gtk_grid_constraint_add (constraint, self->button2, 0, 1, 1, 2);
|
||||
gtk_grid_constraint_add (constraint, self->button5, 0, 1, 2, 3);
|
||||
gtk_grid_constraint_attach (constraint, manager);
|
||||
}
|
||||
|
||||
static void
|
||||
words_base_class_init (WordsBaseClass *klass)
|
||||
complex_grid_init (ComplexGrid *self)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidget *widget = GTK_WIDGET (self);
|
||||
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
||||
|
||||
object_class->dispose = word_base_dispose;
|
||||
}
|
||||
self->button1 = gtk_button_new_with_label ("Child 1");
|
||||
gtk_widget_set_parent (self->button1, widget);
|
||||
gtk_widget_set_name (self->button1, "button1");
|
||||
|
||||
static int num_words = 100;
|
||||
static gboolean use_constraints = FALSE;
|
||||
self->button2 = gtk_button_new_with_label ("Child 2");
|
||||
gtk_widget_set_parent (self->button2, widget);
|
||||
gtk_widget_set_name (self->button2, "button2");
|
||||
|
||||
static void
|
||||
read_words (WordsBase *self)
|
||||
{
|
||||
GBytes *data;
|
||||
const char *words;
|
||||
int left, top;
|
||||
GtkWidget *child = NULL;
|
||||
GtkLayoutManager *layout = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
||||
GtkGridConstraint *grid;
|
||||
GtkConstraint *constraint;
|
||||
int count;
|
||||
int rightmost;
|
||||
GtkWidget *right_child = NULL;
|
||||
gboolean use_constraint = GTK_IS_CONSTRAINT_LAYOUT (layout);
|
||||
self->button3 = gtk_button_new_with_label ("Child 3");
|
||||
gtk_widget_set_parent (self->button3, widget);
|
||||
gtk_widget_set_name (self->button3, "button3");
|
||||
|
||||
if (use_constraint)
|
||||
{
|
||||
grid = gtk_grid_constraint_new ();
|
||||
g_object_set (grid,
|
||||
"row-homogeneous", TRUE,
|
||||
"column-homogeneous", FALSE,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_grid_layout_set_row_homogeneous (GTK_GRID_LAYOUT (layout), TRUE);
|
||||
gtk_grid_layout_set_column_homogeneous (GTK_GRID_LAYOUT (layout), FALSE);
|
||||
}
|
||||
self->button4 = gtk_button_new_with_label ("Child 4");
|
||||
gtk_widget_set_parent (self->button4, widget);
|
||||
gtk_widget_set_name (self->button4, "button4");
|
||||
|
||||
data = g_resources_lookup_data ("/constraints4/words", 0, NULL);
|
||||
words = g_bytes_get_data (data, NULL);
|
||||
count = 0;
|
||||
self->button5 = gtk_button_new_with_label ("Child 5");
|
||||
gtk_widget_set_parent (self->button5, widget);
|
||||
gtk_widget_set_name (self->button5, "button5");
|
||||
|
||||
rightmost = 0;
|
||||
left = 0;
|
||||
top = 0;
|
||||
while (words && words[0])
|
||||
{
|
||||
char *p = strchr (words, '\n');
|
||||
char *word;
|
||||
int len;
|
||||
|
||||
if (p)
|
||||
{
|
||||
word = strndup (words, p - words);
|
||||
words = p + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
word = strdup (words);
|
||||
words = NULL;
|
||||
}
|
||||
|
||||
len = strlen (word);
|
||||
child = gtk_button_new_with_label (word);
|
||||
|
||||
if (left + len > 50)
|
||||
{
|
||||
top++;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
gtk_widget_set_parent (child, GTK_WIDGET (self));
|
||||
|
||||
if (left + len > rightmost)
|
||||
{
|
||||
rightmost = left + len;
|
||||
right_child = child;
|
||||
}
|
||||
|
||||
if (use_constraint)
|
||||
{
|
||||
gtk_grid_constraint_add (grid, child,
|
||||
left, left + len,
|
||||
top, top + 1);
|
||||
if (left == 0 && top == 0)
|
||||
{
|
||||
constraint = gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (layout),
|
||||
constraint);
|
||||
constraint = gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_LEFT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_LEFT,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (layout),
|
||||
constraint);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkGridLayoutChild *grid_child = GTK_GRID_LAYOUT_CHILD (gtk_layout_manager_get_layout_child (layout, child));
|
||||
|
||||
g_object_set (grid_child,
|
||||
"left-attach", left,
|
||||
"top-attach", top,
|
||||
"column-span", len,
|
||||
"row-span", 1,
|
||||
NULL);
|
||||
}
|
||||
|
||||
left = left + len;
|
||||
count++;
|
||||
|
||||
if (count >= num_words)
|
||||
break;
|
||||
}
|
||||
|
||||
if (use_constraint)
|
||||
{
|
||||
constraint = gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_RIGHT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
right_child,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_RIGHT,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (layout),
|
||||
constraint);
|
||||
constraint = gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (layout),
|
||||
constraint);
|
||||
|
||||
gtk_constraint_layout_add_grid_constraint (GTK_CONSTRAINT_LAYOUT (layout),
|
||||
grid);
|
||||
}
|
||||
|
||||
g_bytes_unref (data);
|
||||
}
|
||||
|
||||
static void
|
||||
words_base_init (WordsBase *self)
|
||||
{
|
||||
read_words (self);
|
||||
}
|
||||
|
||||
static void
|
||||
show_words (GtkWidget *parent)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *header, *box, *grid, *button;
|
||||
GtkWidget *swin;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window),
|
||||
GTK_WINDOW (gtk_widget_get_root (parent)));
|
||||
gtk_window_set_modal (GTK_WINDOW (window), TRUE);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (header), use_constraints ? "Constraints" : "Grid");
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
|
||||
swin = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_propagate_natural_width (GTK_SCROLLED_WINDOW (swin), TRUE);
|
||||
gtk_scrolled_window_set_propagate_natural_height (GTK_SCROLLED_WINDOW (swin), TRUE);
|
||||
gtk_widget_set_hexpand (swin, TRUE);
|
||||
gtk_widget_set_vexpand (swin, TRUE);
|
||||
gtk_widget_set_halign (swin, GTK_ALIGN_FILL);
|
||||
gtk_widget_set_valign (swin, GTK_ALIGN_FILL);
|
||||
gtk_container_add (GTK_CONTAINER (box), swin);
|
||||
|
||||
if (use_constraints)
|
||||
grid = g_object_new (WORDS_TYPE_CONSTRAINT, NULL);
|
||||
else
|
||||
grid = g_object_new (WORDS_TYPE_GRID, NULL);
|
||||
|
||||
gtk_widget_set_halign (swin, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (swin, GTK_ALIGN_START);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (swin), grid);
|
||||
|
||||
button = gtk_button_new_with_label ("Close");
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (gtk_widget_destroy), window);
|
||||
|
||||
gtk_widget_show (window);
|
||||
}
|
||||
|
||||
static void
|
||||
use_constraints_cb (GtkButton *button)
|
||||
{
|
||||
use_constraints = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
|
||||
}
|
||||
|
||||
static void
|
||||
word_count_cb (GtkSpinButton *button)
|
||||
{
|
||||
num_words = gtk_spin_button_get_value_as_int (button);
|
||||
build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
@@ -300,50 +142,31 @@ do_constraints4 (GtkWidget *do_widget)
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *header, *grid, *button, *label;
|
||||
GtkWidget *header, *box, *grid, *button;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Words");
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Constraints");
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
g_object_set (grid,
|
||||
"margin", 12,
|
||||
"row-spacing", 12,
|
||||
"column-spacing", 6,
|
||||
"halign", GTK_ALIGN_FILL,
|
||||
"valign", GTK_ALIGN_FILL,
|
||||
"hexpand", TRUE,
|
||||
"vexpand", TRUE,
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), grid);
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
|
||||
label = gtk_label_new ("Constraints:");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1.0);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
|
||||
button = gtk_check_button_new ();
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (use_constraints_cb), NULL);
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 1, 0, 1, 1);
|
||||
label = gtk_label_new ("Words:");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1.0);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
|
||||
button = gtk_spin_button_new_with_range (0, 1300, 1);
|
||||
g_signal_connect (button, "value-changed", G_CALLBACK (word_count_cb), NULL);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (button), 10);
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 1, 1, 1, 1);
|
||||
grid = g_object_new (complex_grid_get_type (), NULL);
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
gtk_widget_set_vexpand (grid, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (box), grid);
|
||||
|
||||
button = gtk_button_new_with_label ("Show");
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_END);
|
||||
button = gtk_button_new_with_label ("Close");
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (show_words), window);
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 0, 2, 2, 1);
|
||||
G_CALLBACK (gtk_widget_destroy), window);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -0,0 +1,354 @@
|
||||
/* Constraints/Words
|
||||
*
|
||||
* GtkConstraintLayout lets you define big grids.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define WORDS_TYPE_BASE (words_base_get_type ())
|
||||
#define WORDS_TYPE_GRID (words_grid_get_type ())
|
||||
#define WORDS_TYPE_CONSTRAINT (words_constraint_get_type ())
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
} WordsBase;
|
||||
|
||||
typedef WordsBase WordsGrid;
|
||||
typedef WordsBase WordsConstraint;
|
||||
|
||||
typedef GtkWidgetClass WordsBaseClass;
|
||||
typedef GtkWidgetClass WordsGridClass;
|
||||
typedef GtkWidgetClass WordsConstraintClass;
|
||||
|
||||
G_DEFINE_TYPE (WordsBase, words_base, GTK_TYPE_WIDGET)
|
||||
G_DEFINE_TYPE (WordsGrid, words_grid, WORDS_TYPE_BASE)
|
||||
G_DEFINE_TYPE (WordsConstraint, words_constraint, WORDS_TYPE_BASE)
|
||||
|
||||
static void
|
||||
words_grid_init (WordsGrid *words)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
words_grid_class_init (WordsGridClass *class)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_GRID_LAYOUT);
|
||||
}
|
||||
|
||||
static void
|
||||
words_constraint_init (WordsGrid *words)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
words_constraint_class_init (WordsConstraintClass *class)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
|
||||
}
|
||||
|
||||
static void
|
||||
word_base_dispose (GObject *object)
|
||||
{
|
||||
GtkWidget *self = GTK_WIDGET (object);
|
||||
GtkWidget *child;
|
||||
|
||||
while ((child = gtk_widget_get_first_child (self)) != NULL)
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
G_OBJECT_CLASS (words_base_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
words_base_class_init (WordsBaseClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = word_base_dispose;
|
||||
}
|
||||
|
||||
static int num_words = 100;
|
||||
static gboolean use_constraints = FALSE;
|
||||
|
||||
static void
|
||||
read_words (WordsBase *self)
|
||||
{
|
||||
GBytes *data;
|
||||
const char *words;
|
||||
int left, top;
|
||||
GtkWidget *child = NULL;
|
||||
GtkLayoutManager *layout = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
||||
GtkGridConstraint *grid;
|
||||
GtkConstraint *constraint;
|
||||
int count;
|
||||
int rightmost;
|
||||
GtkWidget *right_child = NULL;
|
||||
gboolean use_constraint = GTK_IS_CONSTRAINT_LAYOUT (layout);
|
||||
|
||||
if (use_constraint)
|
||||
{
|
||||
grid = gtk_grid_constraint_new ();
|
||||
g_object_set (grid,
|
||||
"row-homogeneous", TRUE,
|
||||
"column-homogeneous", FALSE,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_grid_layout_set_row_homogeneous (GTK_GRID_LAYOUT (layout), TRUE);
|
||||
gtk_grid_layout_set_column_homogeneous (GTK_GRID_LAYOUT (layout), FALSE);
|
||||
}
|
||||
|
||||
data = g_resources_lookup_data ("/constraints5/words", 0, NULL);
|
||||
words = g_bytes_get_data (data, NULL);
|
||||
count = 0;
|
||||
|
||||
rightmost = 0;
|
||||
left = 0;
|
||||
top = 0;
|
||||
while (words && words[0])
|
||||
{
|
||||
char *p = strchr (words, '\n');
|
||||
char *word;
|
||||
int len;
|
||||
|
||||
if (p)
|
||||
{
|
||||
word = strndup (words, p - words);
|
||||
words = p + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
word = strdup (words);
|
||||
words = NULL;
|
||||
}
|
||||
|
||||
len = strlen (word);
|
||||
child = gtk_button_new_with_label (word);
|
||||
|
||||
if (left + len > 50)
|
||||
{
|
||||
top++;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
gtk_widget_set_parent (child, GTK_WIDGET (self));
|
||||
|
||||
if (left + len > rightmost)
|
||||
{
|
||||
rightmost = left + len;
|
||||
right_child = child;
|
||||
}
|
||||
|
||||
if (use_constraint)
|
||||
{
|
||||
gtk_grid_constraint_add (grid, child,
|
||||
left, left + len,
|
||||
top, top + 1);
|
||||
if (left == 0 && top == 0)
|
||||
{
|
||||
constraint = gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (layout),
|
||||
constraint);
|
||||
constraint = gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_LEFT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_LEFT,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (layout),
|
||||
constraint);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkGridLayoutChild *grid_child = GTK_GRID_LAYOUT_CHILD (gtk_layout_manager_get_layout_child (layout, child));
|
||||
|
||||
g_object_set (grid_child,
|
||||
"left-attach", left,
|
||||
"top-attach", top,
|
||||
"column-span", len,
|
||||
"row-span", 1,
|
||||
NULL);
|
||||
}
|
||||
|
||||
left = left + len;
|
||||
count++;
|
||||
|
||||
if (count >= num_words)
|
||||
break;
|
||||
}
|
||||
|
||||
if (use_constraint)
|
||||
{
|
||||
constraint = gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_RIGHT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
right_child,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_RIGHT,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (layout),
|
||||
constraint);
|
||||
constraint = gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (layout),
|
||||
constraint);
|
||||
|
||||
gtk_grid_constraint_attach (grid, GTK_CONSTRAINT_LAYOUT (layout));
|
||||
}
|
||||
|
||||
g_bytes_unref (data);
|
||||
}
|
||||
|
||||
static void
|
||||
words_base_init (WordsBase *self)
|
||||
{
|
||||
read_words (self);
|
||||
}
|
||||
|
||||
static void
|
||||
show_words (GtkWidget *parent)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *header, *box, *grid, *button;
|
||||
GtkWidget *swin;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window),
|
||||
GTK_WINDOW (gtk_widget_get_root (parent)));
|
||||
gtk_window_set_modal (GTK_WINDOW (window), TRUE);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (header), use_constraints ? "Constraints" : "Grid");
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
|
||||
swin = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_propagate_natural_width (GTK_SCROLLED_WINDOW (swin), TRUE);
|
||||
gtk_scrolled_window_set_propagate_natural_height (GTK_SCROLLED_WINDOW (swin), TRUE);
|
||||
gtk_widget_set_hexpand (swin, TRUE);
|
||||
gtk_widget_set_vexpand (swin, TRUE);
|
||||
gtk_widget_set_halign (swin, GTK_ALIGN_FILL);
|
||||
gtk_widget_set_valign (swin, GTK_ALIGN_FILL);
|
||||
gtk_container_add (GTK_CONTAINER (box), swin);
|
||||
|
||||
if (use_constraints)
|
||||
grid = g_object_new (WORDS_TYPE_CONSTRAINT, NULL);
|
||||
else
|
||||
grid = g_object_new (WORDS_TYPE_GRID, NULL);
|
||||
|
||||
gtk_widget_set_halign (swin, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (swin, GTK_ALIGN_START);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (swin), grid);
|
||||
|
||||
button = gtk_button_new_with_label ("Close");
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (gtk_widget_destroy), window);
|
||||
|
||||
gtk_widget_show (window);
|
||||
}
|
||||
|
||||
static void
|
||||
use_constraints_cb (GtkButton *button)
|
||||
{
|
||||
use_constraints = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
|
||||
}
|
||||
|
||||
static void
|
||||
word_count_cb (GtkSpinButton *button)
|
||||
{
|
||||
num_words = gtk_spin_button_get_value_as_int (button);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_constraints5 (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *header, *grid, *button, *label;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Words");
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
g_object_set (grid,
|
||||
"margin", 12,
|
||||
"row-spacing", 12,
|
||||
"column-spacing", 6,
|
||||
"halign", GTK_ALIGN_FILL,
|
||||
"valign", GTK_ALIGN_FILL,
|
||||
"hexpand", TRUE,
|
||||
"vexpand", TRUE,
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), grid);
|
||||
|
||||
label = gtk_label_new ("Constraints:");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1.0);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
|
||||
button = gtk_check_button_new ();
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (use_constraints_cb), NULL);
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 1, 0, 1, 1);
|
||||
label = gtk_label_new ("Words:");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1.0);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
|
||||
button = gtk_spin_button_new_with_range (0, 1300, 1);
|
||||
g_signal_connect (button, "value-changed", G_CALLBACK (word_count_cb), NULL);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (button), 10);
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 1, 1, 1, 1);
|
||||
|
||||
button = gtk_button_new_with_label ("Show");
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_END);
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (show_words), window);
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 0, 2, 2, 1);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -12,9 +12,6 @@
|
||||
<gresource prefix="/builder">
|
||||
<file>demo.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/constraints4">
|
||||
<file>words</file>
|
||||
</gresource>
|
||||
<gresource prefix="/css_accordion">
|
||||
<file>css_accordion.css</file>
|
||||
<file>reset.css</file>
|
||||
@@ -62,6 +59,9 @@
|
||||
<file>cssview.css</file>
|
||||
<file>reset.css</file>
|
||||
</gresource>
|
||||
<gresource prefix="/constraints5">
|
||||
<file>words</file>
|
||||
</gresource>
|
||||
<gresource prefix="/cursors">
|
||||
<file>cursors.ui</file>
|
||||
<file>alias_cursor.png</file>
|
||||
@@ -157,6 +157,7 @@
|
||||
<file>constraints2.c</file>
|
||||
<file>constraints3.c</file>
|
||||
<file>constraints4.c</file>
|
||||
<file>constraints5.c</file>
|
||||
<file>css_accordion.c</file>
|
||||
<file>css_basics.c</file>
|
||||
<file>css_blendmodes.c</file>
|
||||
|
||||
@@ -12,6 +12,7 @@ demos = files([
|
||||
'constraints2.c',
|
||||
'constraints3.c',
|
||||
'constraints4.c',
|
||||
'constraints5.c',
|
||||
'css_accordion.c',
|
||||
'css_basics.c',
|
||||
'css_blendmodes.c',
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,4 @@
|
||||
subdir('constraint-editor')
|
||||
subdir('gtk-demo')
|
||||
subdir('icon-browser')
|
||||
subdir('node-editor')
|
||||
|
||||
@@ -1707,7 +1707,7 @@ activate (GApplication *app)
|
||||
gtk_css_provider_load_from_resource (provider, "/org/gtk/WidgetFactory4/widget-factory.css");
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
g_object_unref (provider);
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/org/gtk/WidgetFactory4/widget-factory.ui");
|
||||
|
||||
@@ -99,7 +99,7 @@ if wayland_enabled
|
||||
src_dir += [ gdkwayland_inc ]
|
||||
endif
|
||||
|
||||
if get_option('documentation')
|
||||
if get_option('gtk_doc')
|
||||
configure_file(input: 'version.xml.in', output: 'version.xml', configuration: version_conf)
|
||||
|
||||
gnome.gtkdoc('gdk4',
|
||||
|
||||
@@ -34,7 +34,7 @@ private_headers = [
|
||||
images = [
|
||||
]
|
||||
|
||||
if get_option('documentation')
|
||||
if get_option('gtk_doc')
|
||||
configure_file(input: 'version.xml.in', output: 'version.xml', configuration: version_conf)
|
||||
|
||||
gnome.gtkdoc('gsk4',
|
||||
|
||||
@@ -355,8 +355,8 @@ How to compile GTK itself
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Ddocumentation=true</arg>
|
||||
<arg choice="plain">-Ddocumentation=false</arg>
|
||||
<arg choice="plain">-Dgtk_doc=true</arg>
|
||||
<arg choice="plain">-Dgtk_doc=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
@@ -382,7 +382,7 @@ How to compile GTK itself
|
||||
</formalpara>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>documentation</systemitem> and
|
||||
<title><systemitem>gtk_doc</systemitem> and
|
||||
<systemitem>man-pages</systemitem></title>
|
||||
|
||||
<para>
|
||||
@@ -394,7 +394,7 @@ How to compile GTK itself
|
||||
<application>gtk-doc</application> installed and
|
||||
are modifying GTK, you may want to enable
|
||||
<application>gtk-doc</application> support by passing
|
||||
in <systemitem>documentation</systemitem>.
|
||||
in <systemitem>gtk_doc</systemitem>.
|
||||
</para>
|
||||
<para>
|
||||
Additionally, some tools provided by GTK have their own
|
||||
|
||||
@@ -109,6 +109,9 @@
|
||||
<xi:include href="xml/gtkcustomlayout.xml" />
|
||||
<xi:include href="xml/gtkfixedlayout.xml" />
|
||||
<xi:include href="xml/gtkgridlayout.xml" />
|
||||
<xi:include href="xml/gtkconstraintlayout.xml" />
|
||||
<xi:include href="xml/gtkconstraint.xml" />
|
||||
<xi:include href="xml/gtkconstraintguide.xml" />
|
||||
</chapter>
|
||||
|
||||
<chapter id="DisplayWidgets">
|
||||
|
||||
@@ -7287,3 +7287,87 @@ gtk_grid_layout_get_type
|
||||
GTK_TYPE_GRID_LAYOUT_CHILD
|
||||
gtk_grid_layout_child_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkconstraint</FILE>
|
||||
GtkConstraint
|
||||
GtkConstraintTarget
|
||||
|
||||
gtk_constraint_new
|
||||
gtk_constraint_new_constant
|
||||
gtk_constraint_get_target
|
||||
GtkConstraintAttribute
|
||||
gtk_constraint_get_target_attribute
|
||||
GtkConstraintRelation
|
||||
gtk_constraint_get_relation
|
||||
gtk_constraint_get_source
|
||||
gtk_constraint_get_source_attribute
|
||||
gtk_constraint_get_multiplier
|
||||
gtk_constraint_get_constant
|
||||
GtkConstraintStrength
|
||||
gtk_constraint_get_strength
|
||||
gtk_constraint_is_required
|
||||
gtk_constraint_is_attached
|
||||
gtk_constraint_is_constant
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_CONSTRAINT
|
||||
gtk_constraint_get_type
|
||||
GTK_TYPE_CONSTRAINT_TARGET
|
||||
gtk_constraint_target_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkconstraintlayout</FILE>
|
||||
GtkConstraintLayout
|
||||
GtkConstraintLayoutChild
|
||||
GtkConstraintVflParserError
|
||||
|
||||
gtk_constraint_layout_new
|
||||
|
||||
<SUBSECTION Constraints>
|
||||
gtk_constraint_layout_add_constraint
|
||||
gtk_constraint_layout_remove_constraint
|
||||
gtk_constraint_layout_remove_all_constraints
|
||||
|
||||
<SUBSECTION Guides>
|
||||
gtk_constraint_layout_add_guide
|
||||
gtk_constraint_layout_remove_guide
|
||||
|
||||
<SUBSECTION VFL>
|
||||
gtk_constraint_layout_add_constraints_from_description
|
||||
gtk_constraint_layout_add_constraints_from_descriptionv
|
||||
|
||||
<SUBSECTION>
|
||||
gtk_constraint_layout_observe_constraints
|
||||
gtk_constraint_layout_observe_guides
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_CONSTRAINT_LAYOUT
|
||||
gtk_constraint_layout_get_type
|
||||
GTK_TYPE_CONSTRAINT_LAYOUT_CHILD
|
||||
gtk_constraint_layout_child_get_type
|
||||
GTK_CONSTRAINT_VFL_PARSER_ERROR
|
||||
gtk_constraint_vfl_parser_error_quark
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkconstraintguide</FILE>
|
||||
GtkConstraintGuide
|
||||
|
||||
gtk_constraint_guide_new
|
||||
gtk_constraint_guide_set_name
|
||||
gtk_constraint_guide_get_name
|
||||
gtk_constraint_guide_set_strength
|
||||
gtk_constraint_guide_get_strength
|
||||
gtk_constraint_guide_set_min_size
|
||||
gtk_constraint_guide_get_min_size
|
||||
gtk_constraint_guide_set_nat_size
|
||||
gtk_constraint_guide_get_nat_size
|
||||
gtk_constraint_guide_set_max_size
|
||||
gtk_constraint_guide_get_max_size
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_CONSTRAINT_GUIDE
|
||||
gtk_constraint_guide_get_tyoe
|
||||
</SECTION>
|
||||
|
||||
@@ -49,6 +49,10 @@ gtk_color_chooser_dialog_get_type
|
||||
gtk_color_chooser_widget_get_type
|
||||
gtk_combo_box_get_type
|
||||
gtk_combo_box_text_get_type
|
||||
gtk_constraint_get_type
|
||||
gtk_constraint_guide_get_type
|
||||
gtk_constraint_layout_get_type
|
||||
gtk_constraint_target_get_type
|
||||
gtk_container_get_type
|
||||
gtk_css_provider_get_type
|
||||
gtk_dialog_get_type
|
||||
|
||||
@@ -23,6 +23,13 @@ private_headers = [
|
||||
'gtkcolorswatchprivate.h',
|
||||
'gtkcomboboxprivate.h',
|
||||
'gtkcontainerprivate.h',
|
||||
'gtkconstraintexpressionprivate.h',
|
||||
'gtkconstraintguideprivate.h',
|
||||
'gtkconstraintlayoutprivate.h',
|
||||
'gtkconstraintprivate.h',
|
||||
'gtkconstraintsolverprivate.h',
|
||||
'gtkconstrainttypesprivate.h',
|
||||
'gtkconstraintvflparserprivate.h',
|
||||
'gtkcssanimatedstyleprivate.h',
|
||||
'gtkcssanimationprivate.h',
|
||||
'gtkcssarrayvalueprivate.h',
|
||||
@@ -394,7 +401,7 @@ else
|
||||
types_conf.set('DISABLE_ON_QUARTZ', '')
|
||||
endif
|
||||
|
||||
if get_option('documentation')
|
||||
if get_option('gtk_doc')
|
||||
configure_file(input: 'version.xml.in', output: 'version.xml', configuration: version_conf)
|
||||
configure_file(input: 'getting_started.xml.in', output: 'getting_started.xml', configuration: src_dir_conf)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
if get_option('documentation')
|
||||
if get_option('gtk_doc')
|
||||
glib_prefix = dependency('glib-2.0').get_pkgconfig_variable('prefix')
|
||||
glib_docpath = join_paths(glib_prefix, 'share', 'gtk-doc', 'html')
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
if x11_enabled and get_option('documentation')
|
||||
if x11_enabled and get_option('gtk_doc')
|
||||
doc_shooter_sources = [
|
||||
'shadow.c',
|
||||
'shooter.c',
|
||||
|
||||
@@ -808,7 +808,8 @@ upload_texture (GskGLRenderer *self,
|
||||
int texture_id;
|
||||
|
||||
if (texture->width <= 128 &&
|
||||
texture->height <= 128)
|
||||
texture->height <= 128 &&
|
||||
!GDK_IS_GL_TEXTURE (texture))
|
||||
{
|
||||
graphene_rect_t trect;
|
||||
|
||||
@@ -943,11 +944,9 @@ render_transform_node (GskGLRenderer *self,
|
||||
case GSK_TRANSFORM_CATEGORY_2D:
|
||||
default:
|
||||
{
|
||||
graphene_matrix_t mat;
|
||||
|
||||
if (node_supports_transform (child))
|
||||
{
|
||||
gsk_transform_to_matrix (node_transform, &mat);
|
||||
ops_push_modelview (builder, node_transform);
|
||||
gsk_gl_renderer_add_render_ops (self, child, builder);
|
||||
ops_pop_modelview (builder);
|
||||
@@ -972,7 +971,6 @@ render_transform_node (GskGLRenderer *self,
|
||||
®ion, &is_offscreen,
|
||||
RESET_CLIP | RESET_OPACITY);
|
||||
|
||||
gsk_transform_to_matrix (node_transform, &mat);
|
||||
ops_push_modelview (builder, node_transform);
|
||||
ops_set_texture (builder, region.texture_id);
|
||||
ops_set_program (builder, &self->blit_program);
|
||||
|
||||
@@ -339,9 +339,12 @@ ops_set_modelview_internal (RenderOpBuilder *builder,
|
||||
RenderOp op;
|
||||
graphene_matrix_t matrix;
|
||||
|
||||
#if 0
|
||||
XXX This is not possible if we want pop() to work.
|
||||
if (builder->current_program &&
|
||||
gsk_transform_equal (builder->current_program_state->modelview, transform))
|
||||
return;
|
||||
#endif
|
||||
|
||||
gsk_transform_to_matrix (transform, &matrix);
|
||||
|
||||
|
||||
+44
-4
@@ -1690,11 +1690,26 @@ gsk_transform_transform_bounds (GskTransform *self,
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
|
||||
{
|
||||
float dx, dy, scale_x, scale_y;
|
||||
|
||||
gsk_transform_to_affine (self, &scale_x, &scale_y, &dx, &dy);
|
||||
|
||||
*out_rect = *rect;
|
||||
out_rect->origin.x *= scale_x;
|
||||
out_rect->origin.y *= scale_y;
|
||||
out_rect->size.width *= scale_x;
|
||||
out_rect->size.height *= scale_y;
|
||||
out_rect->origin.x += dx;
|
||||
out_rect->origin.y += dy;
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_UNKNOWN:
|
||||
case GSK_TRANSFORM_CATEGORY_ANY:
|
||||
case GSK_TRANSFORM_CATEGORY_3D:
|
||||
case GSK_TRANSFORM_CATEGORY_2D:
|
||||
case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
|
||||
default:
|
||||
{
|
||||
graphene_matrix_t mat;
|
||||
@@ -1886,18 +1901,43 @@ gsk_transform_parser_parse (GtkCssParser *parser,
|
||||
|
||||
transform = gsk_transform_translate_3d (transform, &GRAPHENE_POINT3D_INIT (0.f, 0.f, f[0]));
|
||||
}
|
||||
#if 0
|
||||
/* FIXME: add these */
|
||||
else if (gtk_css_token_is_function (token, "skew"))
|
||||
{
|
||||
graphene_matrix_t matrix;
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 2, 2, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
f[0] = f[0] / 180.0 * G_PI;
|
||||
f[1] = f[1] / 180.0 * G_PI;
|
||||
|
||||
graphene_matrix_init_skew (&matrix, f[0], f[1]);
|
||||
transform = gsk_transform_matrix (transform, &matrix);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "skewX"))
|
||||
{
|
||||
graphene_matrix_t matrix;
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
f[0] = f[0] / 180.0 * G_PI;
|
||||
|
||||
graphene_matrix_init_skew (&matrix, f[0], 0);
|
||||
transform = gsk_transform_matrix (transform, &matrix);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "skewY"))
|
||||
{
|
||||
graphene_matrix_t matrix;
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
f[0] = f[0] / 180.0 * G_PI;
|
||||
|
||||
graphene_matrix_init_skew (&matrix, 0, f[0]);
|
||||
transform = gsk_transform_matrix (transform, &matrix);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -561,13 +561,6 @@ prop_actions_connect (GtkActionMuxer *muxer)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
prop_actions_disconnect (GtkActionMuxer *muxer)
|
||||
{
|
||||
if (muxer->widget)
|
||||
g_signal_handlers_disconnect_by_func (muxer->widget,
|
||||
prop_action_notify, muxer);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_action_muxer_query_action (GActionGroup *action_group,
|
||||
@@ -819,8 +812,6 @@ gtk_action_muxer_dispose (GObject *object)
|
||||
{
|
||||
GtkActionMuxer *muxer = GTK_ACTION_MUXER (object);
|
||||
|
||||
prop_actions_disconnect (muxer);
|
||||
|
||||
if (muxer->parent)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_action_added_to_parent, muxer);
|
||||
|
||||
+63
-66
@@ -211,7 +211,7 @@ gtk_constraint_class_init (GtkConstraintClass *klass)
|
||||
/**
|
||||
* GtkConstraint:relation:
|
||||
*
|
||||
* The relation order between the terms of the constraint.
|
||||
* The order relation between the terms of the constraint.
|
||||
*/
|
||||
obj_props[PROP_RELATION] =
|
||||
g_param_spec_enum ("relation",
|
||||
@@ -292,7 +292,7 @@ gtk_constraint_class_init (GtkConstraintClass *klass)
|
||||
g_param_spec_int ("strength",
|
||||
P_("Strength"),
|
||||
P_("The strength of the constraint"),
|
||||
GTK_CONSTRAINT_STRENGTH_WEAK, G_MAXINT,
|
||||
0, GTK_CONSTRAINT_STRENGTH_REQUIRED,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
@@ -387,24 +387,16 @@ gtk_constraint_new_constant (gpointer target,
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_get_target_widget:
|
||||
* gtk_constraint_get_target:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Retrieves the target widget for the @constraint.
|
||||
* Retrieves the #GtkConstraintTarget used as the target for @constraint.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): a #GtkWidget
|
||||
* If the #GtkConstraint:target property is set to %NULL, the @constraint
|
||||
* will use the #GtkConstraintLayout's widget.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): a #GtkConstraintTarget
|
||||
*/
|
||||
GtkWidget *
|
||||
gtk_constraint_get_target_widget (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), NULL);
|
||||
|
||||
if (GTK_IS_WIDGET (constraint->target))
|
||||
return GTK_WIDGET (constraint->target);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GtkConstraintTarget *
|
||||
gtk_constraint_get_target (GtkConstraint *constraint)
|
||||
{
|
||||
@@ -413,6 +405,14 @@ gtk_constraint_get_target (GtkConstraint *constraint)
|
||||
return constraint->target;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_get_target_attribute:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Retrieves the attribute of the target to be set by the @constraint.
|
||||
*
|
||||
* Returns: the target's attribute
|
||||
*/
|
||||
GtkConstraintAttribute
|
||||
gtk_constraint_get_target_attribute (GtkConstraint *constraint)
|
||||
{
|
||||
@@ -422,24 +422,16 @@ gtk_constraint_get_target_attribute (GtkConstraint *constraint)
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_get_source_widget:
|
||||
* gtk_constraint_get_source:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Retrieves the source widget for the @constraint.
|
||||
* Retrieves the #GtkConstraintTarget used as the source for @constraint.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): a #GtkWidget
|
||||
* If the #GtkConstraint:source property is set to %NULL, the @constraint
|
||||
* will use the #GtkConstraintLayout's widget.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): a #GtkConstraintTarget
|
||||
*/
|
||||
GtkWidget *
|
||||
gtk_constraint_get_source_widget (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), NULL);
|
||||
|
||||
if (GTK_IS_WIDGET (constraint->source))
|
||||
return GTK_WIDGET (constraint->source);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GtkConstraintTarget *
|
||||
gtk_constraint_get_source (GtkConstraint *constraint)
|
||||
{
|
||||
@@ -448,6 +440,14 @@ gtk_constraint_get_source (GtkConstraint *constraint)
|
||||
return constraint->source;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_get_source_attribute:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Retrieves the attribute of the source to be read by the @constraint.
|
||||
*
|
||||
* Returns: the target's attribute
|
||||
*/
|
||||
GtkConstraintAttribute
|
||||
gtk_constraint_get_source_attribute (GtkConstraint *constraint)
|
||||
{
|
||||
@@ -456,6 +456,14 @@ gtk_constraint_get_source_attribute (GtkConstraint *constraint)
|
||||
return constraint->source_attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_get_relation:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* The order relation between the terms of the @constraint.
|
||||
*
|
||||
* Returns: a #GtkConstraintRelation value
|
||||
*/
|
||||
GtkConstraintRelation
|
||||
gtk_constraint_get_relation (GtkConstraint *constraint)
|
||||
{
|
||||
@@ -464,6 +472,15 @@ gtk_constraint_get_relation (GtkConstraint *constraint)
|
||||
return constraint->relation;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_get_multiplier:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Retrieves the multiplication factor applied to the source
|
||||
* attribute's value.
|
||||
*
|
||||
* Returns: a multiplication factor
|
||||
*/
|
||||
double
|
||||
gtk_constraint_get_multiplier (GtkConstraint *constraint)
|
||||
{
|
||||
@@ -472,6 +489,14 @@ gtk_constraint_get_multiplier (GtkConstraint *constraint)
|
||||
return constraint->multiplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_get_constant:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Retrieves the constant factor added to the source attributes' value.
|
||||
*
|
||||
* Returns: a constant factor
|
||||
*/
|
||||
double
|
||||
gtk_constraint_get_constant (GtkConstraint *constraint)
|
||||
{
|
||||
@@ -480,6 +505,14 @@ gtk_constraint_get_constant (GtkConstraint *constraint)
|
||||
return constraint->constant;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_get_strength:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Retrieves the strength of the constraint.
|
||||
*
|
||||
* Returns: the strength of the constraint
|
||||
*/
|
||||
int
|
||||
gtk_constraint_get_strength (GtkConstraint *constraint)
|
||||
{
|
||||
@@ -488,42 +521,6 @@ gtk_constraint_get_strength (GtkConstraint *constraint)
|
||||
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
|
||||
|
||||
@@ -73,15 +73,11 @@ GtkConstraint * gtk_constraint_new_constant (gpointer
|
||||
double constant,
|
||||
int strength);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkWidget * gtk_constraint_get_target_widget (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkConstraintTarget * gtk_constraint_get_target (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
|
||||
GtkConstraintTarget * gtk_constraint_get_source (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkConstraintAttribute gtk_constraint_get_source_attribute (GtkConstraint *constraint);
|
||||
|
||||
@@ -55,9 +55,12 @@ static guint64 gtk_constraint_variable_next_id;
|
||||
|
||||
static void
|
||||
gtk_constraint_variable_init (GtkConstraintVariable *variable,
|
||||
const char *prefix,
|
||||
const char *name)
|
||||
{
|
||||
variable->_id = gtk_constraint_variable_next_id++;
|
||||
|
||||
variable->prefix = g_intern_string (prefix);
|
||||
variable->name = g_intern_string (name);
|
||||
variable->prefix = NULL;
|
||||
variable->value = 0.0;
|
||||
@@ -81,7 +84,7 @@ gtk_constraint_variable_new_dummy (const char *name)
|
||||
{
|
||||
GtkConstraintVariable *res = g_rc_box_new (GtkConstraintVariable);
|
||||
|
||||
gtk_constraint_variable_init (res, name);
|
||||
gtk_constraint_variable_init (res, NULL, name);
|
||||
|
||||
res->_type = GTK_CONSTRAINT_SYMBOL_DUMMY;
|
||||
res->is_external = FALSE;
|
||||
@@ -108,7 +111,7 @@ gtk_constraint_variable_new_objective (const char *name)
|
||||
{
|
||||
GtkConstraintVariable *res = g_rc_box_new (GtkConstraintVariable);
|
||||
|
||||
gtk_constraint_variable_init (res, name);
|
||||
gtk_constraint_variable_init (res, NULL, name);
|
||||
|
||||
res->_type = GTK_CONSTRAINT_SYMBOL_OBJECTIVE;
|
||||
res->is_external = FALSE;
|
||||
@@ -145,7 +148,7 @@ gtk_constraint_variable_new_slack (const char *name)
|
||||
{
|
||||
GtkConstraintVariable *res = g_rc_box_new (GtkConstraintVariable);
|
||||
|
||||
gtk_constraint_variable_init (res, name);
|
||||
gtk_constraint_variable_init (res, NULL, name);
|
||||
|
||||
res->_type = GTK_CONSTRAINT_SYMBOL_SLACK;
|
||||
res->is_external = FALSE;
|
||||
@@ -157,7 +160,8 @@ gtk_constraint_variable_new_slack (const char *name)
|
||||
|
||||
/*< private >
|
||||
* gtk_constraint_variable_new:
|
||||
* @name: the name of the variable
|
||||
* @prefix: (nullable): an optional prefix string for @name
|
||||
* @name: (nullable): an optional name for the variable
|
||||
*
|
||||
* Allocates and initializes a new #GtkConstraintVariable for a regular
|
||||
* symbol. All variables introduced by constraints are regular variables.
|
||||
@@ -170,11 +174,12 @@ gtk_constraint_variable_new_slack (const char *name)
|
||||
* Returns: a newly allocated #GtkConstraintVariable
|
||||
*/
|
||||
GtkConstraintVariable *
|
||||
gtk_constraint_variable_new (const char *name)
|
||||
gtk_constraint_variable_new (const char *prefix,
|
||||
const char *name)
|
||||
{
|
||||
GtkConstraintVariable *res = g_rc_box_new (GtkConstraintVariable);
|
||||
|
||||
gtk_constraint_variable_init (res, name);
|
||||
gtk_constraint_variable_init (res, prefix, name);
|
||||
|
||||
res->_type = GTK_CONSTRAINT_SYMBOL_REGULAR;
|
||||
res->is_external = TRUE;
|
||||
@@ -184,24 +189,6 @@ gtk_constraint_variable_new (const char *name)
|
||||
return res;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gtk_constraint_variable_set_prefix:
|
||||
* @variable: a #GtkConstraintVariable
|
||||
* @prefix: a prefix string
|
||||
*
|
||||
* Sets the prefix to the @variable's name.
|
||||
*
|
||||
* This function is useful when debugging the variable contents.
|
||||
*/
|
||||
void
|
||||
gtk_constraint_variable_set_prefix (GtkConstraintVariable *variable,
|
||||
const char *prefix)
|
||||
{
|
||||
g_return_if_fail (variable != NULL);
|
||||
|
||||
variable->prefix = g_intern_string (prefix);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gtk_constraint_variable_ref:
|
||||
* @variable: a #GtkConstraintVariable
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GtkConstraintVariable *
|
||||
gtk_constraint_variable_new (const char *name);
|
||||
gtk_constraint_variable_new (const char *prefix,
|
||||
const char *name);
|
||||
|
||||
GtkConstraintVariable *
|
||||
gtk_constraint_variable_new_dummy (const char *name);
|
||||
@@ -50,10 +51,6 @@ gtk_constraint_variable_set_value (GtkConstraintVariable *variable,
|
||||
double
|
||||
gtk_constraint_variable_get_value (const GtkConstraintVariable *variable);
|
||||
|
||||
void
|
||||
gtk_constraint_variable_set_prefix (GtkConstraintVariable *variable,
|
||||
const char *prefix);
|
||||
|
||||
char *
|
||||
gtk_constraint_variable_to_string (const GtkConstraintVariable *variable);
|
||||
|
||||
|
||||
@@ -17,6 +17,19 @@
|
||||
* Author: Matthias Clasen
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gtkconstraintguide
|
||||
* @Title: GtkConstraintGuide
|
||||
* @Short_description: An invisible constraint target
|
||||
*
|
||||
* A #GtkConstraintGuide is an invisible layout element that can be
|
||||
* used by widgets inside a #GtkConstraintLayout as a source or a target
|
||||
* of a #GtkConstraint. Guides can be used like guidelines or as
|
||||
* flexible space.
|
||||
*
|
||||
* Unlike a #GtkWidget, a #GtkConstraintGuide will not be drawn.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkconstraintguide.h"
|
||||
@@ -145,7 +158,7 @@ gtk_constraint_guide_update_constraint (GtkConstraintGuide *guide,
|
||||
var,
|
||||
GTK_CONSTRAINT_RELATION_GE,
|
||||
gtk_constraint_expression_new (guide->values[index]),
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
}
|
||||
else if ((index == NAT_WIDTH && guide->values[MIN_WIDTH] != guide->values[MAX_WIDTH]) ||
|
||||
(index == NAT_HEIGHT && guide->values[MIN_HEIGHT] != guide->values[MAX_HEIGHT]))
|
||||
@@ -164,8 +177,10 @@ gtk_constraint_guide_update_constraint (GtkConstraintGuide *guide,
|
||||
var,
|
||||
GTK_CONSTRAINT_RELATION_LE,
|
||||
gtk_constraint_expression_new (guide->values[index]),
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
}
|
||||
|
||||
gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (guide->layout));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -292,7 +307,7 @@ gtk_constraint_guide_get_property (GObject *gobject,
|
||||
break;
|
||||
|
||||
case PROP_STRENGTH:
|
||||
g_value_set_int (value, self->strength);
|
||||
g_value_set_enum (value, self->strength);
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
@@ -326,6 +341,11 @@ gtk_constraint_guide_class_init (GtkConstraintGuideClass *class)
|
||||
object_class->set_property = gtk_constraint_guide_set_property;
|
||||
object_class->get_property = gtk_constraint_guide_get_property;
|
||||
|
||||
/**
|
||||
* GtkConstraintGuide:min-width:
|
||||
*
|
||||
* The minimum width of the guide.
|
||||
*/
|
||||
guide_props[PROP_MIN_WIDTH] =
|
||||
g_param_spec_int ("min-width",
|
||||
"Minimum width",
|
||||
@@ -333,6 +353,11 @@ gtk_constraint_guide_class_init (GtkConstraintGuideClass *class)
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE|
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
/**
|
||||
* GtkConstraintGuide:min-height:
|
||||
*
|
||||
* The minimum height of the guide.
|
||||
*/
|
||||
guide_props[PROP_MIN_HEIGHT] =
|
||||
g_param_spec_int ("min-height",
|
||||
"Minimum height",
|
||||
@@ -340,6 +365,11 @@ gtk_constraint_guide_class_init (GtkConstraintGuideClass *class)
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE|
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
/**
|
||||
* GtkConstraintGuide:nat-width:
|
||||
*
|
||||
* The preferred, or natural, width of the guide.
|
||||
*/
|
||||
guide_props[PROP_NAT_WIDTH] =
|
||||
g_param_spec_int ("nat-width",
|
||||
"Natural width",
|
||||
@@ -347,6 +377,11 @@ gtk_constraint_guide_class_init (GtkConstraintGuideClass *class)
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE|
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
/**
|
||||
* GtkConstraintGuide:nat-height:
|
||||
*
|
||||
* The preferred, or natural, height of the guide.
|
||||
*/
|
||||
guide_props[PROP_NAT_HEIGHT] =
|
||||
g_param_spec_int ("nat-height",
|
||||
"Natural height",
|
||||
@@ -354,6 +389,11 @@ gtk_constraint_guide_class_init (GtkConstraintGuideClass *class)
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE|
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
/**
|
||||
* GtkConstraintGuide:max-width:
|
||||
*
|
||||
* The maximum width of the guide.
|
||||
*/
|
||||
guide_props[PROP_MAX_WIDTH] =
|
||||
g_param_spec_int ("max-width",
|
||||
"Maximum width",
|
||||
@@ -361,6 +401,11 @@ gtk_constraint_guide_class_init (GtkConstraintGuideClass *class)
|
||||
0, G_MAXINT, G_MAXINT,
|
||||
G_PARAM_READWRITE|
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
/**
|
||||
* GtkConstraintGuide:max-height:
|
||||
*
|
||||
* The maximum height of the guide.
|
||||
*/
|
||||
guide_props[PROP_MAX_HEIGHT] =
|
||||
g_param_spec_int ("max-height",
|
||||
"Maximum height",
|
||||
@@ -368,7 +413,12 @@ gtk_constraint_guide_class_init (GtkConstraintGuideClass *class)
|
||||
0, G_MAXINT, G_MAXINT,
|
||||
G_PARAM_READWRITE|
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkConstraintGuide:strength:
|
||||
*
|
||||
* The #GtkConstraintStrength to be used for the constraint on
|
||||
* the natural size of the guide.
|
||||
*/
|
||||
guide_props[PROP_STRENGTH] =
|
||||
g_param_spec_enum ("strength",
|
||||
"Strength",
|
||||
@@ -377,7 +427,11 @@ gtk_constraint_guide_class_init (GtkConstraintGuideClass *class)
|
||||
GTK_CONSTRAINT_STRENGTH_MEDIUM,
|
||||
G_PARAM_READWRITE|
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkConstraintGuide:name:
|
||||
*
|
||||
* A name that identifies the #GtkConstraintGuide, for debugging.
|
||||
*/
|
||||
guide_props[PROP_NAME] =
|
||||
g_param_spec_string ("name",
|
||||
"Name",
|
||||
@@ -563,6 +617,14 @@ gtk_constraint_guide_get_max_size (GtkConstraintGuide *guide,
|
||||
*height = guide->values[MAX_HEIGHT];
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_guide_get_name:
|
||||
* @guide: a #GtkConstraintGuide
|
||||
*
|
||||
* Retrieves the name set using gtk_constraint_guide_set_name().
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the name of the guide
|
||||
*/
|
||||
const char *
|
||||
gtk_constraint_guide_get_name (GtkConstraintGuide *guide)
|
||||
{
|
||||
@@ -571,6 +633,15 @@ gtk_constraint_guide_get_name (GtkConstraintGuide *guide)
|
||||
return guide->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_guide_set_name:
|
||||
* @guide: a #GtkConstraintGuide
|
||||
* @name: (nullable): a name for the @guide
|
||||
*
|
||||
* Sets a name for the given #GtkConstraintGuide.
|
||||
*
|
||||
* The name is useful for debugging purposes.
|
||||
*/
|
||||
void
|
||||
gtk_constraint_guide_set_name (GtkConstraintGuide *guide,
|
||||
const char *name)
|
||||
@@ -582,6 +653,14 @@ gtk_constraint_guide_set_name (GtkConstraintGuide *guide,
|
||||
g_object_notify_by_pspec (G_OBJECT (guide), guide_props[PROP_NAME]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_guide_get_strength:
|
||||
* @guide: a #GtkConstraintGuide
|
||||
*
|
||||
* Retrieves the strength set using gtk_constraint_guide_set_strength().
|
||||
*
|
||||
* Returns: the strength of the constraint on the natural size
|
||||
*/
|
||||
GtkConstraintStrength
|
||||
gtk_constraint_guide_get_strength (GtkConstraintGuide *guide)
|
||||
{
|
||||
@@ -591,6 +670,14 @@ gtk_constraint_guide_get_strength (GtkConstraintGuide *guide)
|
||||
return guide->strength;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_guide_set_strength:
|
||||
* @guide: a #GtkConstraintGuide
|
||||
* @strength: the strength of the constraint
|
||||
*
|
||||
* Sets the strength of the constraint on the natural size of the
|
||||
* given #GtkConstraintGuide.
|
||||
*/
|
||||
void
|
||||
gtk_constraint_guide_set_strength (GtkConstraintGuide *guide,
|
||||
GtkConstraintStrength strength)
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define GTK_TYPE_CONSTRAINT_GUIDE (gtk_constraint_guide_get_type ())
|
||||
|
||||
/**
|
||||
|
||||
+1056
-190
File diff suppressed because it is too large
Load Diff
@@ -21,12 +21,12 @@
|
||||
#include <gtk/gtklayoutmanager.h>
|
||||
#include <gtk/gtkconstraint.h>
|
||||
#include <gtk/gtkconstraintguide.h>
|
||||
#include <gtk/gtkgridconstraint.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 ())
|
||||
#define GTK_CONSTRAINT_VFL_PARSER_ERROR (gtk_constraint_vfl_parser_error_quark ())
|
||||
|
||||
/**
|
||||
* GtkConstraintLayoutChild:
|
||||
@@ -45,25 +45,49 @@ G_DECLARE_FINAL_TYPE (GtkConstraintLayoutChild, gtk_constraint_layout_child, GTK
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_FINAL_TYPE (GtkConstraintLayout, gtk_constraint_layout, GTK, CONSTRAINT_LAYOUT, GtkLayoutManager)
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GQuark gtk_constraint_vfl_parser_error_quark (void);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkLayoutManager * gtk_constraint_layout_new (void);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_layout_add_constraint (GtkConstraintLayout *manager,
|
||||
void gtk_constraint_layout_add_constraint (GtkConstraintLayout *layout,
|
||||
GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_layout_remove_constraint (GtkConstraintLayout *manager,
|
||||
void gtk_constraint_layout_remove_constraint (GtkConstraintLayout *layout,
|
||||
GtkConstraint *constraint);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_layout_add_grid_constraint (GtkConstraintLayout *manager,
|
||||
GtkGridConstraint *constraint);
|
||||
void gtk_constraint_layout_add_guide (GtkConstraintLayout *layout,
|
||||
GtkConstraintGuide *guide);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_layout_remove_guide (GtkConstraintLayout *layout,
|
||||
GtkConstraintGuide *guide);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_layout_remove_all_constraints (GtkConstraintLayout *layout);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_layout_add_guide (GtkConstraintLayout *manager,
|
||||
GtkConstraintGuide *guide);
|
||||
GList * gtk_constraint_layout_add_constraints_from_description (GtkConstraintLayout *layout,
|
||||
const char * const lines[],
|
||||
gsize n_lines,
|
||||
int hspacing,
|
||||
int vspacing,
|
||||
GError **error,
|
||||
const char *first_view,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_layout_remove_guide (GtkConstraintLayout *manager,
|
||||
GtkConstraintGuide *guide);
|
||||
GList * gtk_constraint_layout_add_constraints_from_descriptionv (GtkConstraintLayout *layout,
|
||||
const char * const lines[],
|
||||
gsize n_lines,
|
||||
int hspacing,
|
||||
int vspacing,
|
||||
GHashTable *views,
|
||||
GError **error);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GListModel * gtk_constraint_layout_observe_constraints (GtkConstraintLayout *layout);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GListModel * gtk_constraint_layout_observe_guides (GtkConstraintLayout *layout);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -52,8 +52,6 @@ struct _GtkConstraint
|
||||
guint active : 1;
|
||||
};
|
||||
|
||||
double gtk_constraint_get_weight (GtkConstraint *constraint);
|
||||
|
||||
void gtk_constraint_attach (GtkConstraint *constraint,
|
||||
GtkConstraintSolver *solver,
|
||||
GtkConstraintRef *ref);
|
||||
|
||||
+40
-39
@@ -73,14 +73,14 @@
|
||||
* e = gtk_constraint_expression_builder_finish (&builder);
|
||||
* gtk_constraint_solver_add_constraint (solver,
|
||||
* right, GTK_CONSTRAINT_RELATION_EQ, e,
|
||||
* GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
* GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
*
|
||||
* // right ≤ 100
|
||||
* gtk_constraint_expression_builder_constant (&builder, 100.0);
|
||||
* e = gtk_constraint_expression_builder_finish (&builder);
|
||||
* gtk_constraint_solver_add_constraint (solver,
|
||||
* right, GTK_CONSTRAINT_RELATION_LE, e,
|
||||
* GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
* GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
*
|
||||
* // middle = (left + right) / 2
|
||||
* gtk_constraint_expression_builder_term (&builder, left);
|
||||
@@ -91,14 +91,14 @@
|
||||
* e = gtk_constraint_expression_builder_finish (&builder);
|
||||
* gtk_constraint_solver_add_constraint (solver
|
||||
* middle, GTK_CONSTRAINT_RELATION_EQ, e,
|
||||
* GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
* GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
*
|
||||
* // left ≥ 0
|
||||
* gtk_constraint_expression_builder_constant (&builder, 0.0);
|
||||
* e = gtk_constraint_expression_builder_finish (&builder);
|
||||
* gtk_constraint_solver_add_constraint (solver,
|
||||
* left, GTK_CONSTRAINT_RELATION_GE, e,
|
||||
* GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
* GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
* ]|
|
||||
*
|
||||
* Now that we have all our constraints in place, suppose we wish to find
|
||||
@@ -110,8 +110,8 @@
|
||||
* |[
|
||||
* // Set the value first
|
||||
* gtk_constraint_variable_set_value (middle, 45.0);
|
||||
* // and then add the stay constraint, with a weak weight
|
||||
* gtk_constraint_solver_add_stay_variable (solver, middle, GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
* // and then add the stay constraint, with a weak strength
|
||||
* gtk_constraint_solver_add_stay_variable (solver, middle, GTK_CONSTRAINT_STRENGTH_WEAK);
|
||||
* ]|
|
||||
*
|
||||
* GtkConstraintSolver incrementally solves the system every time a constraint
|
||||
@@ -185,8 +185,11 @@ struct _GtkConstraintRef
|
||||
/* The original relation used when creating the constraint */
|
||||
GtkConstraintRelation relation;
|
||||
|
||||
/* The weight, or strength, of the constraint */
|
||||
double weight;
|
||||
/* The strength of the constraint; this value is used to strengthen
|
||||
* or weaken a constraint weight in the tableau when coming to a
|
||||
* solution
|
||||
*/
|
||||
int strength;
|
||||
|
||||
GtkConstraintSolver *solver;
|
||||
|
||||
@@ -374,7 +377,7 @@ gtk_constraint_ref_is_inequality (const GtkConstraintRef *self)
|
||||
static gboolean
|
||||
gtk_constraint_ref_is_required (const GtkConstraintRef *self)
|
||||
{
|
||||
return self->weight >= GTK_CONSTRAINT_WEIGHT_REQUIRED;
|
||||
return self->strength == GTK_CONSTRAINT_STRENGTH_REQUIRED;
|
||||
}
|
||||
|
||||
static const char *relations[] = {
|
||||
@@ -390,15 +393,12 @@ relation_to_string (GtkConstraintRelation r)
|
||||
}
|
||||
|
||||
static const char *
|
||||
weight_to_string (double s)
|
||||
strength_to_string (int s)
|
||||
{
|
||||
if (s >= GTK_CONSTRAINT_WEIGHT_REQUIRED)
|
||||
return "required";
|
||||
|
||||
if (s >= GTK_CONSTRAINT_WEIGHT_STRONG)
|
||||
if (s >= GTK_CONSTRAINT_STRENGTH_STRONG)
|
||||
return "strong";
|
||||
|
||||
if (s >= GTK_CONSTRAINT_WEIGHT_MEDIUM)
|
||||
if (s >= GTK_CONSTRAINT_STRENGTH_MEDIUM)
|
||||
return "medium";
|
||||
|
||||
return "weak";
|
||||
@@ -423,9 +423,12 @@ gtk_constraint_ref_to_string (const GtkConstraintRef *self)
|
||||
g_string_append (buf, relation_to_string (self->relation));
|
||||
g_string_append (buf, " 0.0");
|
||||
|
||||
g_string_append_printf (buf, " [weight:%s (%g)]",
|
||||
weight_to_string (self->weight),
|
||||
self->weight);
|
||||
if (gtk_constraint_ref_is_required (self))
|
||||
g_string_append (buf, " [strength:required]");
|
||||
else
|
||||
g_string_append_printf (buf, " [strength:%d (%s)]",
|
||||
self->strength,
|
||||
strength_to_string (self->strength));
|
||||
|
||||
return g_string_free (buf, FALSE);
|
||||
}
|
||||
@@ -909,7 +912,7 @@ gtk_constraint_solver_new_expression (GtkConstraintSolver *self,
|
||||
gtk_constraint_variable_unref (eminus);
|
||||
|
||||
z_row = g_hash_table_lookup (self->rows, self->objective);
|
||||
gtk_constraint_expression_set_variable (z_row, eminus, constraint->weight);
|
||||
gtk_constraint_expression_set_variable (z_row, eminus, constraint->strength);
|
||||
|
||||
gtk_constraint_solver_insert_error_variable (self, constraint, eminus);
|
||||
gtk_constraint_solver_note_added_variable (self, eminus, self->objective);
|
||||
@@ -939,6 +942,8 @@ gtk_constraint_solver_new_expression (GtkConstraintSolver *self,
|
||||
|
||||
gtk_constraint_expression_set_variable (expr, dummy_var, 1.0);
|
||||
g_hash_table_insert (self->marker_vars, constraint, dummy_var);
|
||||
|
||||
gtk_constraint_variable_unref (dummy_var);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -966,8 +971,8 @@ gtk_constraint_solver_new_expression (GtkConstraintSolver *self,
|
||||
|
||||
z_row = g_hash_table_lookup (self->rows, self->objective);
|
||||
|
||||
gtk_constraint_expression_set_variable (z_row, eplus, constraint->weight);
|
||||
gtk_constraint_expression_set_variable (z_row, eminus, constraint->weight);
|
||||
gtk_constraint_expression_set_variable (z_row, eplus, constraint->strength);
|
||||
gtk_constraint_expression_set_variable (z_row, eminus, constraint->strength);
|
||||
gtk_constraint_solver_note_added_variable (self, eplus, self->objective);
|
||||
gtk_constraint_solver_note_added_variable (self, eminus, self->objective);
|
||||
|
||||
@@ -1049,10 +1054,7 @@ gtk_constraint_solver_dual_optimize (GtkConstraintSolver *self)
|
||||
}
|
||||
|
||||
if (ratio == DBL_MAX)
|
||||
{
|
||||
g_critical ("INTERNAL: ratio == DBL_MAX in dual_optimize");
|
||||
break;
|
||||
}
|
||||
g_critical ("INTERNAL: ratio == DBL_MAX in dual_optimize");
|
||||
|
||||
gtk_constraint_solver_pivot (self, entry_var, exit_var);
|
||||
}
|
||||
@@ -1480,12 +1482,11 @@ gtk_constraint_solver_create_variable (GtkConstraintSolver *self,
|
||||
{
|
||||
GtkConstraintVariable *res;
|
||||
|
||||
self->var_counter++;
|
||||
|
||||
res = gtk_constraint_variable_new (name);
|
||||
gtk_constraint_variable_set_prefix (res, prefix);
|
||||
res = gtk_constraint_variable_new (prefix, name);
|
||||
gtk_constraint_variable_set_value (res, value);
|
||||
|
||||
self->var_counter++;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1524,7 +1525,7 @@ gtk_constraint_solver_resolve (GtkConstraintSolver *solver)
|
||||
* @variable: the subject of the constraint
|
||||
* @relation: the relation of the constraint
|
||||
* @expression: the expression of the constraint
|
||||
* @strength: the weight of the constraint
|
||||
* @strength: the strength of the constraint
|
||||
*
|
||||
* Adds a new constraint in the form of:
|
||||
*
|
||||
@@ -1543,12 +1544,12 @@ gtk_constraint_solver_add_constraint (GtkConstraintSolver *self,
|
||||
GtkConstraintVariable *variable,
|
||||
GtkConstraintRelation relation,
|
||||
GtkConstraintExpression *expression,
|
||||
double strength)
|
||||
int strength)
|
||||
{
|
||||
GtkConstraintRef *res = g_new0 (GtkConstraintRef, 1);
|
||||
|
||||
res->solver = self;
|
||||
res->weight = strength;
|
||||
res->strength = strength;
|
||||
res->is_edit = FALSE;
|
||||
res->is_stay = FALSE;
|
||||
res->relation = relation;
|
||||
@@ -1600,7 +1601,7 @@ gtk_constraint_solver_add_constraint (GtkConstraintSolver *self,
|
||||
* gtk_constraint_solver_add_stay_variable:
|
||||
* @self: a #GtkConstraintSolver
|
||||
* @variable: a stay #GtkConstraintVariable
|
||||
* @strength: the weight of the constraint
|
||||
* @strength: the strength of the constraint
|
||||
*
|
||||
* Adds a constraint on a stay @variable with the given @strength.
|
||||
*
|
||||
@@ -1614,14 +1615,14 @@ gtk_constraint_solver_add_constraint (GtkConstraintSolver *self,
|
||||
GtkConstraintRef *
|
||||
gtk_constraint_solver_add_stay_variable (GtkConstraintSolver *self,
|
||||
GtkConstraintVariable *variable,
|
||||
double strength)
|
||||
int strength)
|
||||
{
|
||||
GtkConstraintRef *res = g_new0 (GtkConstraintRef, 1);
|
||||
|
||||
res->solver = self;
|
||||
res->variable = gtk_constraint_variable_ref (variable);
|
||||
res->relation = GTK_CONSTRAINT_RELATION_EQ;
|
||||
res->weight = strength;
|
||||
res->strength = strength;
|
||||
res->is_stay = TRUE;
|
||||
res->is_edit = FALSE;
|
||||
|
||||
@@ -1694,14 +1695,14 @@ gtk_constraint_solver_remove_stay_variable (GtkConstraintSolver *self,
|
||||
GtkConstraintRef *
|
||||
gtk_constraint_solver_add_edit_variable (GtkConstraintSolver *self,
|
||||
GtkConstraintVariable *variable,
|
||||
double strength)
|
||||
int strength)
|
||||
{
|
||||
GtkConstraintRef *res = g_new0 (GtkConstraintRef, 1);
|
||||
|
||||
res->solver = self;
|
||||
res->variable = gtk_constraint_variable_ref (variable);
|
||||
res->relation = GTK_CONSTRAINT_RELATION_EQ;
|
||||
res->weight = strength;
|
||||
res->strength = strength;
|
||||
res->is_stay = FALSE;
|
||||
res->is_edit = TRUE;
|
||||
|
||||
@@ -1784,7 +1785,7 @@ gtk_constraint_solver_remove_constraint (GtkConstraintSolver *self,
|
||||
{
|
||||
gtk_constraint_expression_add_variable (z_row,
|
||||
v,
|
||||
constraint->weight,
|
||||
constraint->strength,
|
||||
self->objective,
|
||||
self);
|
||||
}
|
||||
@@ -1792,7 +1793,7 @@ gtk_constraint_solver_remove_constraint (GtkConstraintSolver *self,
|
||||
{
|
||||
gtk_constraint_expression_add_expression (z_row,
|
||||
e,
|
||||
constraint->weight,
|
||||
constraint->strength,
|
||||
self->objective,
|
||||
self);
|
||||
}
|
||||
|
||||
@@ -25,61 +25,10 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#ifdef GTK_TEST_EXTERNAL
|
||||
|
||||
#define GTK_TYPE_CONSTRAINT_SOLVER (g_type_from_name ("GtkConstraintSolver"))
|
||||
#define GTK_CONSTRAINT_SOLVER(solver) (G_TYPE_CHECK_INSTANCE_CAST ((solver), GTK_TYPE_CONSTRAINT_SOLVER, GtkConstraintSolver))
|
||||
#define GTK_CONSTRAINT_SOLVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_CONSTRAINT_SOLVER, GtkConstraintSolverClass))
|
||||
#define GTK_IS_CONSTRAINT_SOLVER(solver) (G_TYPE_CHECK_INSTANCE_TYPE ((solver), GTK_TYPE_CONSTRAINT_SOLVER))
|
||||
#define GTK_IS_CONSTRAINT_SOLVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CONSTRAINT_SOLVER))
|
||||
#define GTK_CONSTRAINT_SOLVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CONSTRAINT_SOLVER, GtkConstraintSolverClass))
|
||||
|
||||
typedef struct _GtkConstraintSolver GtkConstraintSolver;
|
||||
typedef struct _GtkConstraintSolverClass GtkConstraintSolverClass;
|
||||
|
||||
struct _GtkConstraintSolverClass {
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define GTK_TYPE_CONSTRAINT_SOLVER (gtk_constraint_solver_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GtkConstraintSolver, gtk_constraint_solver, GTK, CONSTRAINT_SOLVER, GObject)
|
||||
|
||||
#endif
|
||||
|
||||
/* 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);
|
||||
|
||||
@@ -103,7 +52,7 @@ gtk_constraint_solver_add_constraint (GtkConstraintSolver *solver,
|
||||
GtkConstraintVariable *variable,
|
||||
GtkConstraintRelation relation,
|
||||
GtkConstraintExpression *expression,
|
||||
double strength);
|
||||
int strength);
|
||||
|
||||
void
|
||||
gtk_constraint_solver_remove_constraint (GtkConstraintSolver *solver,
|
||||
@@ -112,7 +61,7 @@ gtk_constraint_solver_remove_constraint (GtkConstraintSolver *solver,
|
||||
GtkConstraintRef *
|
||||
gtk_constraint_solver_add_stay_variable (GtkConstraintSolver *solver,
|
||||
GtkConstraintVariable *variable,
|
||||
double strength);
|
||||
int strength);
|
||||
|
||||
void
|
||||
gtk_constraint_solver_remove_stay_variable (GtkConstraintSolver *solver,
|
||||
@@ -125,7 +74,7 @@ gtk_constraint_solver_has_stay_variable (GtkConstraintSolver *solver,
|
||||
GtkConstraintRef *
|
||||
gtk_constraint_solver_add_edit_variable (GtkConstraintSolver *solver,
|
||||
GtkConstraintVariable *variable,
|
||||
double strength);
|
||||
int strength);
|
||||
|
||||
void
|
||||
gtk_constraint_solver_remove_edit_variable (GtkConstraintSolver *solver,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,76 @@
|
||||
/* gtkconstraintvflparserprivate.h: VFL constraint definition parser
|
||||
*
|
||||
* Copyright 2017 Endless
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gtkconstrainttypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkConstraintVflParser GtkConstraintVflParser;
|
||||
|
||||
typedef struct {
|
||||
const char *view1;
|
||||
const char *attr1;
|
||||
GtkConstraintRelation relation;
|
||||
const char *view2;
|
||||
const char *attr2;
|
||||
double constant;
|
||||
double multiplier;
|
||||
double strength;
|
||||
} GtkConstraintVfl;
|
||||
|
||||
GtkConstraintVflParser *
|
||||
gtk_constraint_vfl_parser_new (void);
|
||||
|
||||
void
|
||||
gtk_constraint_vfl_parser_free (GtkConstraintVflParser *parser);
|
||||
|
||||
void
|
||||
gtk_constraint_vfl_parser_set_default_spacing (GtkConstraintVflParser *parser,
|
||||
int hspacing,
|
||||
int vspacing);
|
||||
|
||||
void
|
||||
gtk_constraint_vfl_parser_set_metrics (GtkConstraintVflParser *parser,
|
||||
GHashTable *metrics);
|
||||
|
||||
void
|
||||
gtk_constraint_vfl_parser_set_views (GtkConstraintVflParser *parser,
|
||||
GHashTable *views);
|
||||
|
||||
gboolean
|
||||
gtk_constraint_vfl_parser_parse_line (GtkConstraintVflParser *parser,
|
||||
const char *line,
|
||||
gssize len,
|
||||
GError **error);
|
||||
|
||||
int
|
||||
gtk_constraint_vfl_parser_get_error_offset (GtkConstraintVflParser *parser);
|
||||
|
||||
int
|
||||
gtk_constraint_vfl_parser_get_error_range (GtkConstraintVflParser *parser);
|
||||
|
||||
GtkConstraintVfl *
|
||||
gtk_constraint_vfl_parser_get_constraints (GtkConstraintVflParser *parser,
|
||||
int *n_constraints);
|
||||
|
||||
G_END_DECLS
|
||||
+24
-4
@@ -1080,10 +1080,10 @@ typedef enum {
|
||||
* 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
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED = 1001001000,
|
||||
GTK_CONSTRAINT_STRENGTH_STRONG = 1000000000,
|
||||
GTK_CONSTRAINT_STRENGTH_MEDIUM = 1000,
|
||||
GTK_CONSTRAINT_STRENGTH_WEAK = 1
|
||||
} GtkConstraintStrength;
|
||||
|
||||
/**
|
||||
@@ -1127,4 +1127,24 @@ typedef enum {
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BASELINE
|
||||
} GtkConstraintAttribute;
|
||||
|
||||
/**
|
||||
* GtkConstraintVflParserError:
|
||||
* @GTK_CONSTRAINT_VFL_PARSER_ERROR_INVALID_SYMBOL: Invalid or unknown symbol
|
||||
* @GTK_CONSTRAINT_VFL_PARSER_ERROR_INVALID_ATTRIBUTE: Invalid or unknown attribute
|
||||
* @GTK_CONSTRAINT_VFL_PARSER_ERROR_INVALID_VIEW: Invalid or unknown view
|
||||
* @GTK_CONSTRAINT_VFL_PARSER_ERROR_INVALID_METRIC: Invalid or unknown metric
|
||||
* @GTK_CONSTRAINT_VFL_PARSER_ERROR_INVALID_PRIORITY: Invalid or unknown priority
|
||||
* @GTK_CONSTRAINT_VFL_PARSER_ERROR_INVALID_RELATION: Invalid or unknown relation
|
||||
*
|
||||
* Domain for VFL parsing errors.
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_CONSTRAINT_VFL_PARSER_ERROR_INVALID_SYMBOL,
|
||||
GTK_CONSTRAINT_VFL_PARSER_ERROR_INVALID_ATTRIBUTE,
|
||||
GTK_CONSTRAINT_VFL_PARSER_ERROR_INVALID_VIEW,
|
||||
GTK_CONSTRAINT_VFL_PARSER_ERROR_INVALID_METRIC,
|
||||
GTK_CONSTRAINT_VFL_PARSER_ERROR_INVALID_PRIORITY,
|
||||
GTK_CONSTRAINT_VFL_PARSER_ERROR_INVALID_RELATION
|
||||
} GtkConstraintVflParserError;
|
||||
|
||||
#endif /* __GTK_ENUMS_H__ */
|
||||
|
||||
@@ -216,17 +216,25 @@ gtk_flatten_list_model_items_changed_cb (GListModel *model,
|
||||
guint added,
|
||||
gpointer _node)
|
||||
{
|
||||
FlattenNode *node = _node, *parent;
|
||||
FlattenNode *node = _node, *parent, *left;
|
||||
GtkFlattenListModel *self = node->list;
|
||||
guint real_position;
|
||||
|
||||
gtk_rb_tree_node_mark_dirty (node);
|
||||
real_position = position;
|
||||
|
||||
for (real_position = position;
|
||||
left = gtk_rb_tree_node_get_left (node);
|
||||
if (left)
|
||||
{
|
||||
FlattenAugment *aug = gtk_rb_tree_get_augment (self->items, left);
|
||||
real_position += aug->n_items;
|
||||
}
|
||||
|
||||
for (;
|
||||
(parent = gtk_rb_tree_node_get_parent (node)) != NULL;
|
||||
node = parent)
|
||||
{
|
||||
FlattenNode *left = gtk_rb_tree_node_get_left (parent);
|
||||
left = gtk_rb_tree_node_get_left (parent);
|
||||
if (left != node)
|
||||
{
|
||||
if (left)
|
||||
|
||||
+457
-28
@@ -20,11 +20,81 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkgridconstraint.h"
|
||||
#include "gtkgridconstraintprivate.h"
|
||||
|
||||
#include "gtkintl.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
|
||||
enum {
|
||||
POS_LEFT,
|
||||
POS_RIGHT,
|
||||
POS_TOP,
|
||||
POS_BOTTOM,
|
||||
LAST_POS,
|
||||
SIZE_WIDTH = LAST_POS,
|
||||
SIZE_HEIGHT,
|
||||
LAST_CONSTRAINT
|
||||
};
|
||||
|
||||
/* We maintain constraints of the form:
|
||||
*
|
||||
* child.top = row_x
|
||||
* child.bottom = row_y
|
||||
*
|
||||
* (and similar for columns). We avoid introducing
|
||||
* extra variables for rows and columns by keeping
|
||||
* track of the first child we encounter that ends
|
||||
* at a given position, and using that instead:
|
||||
*
|
||||
* child.top = first.bottom
|
||||
*
|
||||
* (assuming that @first is the first child we saw
|
||||
* that ends at row x (and has its bottom edge there).
|
||||
*
|
||||
* For homogeneous grids, we additionally maintain
|
||||
* constraints of the form:
|
||||
*
|
||||
* a.width / a.colspan = b.width / b.colspan
|
||||
*
|
||||
* (and similar for heights). We only maintain
|
||||
* these relations between a child and its
|
||||
* predecessor in the list of children.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
GtkConstraintTarget *child;
|
||||
int left;
|
||||
int right;
|
||||
int top;
|
||||
int bottom;
|
||||
|
||||
/* We hold a ref on these */
|
||||
GtkConstraint *constraints[LAST_CONSTRAINT];
|
||||
} GtkGridConstraintChild;
|
||||
|
||||
typedef struct {
|
||||
GtkConstraintTarget *target;
|
||||
GtkConstraintAttribute attr;
|
||||
} Attach;
|
||||
|
||||
struct _GtkGridConstraint {
|
||||
GObject parent;
|
||||
|
||||
GtkConstraintLayout *layout;
|
||||
|
||||
gboolean row_homogeneous;
|
||||
gboolean column_homogeneous;
|
||||
|
||||
/* List<GtkGridConstraintChild>, owned */
|
||||
GPtrArray *children;
|
||||
|
||||
/* List<GtkConstaint>, not owned */
|
||||
GPtrArray *constraints;
|
||||
|
||||
/* Array<Attach>, not owning Attach.target */
|
||||
GArray *rows;
|
||||
GArray *cols;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_ROW_HOMOGENEOUS = 1,
|
||||
PROP_COLUMN_HOMOGENEOUS,
|
||||
@@ -35,6 +105,11 @@ static GParamSpec *obj_props[N_PROPERTIES];
|
||||
|
||||
G_DEFINE_TYPE (GtkGridConstraint, gtk_grid_constraint, G_TYPE_OBJECT)
|
||||
|
||||
static void set_row_homogeneous (GtkGridConstraint *self,
|
||||
gboolean homogeneous);
|
||||
static void set_column_homogeneous (GtkGridConstraint *self,
|
||||
gboolean homogeneous);
|
||||
|
||||
static void
|
||||
gtk_constraint_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
@@ -46,11 +121,11 @@ gtk_constraint_set_property (GObject *gobject,
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ROW_HOMOGENEOUS:
|
||||
self->row_homogeneous = g_value_get_boolean (value);
|
||||
set_row_homogeneous (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_COLUMN_HOMOGENEOUS:
|
||||
self->column_homogeneous = g_value_get_boolean (value);
|
||||
set_column_homogeneous (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -83,12 +158,29 @@ gtk_constraint_get_property (GObject *gobject,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_grid_constraint_init (GtkGridConstraint *self)
|
||||
{
|
||||
self->children = g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
self->constraints = g_ptr_array_new ();
|
||||
|
||||
self->rows = g_array_new (FALSE, TRUE, sizeof (Attach));
|
||||
self->cols = g_array_new (FALSE, TRUE, sizeof (Attach));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_constraint_finalize (GObject *gobject)
|
||||
{
|
||||
GtkGridConstraint *self = GTK_GRID_CONSTRAINT (gobject);
|
||||
|
||||
gtk_grid_constraint_detach (self);
|
||||
g_array_free (self->rows, TRUE);
|
||||
g_array_free (self->cols, TRUE);
|
||||
|
||||
if (self->layout)
|
||||
gtk_grid_constraint_detach (self);
|
||||
g_assert (self->constraints->len == 0);
|
||||
g_ptr_array_free (self->constraints, TRUE);
|
||||
|
||||
g_ptr_array_free (self->children, TRUE);
|
||||
|
||||
@@ -134,9 +226,257 @@ gtk_grid_constraint_class_init (GtkGridConstraintClass *klass)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_grid_constraint_init (GtkGridConstraint *self)
|
||||
remove_child_constraint (GtkGridConstraint *self,
|
||||
GtkGridConstraintChild *child,
|
||||
int pos)
|
||||
{
|
||||
self->children = g_ptr_array_new_with_free_func (g_free);
|
||||
if (child->constraints[pos] == NULL)
|
||||
return;
|
||||
|
||||
if (self->layout)
|
||||
gtk_constraint_layout_remove_constraint (self->layout,
|
||||
child->constraints[pos]);
|
||||
g_object_unref (child->constraints[pos]);
|
||||
child->constraints[pos] = NULL;
|
||||
}
|
||||
|
||||
/* Ensure that the child variable @var is placed
|
||||
* at the grid edge @pos. If we already have a variable
|
||||
* that needs to end up there, we use it to assert
|
||||
* var = vars[top], otherwise we put @var in the
|
||||
* the list of variables.
|
||||
*
|
||||
* @attr may be one of LEFT/RIGHT/TOP/BOTTOM here.
|
||||
*/
|
||||
static void
|
||||
add_child_constraint (GtkGridConstraint *self,
|
||||
GtkGridConstraintChild *child,
|
||||
GtkConstraintAttribute attr,
|
||||
int pos)
|
||||
{
|
||||
Attach *attach;
|
||||
GArray *vars;
|
||||
int cpos;
|
||||
|
||||
switch ((int)attr)
|
||||
{
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_LEFT:
|
||||
vars = self->cols;
|
||||
cpos = POS_LEFT;
|
||||
break;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_RIGHT:
|
||||
vars = self->cols;
|
||||
cpos = POS_RIGHT;
|
||||
break;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_TOP:
|
||||
vars = self->rows;
|
||||
cpos = POS_TOP;
|
||||
break;
|
||||
case GTK_CONSTRAINT_ATTRIBUTE_BOTTOM:
|
||||
vars = self->rows;
|
||||
cpos = POS_BOTTOM;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (vars->len <= pos)
|
||||
g_array_set_size (vars, pos + 1);
|
||||
|
||||
attach = &g_array_index (vars, Attach, pos);
|
||||
if (attach->target == NULL)
|
||||
{
|
||||
attach->target = child->child;
|
||||
attach->attr = attr;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert (child->constraints[cpos] == NULL);
|
||||
|
||||
child->constraints[cpos] = gtk_constraint_new (child->child, attr,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
attach->target, attach->attr,
|
||||
1.0, 0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
if (self->layout)
|
||||
gtk_constraint_layout_add_constraint (self->layout,
|
||||
child->constraints[cpos]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the contraint:
|
||||
*
|
||||
* child1.width/child1.colspan = child2.width/child2.colspan
|
||||
*
|
||||
* @attr can be WIDTH or HEIGHT here.
|
||||
*/
|
||||
static void
|
||||
add_homogeneous_constraint (GtkGridConstraint *self,
|
||||
GtkGridConstraintChild *child1,
|
||||
GtkGridConstraintChild *child2,
|
||||
GtkConstraintAttribute attr)
|
||||
{
|
||||
int span1, span2;
|
||||
int pos;
|
||||
|
||||
if (attr == GTK_CONSTRAINT_ATTRIBUTE_WIDTH)
|
||||
{
|
||||
pos = SIZE_WIDTH;
|
||||
span1 = child1->right - child1->left;
|
||||
span2 = child2->right - child2->left;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = SIZE_HEIGHT;
|
||||
span1 = child1->bottom - child1->top;
|
||||
span2 = child2->bottom - child2->top;
|
||||
}
|
||||
|
||||
g_assert (child1->constraints[pos] == NULL);
|
||||
|
||||
child1->constraints[pos] = gtk_constraint_new (child1->child, attr,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child2->child, attr,
|
||||
(double) span1 / (double) span2,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
|
||||
if (self->layout)
|
||||
gtk_constraint_layout_add_constraint (self->layout,
|
||||
child1->constraints[pos]);
|
||||
}
|
||||
|
||||
static void
|
||||
set_row_homogeneous (GtkGridConstraint *self,
|
||||
gboolean homogeneous)
|
||||
{
|
||||
GtkGridConstraintChild *child1;
|
||||
GtkGridConstraintChild *child2;
|
||||
int i;
|
||||
|
||||
if (self->row_homogeneous == homogeneous)
|
||||
return;
|
||||
|
||||
self->row_homogeneous = homogeneous;
|
||||
|
||||
for (i = 1; i < self->children->len; i++)
|
||||
{
|
||||
child1 = g_ptr_array_index (self->children, i);
|
||||
child2 = g_ptr_array_index (self->children, i - 1);
|
||||
if (homogeneous)
|
||||
add_homogeneous_constraint (self, child1, child2, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT);
|
||||
else
|
||||
remove_child_constraint (self, child1, SIZE_HEIGHT);
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (self), "row-homogeneous");
|
||||
}
|
||||
|
||||
static void
|
||||
set_column_homogeneous (GtkGridConstraint *self,
|
||||
gboolean homogeneous)
|
||||
{
|
||||
GtkGridConstraintChild *child1;
|
||||
GtkGridConstraintChild *child2;
|
||||
int i;
|
||||
|
||||
if (self->column_homogeneous == homogeneous)
|
||||
return;
|
||||
|
||||
self->column_homogeneous = homogeneous;
|
||||
|
||||
for (i = 1; i < self->children->len; i++)
|
||||
{
|
||||
child1 = g_ptr_array_index (self->children, i);
|
||||
child2 = g_ptr_array_index (self->children, i - 1);
|
||||
if (homogeneous)
|
||||
add_homogeneous_constraint (self, child1, child2, GTK_CONSTRAINT_ATTRIBUTE_WIDTH);
|
||||
else
|
||||
remove_child_constraint (self, child1, SIZE_WIDTH);
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (self), "column-homogeneous");
|
||||
}
|
||||
|
||||
/* Fix up attachment constraints for the removal of @target.
|
||||
* We are fixing up the attachment at row/col @rows and
|
||||
* position @pos. If @target was not the representative
|
||||
* for this position, there is nothing to do (all of @targets
|
||||
* constraints are already removed). Otherwise, look over
|
||||
* all children that are attached to @target for this position,
|
||||
* pick a new representative, and fix up the constraints
|
||||
* for all others to attach to the new representative.
|
||||
*/
|
||||
static void
|
||||
fix_up_attach (GtkGridConstraint *self,
|
||||
GtkConstraintTarget *target,
|
||||
gboolean rows,
|
||||
int pos)
|
||||
{
|
||||
int i;
|
||||
Attach *attach;
|
||||
|
||||
if (rows)
|
||||
attach = &g_array_index (self->rows, Attach, pos);
|
||||
else
|
||||
attach = &g_array_index (self->cols, Attach, pos);
|
||||
|
||||
if (attach->target != target)
|
||||
return;
|
||||
|
||||
attach->target = NULL;
|
||||
|
||||
for (i = 0; i < self->children->len; i++)
|
||||
{
|
||||
int cpos;
|
||||
GtkGridConstraintChild *child;
|
||||
GtkConstraintAttribute attr;
|
||||
|
||||
child = g_ptr_array_index (self->children, i);
|
||||
if (rows && child->top == pos)
|
||||
{
|
||||
cpos = POS_TOP;
|
||||
attr = GTK_CONSTRAINT_ATTRIBUTE_TOP;
|
||||
}
|
||||
else if (rows && child->bottom == pos)
|
||||
{
|
||||
cpos = POS_BOTTOM;
|
||||
attr = GTK_CONSTRAINT_ATTRIBUTE_BOTTOM;
|
||||
}
|
||||
else if (!rows && child->left == pos)
|
||||
{
|
||||
cpos = POS_LEFT;
|
||||
attr = GTK_CONSTRAINT_ATTRIBUTE_LEFT;
|
||||
}
|
||||
else if (!rows && child->right == pos)
|
||||
{
|
||||
cpos = POS_LEFT;
|
||||
attr = GTK_CONSTRAINT_ATTRIBUTE_LEFT;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
remove_child_constraint (self, child, cpos);
|
||||
|
||||
if (attach->target == NULL)
|
||||
{
|
||||
attach->target = child->child;
|
||||
attach->attr = attr;
|
||||
}
|
||||
else
|
||||
{
|
||||
child->constraints[cpos] =
|
||||
gtk_constraint_new (child->child, attr,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
attach->target, attach->attr,
|
||||
1.0, 0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
if (self->layout)
|
||||
gtk_constraint_layout_add_constraint (self->layout,
|
||||
g_object_ref (child->constraints[cpos]));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GtkGridConstraint *
|
||||
@@ -153,54 +493,143 @@ gtk_grid_constraint_add (GtkGridConstraint *self,
|
||||
int top,
|
||||
int bottom)
|
||||
{
|
||||
GtkGridConstraintChild *data;
|
||||
GtkGridConstraintChild *child1;
|
||||
GtkGridConstraintChild *child2;
|
||||
|
||||
g_return_if_fail (GTK_IS_GRID_CONSTRAINT (self));
|
||||
g_return_if_fail (GTK_IS_WIDGET (child));
|
||||
g_return_if_fail (left < right);
|
||||
g_return_if_fail (top < bottom);
|
||||
g_return_if_fail (self->refs == NULL);
|
||||
g_return_if_fail (self->layout == NULL);
|
||||
|
||||
data = g_new0 (GtkGridConstraintChild, 1);
|
||||
child1 = g_new0 (GtkGridConstraintChild, 1);
|
||||
|
||||
data->child = child;
|
||||
data->left = left;
|
||||
data->right = right;
|
||||
data->top = top;
|
||||
data->bottom = bottom;
|
||||
child1->child = GTK_CONSTRAINT_TARGET (child);
|
||||
child1->left = left;
|
||||
child1->right = right;
|
||||
child1->top = top;
|
||||
child1->bottom = bottom;
|
||||
|
||||
g_ptr_array_add (self->children, data);
|
||||
if (self->children->len > 0)
|
||||
child2 = g_ptr_array_index (self->children, self->children->len - 1);
|
||||
else
|
||||
child2 = NULL;
|
||||
|
||||
add_child_constraint (self, child1, GTK_CONSTRAINT_ATTRIBUTE_TOP, top);
|
||||
add_child_constraint (self, child1, GTK_CONSTRAINT_ATTRIBUTE_BOTTOM, bottom);
|
||||
add_child_constraint (self, child1, GTK_CONSTRAINT_ATTRIBUTE_LEFT, left);
|
||||
add_child_constraint (self, child1, GTK_CONSTRAINT_ATTRIBUTE_RIGHT, right);
|
||||
|
||||
if (self->row_homogeneous && child2)
|
||||
add_homogeneous_constraint (self, child1, child2, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT);
|
||||
if (self->column_homogeneous && child2)
|
||||
add_homogeneous_constraint (self, child1, child2, GTK_CONSTRAINT_ATTRIBUTE_WIDTH);
|
||||
|
||||
g_ptr_array_add (self->children, child1);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_grid_constraint_remove (GtkGridConstraint *self,
|
||||
GtkWidget *child)
|
||||
{
|
||||
GtkGridConstraintChild *child1 = NULL;
|
||||
GtkGridConstraintChild *next = NULL;
|
||||
GtkGridConstraintChild *prev = NULL;
|
||||
GtkConstraintTarget *target = (GtkConstraintTarget *)child;
|
||||
int i;
|
||||
int left, right, top, bottom;
|
||||
|
||||
for (i = 0; i < self->children->len; i++)
|
||||
{
|
||||
child1 = g_ptr_array_index (self->children, i);
|
||||
if (child1->child == target)
|
||||
break;
|
||||
child1 = NULL;
|
||||
}
|
||||
|
||||
if (child1 == NULL)
|
||||
return;
|
||||
|
||||
if (i > 0)
|
||||
prev = g_ptr_array_index (self->children, i - 1);
|
||||
if (i + 1 < self->children->len)
|
||||
next = g_ptr_array_index (self->children, i + 1);
|
||||
|
||||
for (i = 0; i < LAST_CONSTRAINT; i++)
|
||||
remove_child_constraint (self, child1, i);
|
||||
|
||||
top = child1->top;
|
||||
bottom = child1->bottom;
|
||||
left = child1->left;
|
||||
right = child1->right;
|
||||
|
||||
g_ptr_array_remove (self->children, child1);
|
||||
|
||||
fix_up_attach (self, target, TRUE, top);
|
||||
fix_up_attach (self, target, TRUE, bottom);
|
||||
fix_up_attach (self, target, FALSE, right);
|
||||
fix_up_attach (self, target, FALSE, left);
|
||||
|
||||
if (self->column_homogeneous && next)
|
||||
{
|
||||
remove_child_constraint (self, next, SIZE_WIDTH);
|
||||
if (prev)
|
||||
add_homogeneous_constraint (self, next, prev, GTK_CONSTRAINT_ATTRIBUTE_WIDTH);
|
||||
}
|
||||
if (self->row_homogeneous && next)
|
||||
{
|
||||
remove_child_constraint (self, next, SIZE_HEIGHT);
|
||||
if (prev)
|
||||
add_homogeneous_constraint (self, next, prev, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_grid_constraint_is_attached (GtkGridConstraint *self)
|
||||
{
|
||||
return self->refs != NULL;
|
||||
return self->layout != NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_grid_constraint_attach (GtkGridConstraint *self,
|
||||
GtkConstraintSolver *solver,
|
||||
GPtrArray *refs)
|
||||
GtkConstraintLayout *layout)
|
||||
{
|
||||
g_return_if_fail (self->refs == NULL);
|
||||
int i, j;
|
||||
|
||||
self->solver = solver;
|
||||
self->refs = g_ptr_array_ref (refs);
|
||||
g_return_if_fail (self->layout == NULL);
|
||||
|
||||
self->layout = layout;
|
||||
|
||||
for (i = 0; i < self->children->len; i++)
|
||||
{
|
||||
GtkGridConstraintChild *child = g_ptr_array_index (self->children, i);
|
||||
for (j = 0; j < LAST_CONSTRAINT; j++)
|
||||
{
|
||||
if (child->constraints[j] != NULL)
|
||||
gtk_constraint_layout_add_constraint (self->layout,
|
||||
g_object_ref (child->constraints[j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gtk_grid_constraint_detach (GtkGridConstraint *self)
|
||||
void
|
||||
gtk_grid_constraint_detach (GtkGridConstraint *self)
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
if (self->refs == NULL)
|
||||
if (self->layout == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < self->refs->len; i++)
|
||||
for (i = 0; i < self->children->len; i++)
|
||||
{
|
||||
GtkConstraintRef *ref = g_ptr_array_index (self->refs, i);
|
||||
gtk_constraint_solver_remove_constraint (self->solver, ref);
|
||||
GtkGridConstraintChild *child = g_ptr_array_index (self->children, i);
|
||||
for (j = 0; j < LAST_CONSTRAINT; j++)
|
||||
{
|
||||
if (child->constraints[j] != NULL)
|
||||
gtk_constraint_layout_remove_constraint (self->layout,
|
||||
child->constraints[j]);
|
||||
}
|
||||
}
|
||||
|
||||
g_clear_pointer (&self->refs, g_ptr_array_unref);
|
||||
self->layout = NULL;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define __GTK_GRID_CONSTRAINT_H__
|
||||
|
||||
#include <gtk/gtkwidget.h>
|
||||
#include <gtk/gtkconstraintlayout.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -44,6 +45,18 @@ void gtk_grid_constraint_add (GtkGridConstraint *self,
|
||||
int top,
|
||||
int bottom);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_grid_constraint_remove (GtkGridConstraint *self,
|
||||
GtkWidget *child);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_grid_constraint_attach (GtkGridConstraint *self,
|
||||
GtkConstraintLayout *layout);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_grid_constraint_detach (GtkGridConstraint *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_grid_constraint_is_attached (GtkGridConstraint *self);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_GRID_CONSTRAINT_H__ */
|
||||
|
||||
@@ -212,6 +212,8 @@ gtk_grid_layout_child_class_init (GtkGridLayoutChildClass *klass)
|
||||
static void
|
||||
gtk_grid_layout_child_init (GtkGridLayoutChild *self)
|
||||
{
|
||||
CHILD_ROW_SPAN (self) = 1;
|
||||
CHILD_COL_SPAN (self) = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,6 +39,7 @@ gtk_private_sources = files([
|
||||
'gtkcolorswatch.c',
|
||||
'gtkconstraintexpression.c',
|
||||
'gtkconstraintsolver.c',
|
||||
'gtkconstraintvflparser.c',
|
||||
'gtkcssanimatedstyle.c',
|
||||
'gtkcssanimation.c',
|
||||
'gtkcssarrayvalue.c',
|
||||
@@ -465,6 +466,7 @@ gtk_public_headers = files([
|
||||
'gtkcolorutils.h',
|
||||
'gtkcombobox.h',
|
||||
'gtkcomboboxtext.h',
|
||||
'gtkconstraintguide.h',
|
||||
'gtkconstraintlayout.h',
|
||||
'gtkconstraint.h',
|
||||
'gtkcontainer.h',
|
||||
|
||||
@@ -2178,11 +2178,11 @@ popover>contents {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
popover>contents.background {
|
||||
popover.background>contents {
|
||||
|
||||
background-color: $popover_bg_color;
|
||||
box-shadow: 0 1px 2px transparentize(black, 0.7);
|
||||
.csd &, & {
|
||||
.csd &, & {
|
||||
border: 1px solid $borders_color;
|
||||
border-radius: $popover_radius;
|
||||
}
|
||||
@@ -4766,8 +4766,9 @@ popover.menu {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
arrow,
|
||||
&.background contents {
|
||||
background: white;
|
||||
background-color: $menu_color;
|
||||
}
|
||||
|
||||
&.background separator {
|
||||
|
||||
@@ -82,9 +82,9 @@ assistant .sidebar label { padding: 6px 12px; }
|
||||
|
||||
assistant .sidebar label.highlight { background-color: #5a5a59; }
|
||||
|
||||
.csd popover > contents.background.touch-selection, .csd popover > contents.background.magnifier, popover > contents.background.touch-selection, popover > contents.background.magnifier, .csd popover > contents.background.osd, popover > contents.background.osd, .app-notification, .app-notification.frame, .osd .scale-popup, .osd { color: #eeeeec; border: none; background-color: rgba(38, 38, 38, 0.7); background-clip: padding-box; text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; }
|
||||
.csd popover.background > contents.touch-selection, .csd popover.background > contents.magnifier, popover.background > contents.touch-selection, popover.background > contents.magnifier, .csd popover.background > contents.osd, popover.background > contents.osd, .app-notification, .app-notification.frame, .osd .scale-popup, .osd { color: #eeeeec; border: none; background-color: rgba(37, 37, 38, 0.7); background-clip: padding-box; text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; }
|
||||
|
||||
.csd popover > contents.background.touch-selection:backdrop, .csd popover > contents.background.magnifier:backdrop, popover > contents.background.touch-selection:backdrop, popover > contents.background.magnifier:backdrop, .csd popover > contents.background.osd:backdrop, popover > contents.background.osd:backdrop, .app-notification:backdrop, .osd .scale-popup:backdrop, .osd:backdrop { text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.csd popover.background > contents.touch-selection:backdrop, .csd popover.background > contents.magnifier:backdrop, popover.background > contents.touch-selection:backdrop, popover.background > contents.magnifier:backdrop, .csd popover.background > contents.osd:backdrop, popover.background > contents.osd:backdrop, .app-notification:backdrop, .osd .scale-popup:backdrop, .osd:backdrop { text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
/********************* Spinner Animation * */
|
||||
@keyframes spin { to { -gtk-icon-transform: rotate(1turn); } }
|
||||
@@ -265,7 +265,7 @@ row:selected button.sidebar-button:not(:active):not(:checked):not(:hover):not(di
|
||||
|
||||
row:selected button.sidebar-button:not(:active):not(:checked):not(:hover):not(disabled):backdrop, row:selected button.flat:not(:active):not(:checked):not(:hover):not(disabled):backdrop { color: #919190; }
|
||||
|
||||
button.osd { min-width: 26px; min-height: 32px; color: #eeeeec; border-radius: 5px; color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); border: none; box-shadow: none; }
|
||||
button.osd { min-width: 26px; min-height: 32px; color: #eeeeec; border-radius: 5px; color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); border: none; box-shadow: none; }
|
||||
|
||||
button.osd.image-button { min-width: 34px; }
|
||||
|
||||
@@ -275,27 +275,27 @@ button.osd:active, button.osd:checked { color: white; border-color: rgba(0, 0, 0
|
||||
|
||||
button.osd:disabled:backdrop, button.osd:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; border: none; }
|
||||
|
||||
button.osd:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; border: none; }
|
||||
button.osd:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; border: none; }
|
||||
|
||||
.csd popover > contents.background.touch-selection button, .csd popover > contents.background.magnifier button, popover > contents.background.touch-selection button, popover > contents.background.magnifier button, .app-notification button, .app-notification.frame button, .osd button { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.csd popover.background > contents.touch-selection button, .csd popover.background > contents.magnifier button, popover.background > contents.touch-selection button, popover.background > contents.magnifier button, .app-notification button, .app-notification.frame button, .osd button { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.csd popover > contents.background.touch-selection button:hover, .csd popover > contents.background.magnifier button:hover, popover > contents.background.touch-selection button:hover, popover > contents.background.magnifier button:hover, .app-notification button:hover, .osd button:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.csd popover.background > contents.touch-selection button:hover, .csd popover.background > contents.magnifier button:hover, popover.background > contents.touch-selection button:hover, popover.background > contents.magnifier button:hover, .app-notification button:hover, .osd button:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.csd popover > contents.background.touch-selection button:active:backdrop, .csd popover > contents.background.magnifier button:active:backdrop, popover > contents.background.touch-selection button:active:backdrop, popover > contents.background.magnifier button:active:backdrop, .app-notification button:active:backdrop, .csd popover > contents.background.touch-selection button:active, .csd popover > contents.background.magnifier button:active, popover > contents.background.touch-selection button:active, popover > contents.background.magnifier button:active, .app-notification button:active, .csd popover > contents.background.touch-selection button:checked:backdrop, .csd popover > contents.background.magnifier button:checked:backdrop, popover > contents.background.touch-selection button:checked:backdrop, popover > contents.background.magnifier button:checked:backdrop, .app-notification button:checked:backdrop, .csd popover > contents.background.touch-selection button:checked, .csd popover > contents.background.magnifier button:checked, popover > contents.background.touch-selection button:checked, popover > contents.background.magnifier button:checked, .app-notification button:checked, .osd button:active:backdrop, .osd button:active, .osd button:checked:backdrop, .osd button:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.csd popover.background > contents.touch-selection button:active:backdrop, .csd popover.background > contents.magnifier button:active:backdrop, popover.background > contents.touch-selection button:active:backdrop, popover.background > contents.magnifier button:active:backdrop, .app-notification button:active:backdrop, .csd popover.background > contents.touch-selection button:active, .csd popover.background > contents.magnifier button:active, popover.background > contents.touch-selection button:active, popover.background > contents.magnifier button:active, .app-notification button:active, .csd popover.background > contents.touch-selection button:checked:backdrop, .csd popover.background > contents.magnifier button:checked:backdrop, popover.background > contents.touch-selection button:checked:backdrop, popover.background > contents.magnifier button:checked:backdrop, .app-notification button:checked:backdrop, .csd popover.background > contents.touch-selection button:checked, .csd popover.background > contents.magnifier button:checked, popover.background > contents.touch-selection button:checked, popover.background > contents.magnifier button:checked, .app-notification button:checked, .osd button:active:backdrop, .osd button:active, .osd button:checked:backdrop, .osd button:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.csd popover > contents.background.touch-selection button:disabled:backdrop, .csd popover > contents.background.magnifier button:disabled:backdrop, popover > contents.background.touch-selection button:disabled:backdrop, popover > contents.background.magnifier button:disabled:backdrop, .app-notification button:disabled:backdrop, .csd popover > contents.background.touch-selection button:disabled, .csd popover > contents.background.magnifier button:disabled, popover > contents.background.touch-selection button:disabled, popover > contents.background.magnifier button:disabled, .app-notification button:disabled, .osd button:disabled:backdrop, .osd button:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.csd popover.background > contents.touch-selection button:disabled:backdrop, .csd popover.background > contents.magnifier button:disabled:backdrop, popover.background > contents.touch-selection button:disabled:backdrop, popover.background > contents.magnifier button:disabled:backdrop, .app-notification button:disabled:backdrop, .csd popover.background > contents.touch-selection button:disabled, .csd popover.background > contents.magnifier button:disabled, popover.background > contents.touch-selection button:disabled, popover.background > contents.magnifier button:disabled, .app-notification button:disabled, .osd button:disabled:backdrop, .osd button:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.csd popover > contents.background.touch-selection button:backdrop, .csd popover > contents.background.magnifier button:backdrop, popover > contents.background.touch-selection button:backdrop, popover > contents.background.magnifier button:backdrop, .app-notification button:backdrop, .osd button:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.csd popover.background > contents.touch-selection button:backdrop, .csd popover.background > contents.magnifier button:backdrop, popover.background > contents.touch-selection button:backdrop, popover.background > contents.magnifier button:backdrop, .app-notification button:backdrop, .osd button:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.csd popover > contents.background.touch-selection button.flat, .csd popover > contents.background.magnifier button.flat, popover > contents.background.touch-selection button.flat, popover > contents.background.magnifier button.flat, .app-notification button.flat, .osd button.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; box-shadow: none; text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; }
|
||||
.csd popover.background > contents.touch-selection button.flat, .csd popover.background > contents.magnifier button.flat, popover.background > contents.touch-selection button.flat, popover.background > contents.magnifier button.flat, .app-notification button.flat, .osd button.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; box-shadow: none; text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; }
|
||||
|
||||
.csd popover > contents.background.touch-selection button.flat:hover, .csd popover > contents.background.magnifier button.flat:hover, popover > contents.background.touch-selection button.flat:hover, popover > contents.background.magnifier button.flat:hover, .app-notification button.flat:hover, .osd button.flat:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.csd popover.background > contents.touch-selection button.flat:hover, .csd popover.background > contents.magnifier button.flat:hover, popover.background > contents.touch-selection button.flat:hover, popover.background > contents.magnifier button.flat:hover, .app-notification button.flat:hover, .osd button.flat:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.csd popover > contents.background.touch-selection button.flat:disabled, .csd popover > contents.background.magnifier button.flat:disabled, popover > contents.background.touch-selection button.flat:disabled, popover > contents.background.magnifier button.flat:disabled, .app-notification button.flat:disabled, .osd button.flat:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; background-image: none; border-color: transparent; box-shadow: none; }
|
||||
.csd popover.background > contents.touch-selection button.flat:disabled, .csd popover.background > contents.magnifier button.flat:disabled, popover.background > contents.touch-selection button.flat:disabled, popover.background > contents.magnifier button.flat:disabled, .app-notification button.flat:disabled, .osd button.flat:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; background-image: none; border-color: transparent; box-shadow: none; }
|
||||
|
||||
.csd popover > contents.background.touch-selection button.flat:backdrop, .csd popover > contents.background.magnifier button.flat:backdrop, popover > contents.background.touch-selection button.flat:backdrop, popover > contents.background.magnifier button.flat:backdrop, .app-notification button.flat:backdrop, .osd button.flat:backdrop { border-color: transparent; background-color: transparent; background-image: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.csd popover.background > contents.touch-selection button.flat:backdrop, .csd popover.background > contents.magnifier button.flat:backdrop, popover.background > contents.touch-selection button.flat:backdrop, popover.background > contents.magnifier button.flat:backdrop, .app-notification button.flat:backdrop, .osd button.flat:backdrop { border-color: transparent; background-color: transparent; background-image: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.csd popover > contents.background.touch-selection button.flat:active, .csd popover > contents.background.magnifier button.flat:active, popover > contents.background.touch-selection button.flat:active, popover > contents.background.magnifier button.flat:active, .app-notification button.flat:active, .csd popover > contents.background.touch-selection button.flat:checked, .csd popover > contents.background.magnifier button.flat:checked, popover > contents.background.touch-selection button.flat:checked, popover > contents.background.magnifier button.flat:checked, .app-notification button.flat:checked, .osd button.flat:active, .osd button.flat:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.csd popover.background > contents.touch-selection button.flat:active, .csd popover.background > contents.magnifier button.flat:active, popover.background > contents.touch-selection button.flat:active, popover.background > contents.magnifier button.flat:active, .app-notification button.flat:active, .csd popover.background > contents.touch-selection button.flat:checked, .csd popover.background > contents.magnifier button.flat:checked, popover.background > contents.touch-selection button.flat:checked, popover.background > contents.magnifier button.flat:checked, .app-notification button.flat:checked, .osd button.flat:active, .osd button.flat:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
button.suggested-action { color: white; outline-color: rgba(255, 255, 255, 0.3); border-color: #0f3b71; border-bottom-color: #092444; background-image: linear-gradient(to top, #155099 2px, #15539e); text-shadow: 0 -1px rgba(0, 0, 0, 0.719216); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.719216); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px 2px rgba(0, 0, 0, 0.07); }
|
||||
|
||||
@@ -497,7 +497,7 @@ button:link > label:active, button:visited > label:active, *:link:active, button
|
||||
|
||||
*:selected button:link > label:active, *:selected button:visited > label:active, *:selected *:link:active, *:selected button:active:link, *:selected button:active:visited { color: #d0ddec; }
|
||||
|
||||
button:link > label:disabled, button:visited > label:disabled, button:link > label:disabled:backdrop, button:visited > label:disabled:backdrop, *:link:disabled, button:disabled:link, button:disabled:visited, *:link:disabled:backdrop, button:disabled:backdrop:link, button:disabled:backdrop:visited { color: rgba(141, 141, 141, 0.8); }
|
||||
button:link > label:disabled, button:visited > label:disabled, button:link > label:disabled:backdrop, button:visited > label:disabled:backdrop, *:link:disabled, button:disabled:link, button:disabled:visited, *:link:disabled:backdrop, button:disabled:backdrop:link, button:disabled:backdrop:visited { color: rgba(140, 140, 141, 0.8); }
|
||||
|
||||
button:link > label:backdrop:backdrop:hover, button:visited > label:backdrop:backdrop:hover, button:link > label:backdrop:backdrop:hover:selected, button:visited > label:backdrop:backdrop:hover:selected, button:link > label:backdrop, button:visited > label:backdrop, *:link:backdrop:backdrop:hover, button:backdrop:backdrop:hover:link, button:backdrop:backdrop:hover:visited, *:link:backdrop:backdrop:hover:selected, button:backdrop:backdrop:hover:selected:link, button:backdrop:backdrop:hover:selected:visited, .selection-mode .titlebar:not(headerbar) .subtitle:backdrop:backdrop:hover:link, .selection-mode.titlebar:not(headerbar) .subtitle:backdrop:backdrop:hover:link, .selection-mode headerbar .subtitle:backdrop:backdrop:hover:link, headerbar.selection-mode .subtitle:backdrop:backdrop:hover:link, *:link:backdrop, button:backdrop:link, button:backdrop:visited { color: #15539e; }
|
||||
|
||||
@@ -564,7 +564,7 @@ spinbutton.vertical button.up { border-bottom-style: none; border-bottom-left-ra
|
||||
|
||||
spinbutton.vertical button.down { border-top-style: none; border-top-left-radius: 0; border-top-right-radius: 0; }
|
||||
|
||||
.osd spinbutton.vertical button:first-child { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.osd spinbutton.vertical button:first-child { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.osd spinbutton.vertical button:first-child:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
@@ -572,7 +572,7 @@ spinbutton.vertical button.down { border-top-style: none; border-top-left-radius
|
||||
|
||||
.osd spinbutton.vertical button:first-child:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.osd spinbutton.vertical button:first-child:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.osd spinbutton.vertical button:first-child:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
treeview spinbutton:not(.vertical) { min-height: 0; border-style: none; border-radius: 0; }
|
||||
|
||||
@@ -590,7 +590,7 @@ toolbar { padding: 4px 3px 3px 4px; }
|
||||
|
||||
.osd toolbar { background-color: transparent; }
|
||||
|
||||
toolbar.osd { padding: 13px; border: none; border-radius: 5px; background-color: rgba(38, 38, 38, 0.7); }
|
||||
toolbar.osd { padding: 13px; border: none; border-radius: 5px; background-color: rgba(37, 37, 38, 0.7); }
|
||||
|
||||
toolbar.osd.left, toolbar.osd.right, toolbar.osd.top, toolbar.osd.bottom { border-radius: 0; }
|
||||
|
||||
@@ -613,7 +613,7 @@ searchbar > revealer > box { padding: 6px; border-width: 0 0 1px; }
|
||||
.inline-toolbar:backdrop, .location-bar:backdrop, searchbar > revealer > box:backdrop { border-color: #202020; background-color: #2e2e2e; box-shadow: none; transition: 200ms ease-out; }
|
||||
|
||||
/*************** Header bars * */
|
||||
.titlebar:not(headerbar), headerbar { padding: 0 6px; min-height: 46px; border-width: 0 0 1px; border-style: solid; border-color: #070707; border-radius: 0; background: #1b1b1b linear-gradient(to top, #262626, #2b2b2b); box-shadow: inset 0 1px rgba(238, 238, 236, 0.07); /* Darken switchbuttons for headerbars. issue #1588 */ /* hide the close button separator */ }
|
||||
.titlebar:not(headerbar), headerbar { padding: 0 6px; min-height: 46px; border-width: 0 0 1px; border-style: solid; border-color: #070707; border-radius: 0; background: #1b1b1b linear-gradient(to top, #252526, #2b2b2b); box-shadow: inset 0 1px rgba(238, 238, 236, 0.07); /* Darken switchbuttons for headerbars. issue #1588 */ /* hide the close button separator */ }
|
||||
|
||||
.titlebar:backdrop:not(headerbar), headerbar:backdrop { border-color: #202020; background-color: #353535; background-image: none; box-shadow: inset 0 1px rgba(238, 238, 236, 0.07); transition: 200ms ease-out; }
|
||||
|
||||
@@ -879,19 +879,19 @@ popover.menu > arrow, popover > arrow { background-color: #353535; border: 1px s
|
||||
|
||||
popover > contents { padding: 8px; background-color: #353535; border: 1px solid #1b1b1b; margin: 0px; }
|
||||
|
||||
popover > contents.background { background-color: #353535; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); }
|
||||
popover.background > contents { background-color: #353535; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); }
|
||||
|
||||
.csd popover > contents.background, popover > contents.background { border: 1px solid #1b1b1b; border-radius: 9px; }
|
||||
.csd popover.background > contents, popover.background > contents { border: 1px solid #1b1b1b; border-radius: 9px; }
|
||||
|
||||
popover > contents.background:backdrop { background-color: #353535; box-shadow: none; }
|
||||
popover.background > contents:backdrop { background-color: #353535; box-shadow: none; }
|
||||
|
||||
popover > contents.background > list, popover > contents.background > .view, popover > contents.background > iconview, popover > contents.background > toolbar { border-style: none; background-color: transparent; }
|
||||
popover.background > contents > list, popover.background > contents > .view, popover.background > contents > iconview, popover.background > contents > toolbar { border-style: none; background-color: transparent; }
|
||||
|
||||
.csd popover > contents.background.touch-selection, .csd popover > contents.background.magnifier, popover > contents.background.touch-selection, popover > contents.background.magnifier { border: 1px solid rgba(255, 255, 255, 0.1); }
|
||||
.csd popover.background > contents.touch-selection, .csd popover.background > contents.magnifier, popover.background > contents.touch-selection, popover.background > contents.magnifier { border: 1px solid rgba(255, 255, 255, 0.1); }
|
||||
|
||||
popover > contents.background separator { margin: 3px; }
|
||||
popover.background > contents separator { margin: 3px; }
|
||||
|
||||
popover > contents.background list separator { margin: 0px; }
|
||||
popover.background > contents list separator { margin: 0px; }
|
||||
|
||||
/************* Notebooks * */
|
||||
notebook box > header { padding: 1px; border-color: #1b1b1b; border-width: 1px; background-color: #282828; }
|
||||
@@ -1141,7 +1141,7 @@ switch:backdrop:disabled slider label, switch:backdrop:disabled slider { color:
|
||||
|
||||
.view.content-view.check:active:not(list), iconview.content-view.check:active:not(list), .content-view .tile check:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: rgba(21, 83, 158, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.view.content-view.check:backdrop:not(list), iconview.content-view.check:backdrop:not(list), .content-view .tile check:backdrop:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: rgba(90, 90, 90, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
|
||||
.view.content-view.check:backdrop:not(list), iconview.content-view.check:backdrop:not(list), .content-view .tile check:backdrop:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: rgba(89, 89, 90, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.view.content-view.check:checked:not(list), iconview.content-view.check:checked:not(list), .content-view .tile check:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: rgba(21, 83, 158, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
|
||||
|
||||
@@ -1149,7 +1149,7 @@ switch:backdrop:disabled slider label, switch:backdrop:disabled slider { color:
|
||||
|
||||
.view.content-view.check:checked:active:not(list), iconview.content-view.check:checked:active:not(list), .content-view .tile check:checked:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: rgba(21, 83, 158, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
|
||||
|
||||
.view.content-view.check:backdrop:checked:not(list), iconview.content-view.check:backdrop:checked:not(list), .content-view .tile check:backdrop:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: rgba(238, 238, 236, 0.8); background-color: rgba(90, 90, 90, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
|
||||
.view.content-view.check:backdrop:checked:not(list), iconview.content-view.check:backdrop:checked:not(list), .content-view .tile check:backdrop:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: rgba(238, 238, 236, 0.8); background-color: rgba(89, 89, 90, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
|
||||
|
||||
checkbutton.text-button, radiobutton.text-button { padding: 2px 0; outline-offset: 0; }
|
||||
|
||||
@@ -1157,7 +1157,7 @@ checkbutton.text-button label:not(:only-child):first-child, radiobutton.text-but
|
||||
|
||||
checkbutton.text-button label:not(:only-child):last-child, radiobutton.text-button label:not(:only-child):last-child { margin-right: 4px; }
|
||||
|
||||
check, radio { margin: 0 4px; min-height: 14px; min-width: 14px; border: 1px solid; -gtk-icon-source: none; color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #070707; text-shadow: 0 -1px rgba(0, 0, 0, 0.834353); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.834353); background-image: linear-gradient(to bottom, #2d2d2d 20%, #262626 90%); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); }
|
||||
check, radio { margin: 0 4px; min-height: 14px; min-width: 14px; border: 1px solid; -gtk-icon-source: none; color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #070707; text-shadow: 0 -1px rgba(0, 0, 0, 0.834353); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.834353); background-image: linear-gradient(to bottom, #2d2d2d 20%, #252526 90%); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); }
|
||||
|
||||
check:only-child, radio:only-child { margin: 0; }
|
||||
|
||||
@@ -1181,13 +1181,13 @@ check:backdrop:disabled, radio:backdrop:disabled { border-color: #202020; backgr
|
||||
|
||||
check:backdrop:disabled label, check:backdrop:disabled, radio:backdrop:disabled label, radio:backdrop:disabled { color: #5b5b5b; }
|
||||
|
||||
.osd check, .osd radio { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.osd check, .osd radio { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.osd check:hover, .osd radio:hover { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.osd check:hover, .osd radio:hover { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.osd check:active, .osd radio:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.osd check:backdrop, .osd radio:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.osd check:backdrop, .osd radio:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.osd check:disabled, .osd radio:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
@@ -1280,7 +1280,7 @@ scale fill:disabled:backdrop, scale fill:disabled { border-color: transparent; b
|
||||
|
||||
.osd scale fill:disabled:backdrop, .osd scale fill:disabled { border-color: transparent; background-color: transparent; }
|
||||
|
||||
scale slider { color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #070707; text-shadow: 0 -1px rgba(0, 0, 0, 0.834353); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.834353); background-image: linear-gradient(to bottom, #2d2d2d 20%, #262626 90%); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); border: 1px solid black; border-radius: 100%; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: background, border, box-shadow; }
|
||||
scale slider { color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #070707; text-shadow: 0 -1px rgba(0, 0, 0, 0.834353); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.834353); background-image: linear-gradient(to bottom, #2d2d2d 20%, #252526 90%); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); border: 1px solid black; border-radius: 100%; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: background, border, box-shadow; }
|
||||
|
||||
scale slider:hover { color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #070707; box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); background-image: linear-gradient(to bottom, #353535 20%, #2b2b2b 90%); }
|
||||
|
||||
@@ -1300,17 +1300,17 @@ scale slider:backdrop:disabled label, scale slider:backdrop:disabled { color: #5
|
||||
|
||||
row:selected scale slider:disabled, row:selected scale slider { border-color: #030c17; }
|
||||
|
||||
.osd scale slider { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); border-color: rgba(0, 0, 0, 0.7); background-color: #262626; }
|
||||
.osd scale slider { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); border-color: rgba(0, 0, 0, 0.7); background-color: #252526; }
|
||||
|
||||
.osd scale slider:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); background-color: #262626; }
|
||||
.osd scale slider:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); background-color: #252526; }
|
||||
|
||||
.osd scale slider:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); background-color: #262626; }
|
||||
.osd scale slider:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); background-color: #252526; }
|
||||
|
||||
.osd scale slider:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; background-color: #262626; }
|
||||
.osd scale slider:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; background-color: #252526; }
|
||||
|
||||
.osd scale slider:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; background-color: #262626; }
|
||||
.osd scale slider:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; background-color: #252526; }
|
||||
|
||||
.osd scale slider:backdrop:disabled { background-color: #262626; }
|
||||
.osd scale slider:backdrop:disabled { background-color: #252526; }
|
||||
|
||||
scale value { color: alpha(currentColor,0.55); }
|
||||
|
||||
@@ -1636,7 +1636,7 @@ row.activatable:selected.has-open-popup, row.activatable:selected:hover { backgr
|
||||
row.activatable:selected:backdrop { background-color: #15539e; }
|
||||
|
||||
/********************* App Notifications * */
|
||||
.app-notification, .app-notification.frame { padding: 10px; border-radius: 0 0 5px 5px; background-color: rgba(38, 38, 38, 0.7); background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.2), transparent 2px); background-clip: padding-box; }
|
||||
.app-notification, .app-notification.frame { padding: 10px; border-radius: 0 0 5px 5px; background-color: rgba(37, 37, 38, 0.7); background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.2), transparent 2px); background-clip: padding-box; }
|
||||
|
||||
.app-notification:backdrop, .app-notification.frame:backdrop { background-image: none; transition: 200ms ease-out; }
|
||||
|
||||
@@ -2063,7 +2063,7 @@ popover.menu box.inline-buttons { border-radius: 5px; border-style: none; border
|
||||
|
||||
popover.menu box.circular-buttons { padding-bottom: 5px; }
|
||||
|
||||
popover.menu.background contents { background: white; }
|
||||
popover.menu arrow, popover.menu.background contents { background-color: #2f2f2f; }
|
||||
|
||||
popover.menu.background separator { margin: 5px 0px; }
|
||||
|
||||
|
||||
@@ -82,9 +82,9 @@ assistant .sidebar label { padding: 6px 12px; }
|
||||
|
||||
assistant .sidebar label.highlight { background-color: #cecece; }
|
||||
|
||||
.csd popover > contents.background.touch-selection, .csd popover > contents.background.magnifier, popover > contents.background.touch-selection, popover > contents.background.magnifier, .csd popover > contents.background.osd, popover > contents.background.osd, .app-notification, .app-notification.frame, .osd .scale-popup, .osd { color: #eeeeec; border: none; background-color: rgba(53, 53, 53, 0.7); background-clip: padding-box; text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; }
|
||||
.csd popover.background > contents.touch-selection, .csd popover.background > contents.magnifier, popover.background > contents.touch-selection, popover.background > contents.magnifier, .csd popover.background > contents.osd, popover.background > contents.osd, .app-notification, .app-notification.frame, .osd .scale-popup, .osd { color: #eeeeec; border: none; background-color: rgba(53, 53, 53, 0.7); background-clip: padding-box; text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; }
|
||||
|
||||
.csd popover > contents.background.touch-selection:backdrop, .csd popover > contents.background.magnifier:backdrop, popover > contents.background.touch-selection:backdrop, popover > contents.background.magnifier:backdrop, .csd popover > contents.background.osd:backdrop, popover > contents.background.osd:backdrop, .app-notification:backdrop, .osd .scale-popup:backdrop, .osd:backdrop { text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.csd popover.background > contents.touch-selection:backdrop, .csd popover.background > contents.magnifier:backdrop, popover.background > contents.touch-selection:backdrop, popover.background > contents.magnifier:backdrop, .csd popover.background > contents.osd:backdrop, popover.background > contents.osd:backdrop, .app-notification:backdrop, .osd .scale-popup:backdrop, .osd:backdrop { text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
/********************* Spinner Animation * */
|
||||
@keyframes spin { to { -gtk-icon-transform: rotate(1turn); } }
|
||||
@@ -279,25 +279,25 @@ button.osd:disabled:backdrop, button.osd:disabled { color: #919190; border-color
|
||||
|
||||
button.osd:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; border: none; }
|
||||
|
||||
.csd popover > contents.background.touch-selection button, .csd popover > contents.background.magnifier button, popover > contents.background.touch-selection button, popover > contents.background.magnifier button, .app-notification button, .app-notification.frame button, .osd button { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.csd popover.background > contents.touch-selection button, .csd popover.background > contents.magnifier button, popover.background > contents.touch-selection button, popover.background > contents.magnifier button, .app-notification button, .app-notification.frame button, .osd button { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.csd popover > contents.background.touch-selection button:hover, .csd popover > contents.background.magnifier button:hover, popover > contents.background.touch-selection button:hover, popover > contents.background.magnifier button:hover, .app-notification button:hover, .osd button:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(83, 83, 83, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.csd popover.background > contents.touch-selection button:hover, .csd popover.background > contents.magnifier button:hover, popover.background > contents.touch-selection button:hover, popover.background > contents.magnifier button:hover, .app-notification button:hover, .osd button:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(83, 83, 83, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.csd popover > contents.background.touch-selection button:active:backdrop, .csd popover > contents.background.magnifier button:active:backdrop, popover > contents.background.touch-selection button:active:backdrop, popover > contents.background.magnifier button:active:backdrop, .app-notification button:active:backdrop, .csd popover > contents.background.touch-selection button:active, .csd popover > contents.background.magnifier button:active, popover > contents.background.touch-selection button:active, popover > contents.background.magnifier button:active, .app-notification button:active, .csd popover > contents.background.touch-selection button:checked:backdrop, .csd popover > contents.background.magnifier button:checked:backdrop, popover > contents.background.touch-selection button:checked:backdrop, popover > contents.background.magnifier button:checked:backdrop, .app-notification button:checked:backdrop, .csd popover > contents.background.touch-selection button:checked, .csd popover > contents.background.magnifier button:checked, popover > contents.background.touch-selection button:checked, popover > contents.background.magnifier button:checked, .app-notification button:checked, .osd button:active:backdrop, .osd button:active, .osd button:checked:backdrop, .osd button:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.csd popover.background > contents.touch-selection button:active:backdrop, .csd popover.background > contents.magnifier button:active:backdrop, popover.background > contents.touch-selection button:active:backdrop, popover.background > contents.magnifier button:active:backdrop, .app-notification button:active:backdrop, .csd popover.background > contents.touch-selection button:active, .csd popover.background > contents.magnifier button:active, popover.background > contents.touch-selection button:active, popover.background > contents.magnifier button:active, .app-notification button:active, .csd popover.background > contents.touch-selection button:checked:backdrop, .csd popover.background > contents.magnifier button:checked:backdrop, popover.background > contents.touch-selection button:checked:backdrop, popover.background > contents.magnifier button:checked:backdrop, .app-notification button:checked:backdrop, .csd popover.background > contents.touch-selection button:checked, .csd popover.background > contents.magnifier button:checked, popover.background > contents.touch-selection button:checked, popover.background > contents.magnifier button:checked, .app-notification button:checked, .osd button:active:backdrop, .osd button:active, .osd button:checked:backdrop, .osd button:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.csd popover > contents.background.touch-selection button:disabled:backdrop, .csd popover > contents.background.magnifier button:disabled:backdrop, popover > contents.background.touch-selection button:disabled:backdrop, popover > contents.background.magnifier button:disabled:backdrop, .app-notification button:disabled:backdrop, .csd popover > contents.background.touch-selection button:disabled, .csd popover > contents.background.magnifier button:disabled, popover > contents.background.touch-selection button:disabled, popover > contents.background.magnifier button:disabled, .app-notification button:disabled, .osd button:disabled:backdrop, .osd button:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.csd popover.background > contents.touch-selection button:disabled:backdrop, .csd popover.background > contents.magnifier button:disabled:backdrop, popover.background > contents.touch-selection button:disabled:backdrop, popover.background > contents.magnifier button:disabled:backdrop, .app-notification button:disabled:backdrop, .csd popover.background > contents.touch-selection button:disabled, .csd popover.background > contents.magnifier button:disabled, popover.background > contents.touch-selection button:disabled, popover.background > contents.magnifier button:disabled, .app-notification button:disabled, .osd button:disabled:backdrop, .osd button:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.csd popover > contents.background.touch-selection button:backdrop, .csd popover > contents.background.magnifier button:backdrop, popover > contents.background.touch-selection button:backdrop, popover > contents.background.magnifier button:backdrop, .app-notification button:backdrop, .osd button:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.csd popover.background > contents.touch-selection button:backdrop, .csd popover.background > contents.magnifier button:backdrop, popover.background > contents.touch-selection button:backdrop, popover.background > contents.magnifier button:backdrop, .app-notification button:backdrop, .osd button:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.csd popover > contents.background.touch-selection button.flat, .csd popover > contents.background.magnifier button.flat, popover > contents.background.touch-selection button.flat, popover > contents.background.magnifier button.flat, .app-notification button.flat, .osd button.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; box-shadow: none; text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; }
|
||||
.csd popover.background > contents.touch-selection button.flat, .csd popover.background > contents.magnifier button.flat, popover.background > contents.touch-selection button.flat, popover.background > contents.magnifier button.flat, .app-notification button.flat, .osd button.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; box-shadow: none; text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; }
|
||||
|
||||
.csd popover > contents.background.touch-selection button.flat:hover, .csd popover > contents.background.magnifier button.flat:hover, popover > contents.background.touch-selection button.flat:hover, popover > contents.background.magnifier button.flat:hover, .app-notification button.flat:hover, .osd button.flat:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(83, 83, 83, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.csd popover.background > contents.touch-selection button.flat:hover, .csd popover.background > contents.magnifier button.flat:hover, popover.background > contents.touch-selection button.flat:hover, popover.background > contents.magnifier button.flat:hover, .app-notification button.flat:hover, .osd button.flat:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(83, 83, 83, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.csd popover > contents.background.touch-selection button.flat:disabled, .csd popover > contents.background.magnifier button.flat:disabled, popover > contents.background.touch-selection button.flat:disabled, popover > contents.background.magnifier button.flat:disabled, .app-notification button.flat:disabled, .osd button.flat:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; background-image: none; border-color: transparent; box-shadow: none; }
|
||||
.csd popover.background > contents.touch-selection button.flat:disabled, .csd popover.background > contents.magnifier button.flat:disabled, popover.background > contents.touch-selection button.flat:disabled, popover.background > contents.magnifier button.flat:disabled, .app-notification button.flat:disabled, .osd button.flat:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; background-image: none; border-color: transparent; box-shadow: none; }
|
||||
|
||||
.csd popover > contents.background.touch-selection button.flat:backdrop, .csd popover > contents.background.magnifier button.flat:backdrop, popover > contents.background.touch-selection button.flat:backdrop, popover > contents.background.magnifier button.flat:backdrop, .app-notification button.flat:backdrop, .osd button.flat:backdrop { border-color: transparent; background-color: transparent; background-image: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.csd popover.background > contents.touch-selection button.flat:backdrop, .csd popover.background > contents.magnifier button.flat:backdrop, popover.background > contents.touch-selection button.flat:backdrop, popover.background > contents.magnifier button.flat:backdrop, .app-notification button.flat:backdrop, .osd button.flat:backdrop { border-color: transparent; background-color: transparent; background-image: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.csd popover > contents.background.touch-selection button.flat:active, .csd popover > contents.background.magnifier button.flat:active, popover > contents.background.touch-selection button.flat:active, popover > contents.background.magnifier button.flat:active, .app-notification button.flat:active, .csd popover > contents.background.touch-selection button.flat:checked, .csd popover > contents.background.magnifier button.flat:checked, popover > contents.background.touch-selection button.flat:checked, popover > contents.background.magnifier button.flat:checked, .app-notification button.flat:checked, .osd button.flat:active, .osd button.flat:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.csd popover.background > contents.touch-selection button.flat:active, .csd popover.background > contents.magnifier button.flat:active, popover.background > contents.touch-selection button.flat:active, popover.background > contents.magnifier button.flat:active, .app-notification button.flat:active, .csd popover.background > contents.touch-selection button.flat:checked, .csd popover.background > contents.magnifier button.flat:checked, popover.background > contents.touch-selection button.flat:checked, popover.background > contents.magnifier button.flat:checked, .app-notification button.flat:checked, .osd button.flat:active, .osd button.flat:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
button.suggested-action { color: white; outline-color: rgba(255, 255, 255, 0.3); border-color: #1b6acb; border-bottom-color: #15539e; background-image: linear-gradient(to top, #2379e2 2px, #3584e4); text-shadow: 0 -1px rgba(0, 0, 0, 0.559216); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.559216); box-shadow: inset 0 1px rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.07); }
|
||||
|
||||
@@ -887,19 +887,19 @@ popover.menu > arrow, popover > arrow { background-color: #f6f5f4; border: 1px s
|
||||
|
||||
popover > contents { padding: 8px; background-color: #f6f5f4; border: 1px solid #cdc7c2; margin: 0px; }
|
||||
|
||||
popover > contents.background { background-color: #f6f5f4; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); }
|
||||
popover.background > contents { background-color: #f6f5f4; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); }
|
||||
|
||||
.csd popover > contents.background, popover > contents.background { border: 1px solid #cdc7c2; border-radius: 9px; }
|
||||
.csd popover.background > contents, popover.background > contents { border: 1px solid #cdc7c2; border-radius: 9px; }
|
||||
|
||||
popover > contents.background:backdrop { background-color: #f6f5f4; box-shadow: none; }
|
||||
popover.background > contents:backdrop { background-color: #f6f5f4; box-shadow: none; }
|
||||
|
||||
popover > contents.background > list, popover > contents.background > .view, popover > contents.background > iconview, popover > contents.background > toolbar { border-style: none; background-color: transparent; }
|
||||
popover.background > contents > list, popover.background > contents > .view, popover.background > contents > iconview, popover.background > contents > toolbar { border-style: none; background-color: transparent; }
|
||||
|
||||
.csd popover > contents.background.touch-selection, .csd popover > contents.background.magnifier, popover > contents.background.touch-selection, popover > contents.background.magnifier { border: 1px solid rgba(255, 255, 255, 0.1); }
|
||||
.csd popover.background > contents.touch-selection, .csd popover.background > contents.magnifier, popover.background > contents.touch-selection, popover.background > contents.magnifier { border: 1px solid rgba(255, 255, 255, 0.1); }
|
||||
|
||||
popover > contents.background separator { margin: 3px; }
|
||||
popover.background > contents separator { margin: 3px; }
|
||||
|
||||
popover > contents.background list separator { margin: 0px; }
|
||||
popover.background > contents list separator { margin: 0px; }
|
||||
|
||||
/************* Notebooks * */
|
||||
notebook box > header { padding: 1px; border-color: #cdc7c2; border-width: 1px; background-color: #e1dedb; }
|
||||
@@ -1155,7 +1155,7 @@ row:selected switch slider:checked, row:selected switch slider { border-color: #
|
||||
|
||||
.view.content-view.check:active:not(list), iconview.content-view.check:active:not(list), .content-view .tile check:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: rgba(53, 132, 228, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.view.content-view.check:backdrop:not(list), iconview.content-view.check:backdrop:not(list), .content-view .tile check:backdrop:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: rgba(141, 141, 141, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
|
||||
.view.content-view.check:backdrop:not(list), iconview.content-view.check:backdrop:not(list), .content-view .tile check:backdrop:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: rgba(140, 140, 141, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.view.content-view.check:checked:not(list), iconview.content-view.check:checked:not(list), .content-view .tile check:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: rgba(53, 132, 228, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
|
||||
|
||||
@@ -1163,7 +1163,7 @@ row:selected switch slider:checked, row:selected switch slider { border-color: #
|
||||
|
||||
.view.content-view.check:checked:active:not(list), iconview.content-view.check:checked:active:not(list), .content-view .tile check:checked:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: rgba(53, 132, 228, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
|
||||
|
||||
.view.content-view.check:backdrop:checked:not(list), iconview.content-view.check:backdrop:checked:not(list), .content-view .tile check:backdrop:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: rgba(238, 238, 236, 0.8); background-color: rgba(141, 141, 141, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
|
||||
.view.content-view.check:backdrop:checked:not(list), iconview.content-view.check:backdrop:checked:not(list), .content-view .tile check:backdrop:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: rgba(238, 238, 236, 0.8); background-color: rgba(140, 140, 141, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
|
||||
|
||||
checkbutton.text-button, radiobutton.text-button { padding: 2px 0; outline-offset: 0; }
|
||||
|
||||
@@ -2079,7 +2079,7 @@ popover.menu box.inline-buttons { border-radius: 5px; border-style: none; border
|
||||
|
||||
popover.menu box.circular-buttons { padding-bottom: 5px; }
|
||||
|
||||
popover.menu.background contents { background: white; }
|
||||
popover.menu arrow, popover.menu.background contents { background-color: #ffffff; }
|
||||
|
||||
popover.menu.background separator { margin: 5px 0px; }
|
||||
|
||||
|
||||
+1
-1
@@ -827,7 +827,7 @@ summary = [
|
||||
' Colord support: @0@'.format(get_option('colord')),
|
||||
' Profiler: @0@'.format(get_option('profiler')),
|
||||
' Introspection: @0@'.format(get_option('introspection')),
|
||||
' Documentation: @0@'.format(get_option('documentation')),
|
||||
' Documentation: @0@'.format(get_option('gtk_doc')),
|
||||
' Man pages: @0@'.format(get_option('man-pages')),
|
||||
' Build tests: @0@'.format(get_option('build-tests')),
|
||||
' Install tests: @0@'.format(get_option('install-tests')),
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ option('colord', type: 'combo', choices : ['yes', 'no', 'auto'], value : 'auto',
|
||||
description : 'Build colord support for the CUPS printing backend')
|
||||
|
||||
# Documentation and introspection
|
||||
option('documentation', type: 'boolean', value: 'false',
|
||||
option('gtk_doc', type: 'boolean', value: 'false',
|
||||
description : 'Build API reference and tools documentation')
|
||||
option('man-pages', type: 'boolean', value: 'false',
|
||||
description : 'Build man pages for installed tools')
|
||||
|
||||
@@ -709,13 +709,7 @@ _post_send (GtkCupsRequest *request)
|
||||
httpClearFields (request->http);
|
||||
httpSetField (request->http, HTTP_FIELD_CONTENT_LENGTH, length);
|
||||
httpSetField (request->http, HTTP_FIELD_CONTENT_TYPE, "application/ipp");
|
||||
#ifdef HAVE_HTTPGETAUTHSTRING
|
||||
httpSetField (request->http, HTTP_FIELD_AUTHORIZATION, httpGetAuthString (request->http));
|
||||
#else
|
||||
#ifdef HAVE_HTTP_AUTHSTRING
|
||||
httpSetField (request->http, HTTP_FIELD_AUTHORIZATION, request->http->authstring);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (httpPost (request->http, request->resource))
|
||||
{
|
||||
@@ -1198,13 +1192,7 @@ _get_send (GtkCupsRequest *request)
|
||||
}
|
||||
|
||||
httpClearFields (request->http);
|
||||
#ifdef HAVE_HTTPGETAUTHSTRING
|
||||
httpSetField (request->http, HTTP_FIELD_AUTHORIZATION, httpGetAuthString (request->http));
|
||||
#else
|
||||
#ifdef HAVE_HTTP_AUTHSTRING
|
||||
httpSetField (request->http, HTTP_FIELD_AUTHORIZATION, request->http->authstring);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (httpGet (request->http, request->resource))
|
||||
{
|
||||
|
||||
@@ -17,32 +17,8 @@ print_backends = ['file']
|
||||
# Checks to see if we should compile with CUPS backend for GTK
|
||||
enable_cups = enabled_print_backends.contains('cups')
|
||||
if enable_cups
|
||||
#cups_config = find_program('cups-config', required : true)
|
||||
#if cups_config.found()
|
||||
# FIXME: eek, see configure.ac (we're just not going to support non-standar prefix for now)
|
||||
#endif
|
||||
if cc.has_header('cups/cups.h')
|
||||
# TODO: include_directories from cups-config
|
||||
cups_major_version = cc.compute_int('CUPS_VERSION_MAJOR', prefix : '#include <cups/cups.h>')
|
||||
cups_minor_version = cc.compute_int('CUPS_VERSION_MINOR', prefix : '#include <cups/cups.h>')
|
||||
message('Found CUPS version: @0@.@1@'.format(cups_major_version, cups_minor_version))
|
||||
if cups_major_version >= 2
|
||||
if cc.compiles('#include <cups/http.h> \n http_t http; char *s = http.authstring;')
|
||||
cdata.set('HAVE_HTTP_AUTHSTRING', 1,
|
||||
description :'Define if cups http_t authstring field is accessible')
|
||||
endif
|
||||
libcups = cc.find_library('cups', required : true)
|
||||
if libcups.found() and cc.has_function('httpGetAuthString', dependencies : libcups)
|
||||
cdata.set('HAVE_HTTPGETAUTHSTRING', 1)
|
||||
endif
|
||||
|
||||
print_backends += ['cups']
|
||||
else
|
||||
error('Need CUPS version >= 2.0')
|
||||
endif
|
||||
else
|
||||
error('Cannot find CUPS headers in default prefix.')
|
||||
endif
|
||||
cups_dep = dependency('cups', version : '>=2.0', required: true)
|
||||
print_backends += ['cups']
|
||||
endif
|
||||
|
||||
# Checks to see if we should compile with cloudprint backend for GTK
|
||||
@@ -101,7 +77,7 @@ if print_backends.contains('cups')
|
||||
'gtkcupsutils.c',
|
||||
'gtkcupssecretsutils.c',
|
||||
c_args: printbackends_args,
|
||||
dependencies: [libgtk_dep, libcups, colord_dep],
|
||||
dependencies: [libgtk_dep, cups_dep, colord_dep],
|
||||
install_dir: printbackends_install_dir,
|
||||
install : true)
|
||||
endif
|
||||
|
||||
@@ -1,382 +0,0 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "../../gtk/gtkconstrainttypesprivate.h"
|
||||
#include "../../gtk/gtkconstraintsolverprivate.h"
|
||||
#include "../../gtk/gtkconstraintexpressionprivate.h"
|
||||
|
||||
typedef struct _Node Node;
|
||||
|
||||
static GtkConstraintSolver *solver;
|
||||
static Node *tree;
|
||||
static Node *drag_node;
|
||||
static double drag_start_x;
|
||||
static double drag_start_y;
|
||||
static GtkConstraintVariable *width_var;
|
||||
static GtkConstraintVariable *height_var;
|
||||
|
||||
struct _Node {
|
||||
double x;
|
||||
double y;
|
||||
Node *parent;
|
||||
Node *left;
|
||||
Node *right;
|
||||
|
||||
GtkConstraintVariable *x_var;
|
||||
GtkConstraintVariable *y_var;
|
||||
};
|
||||
|
||||
static Node *
|
||||
make_tree (Node *parent,
|
||||
int depth,
|
||||
int x,
|
||||
int y,
|
||||
int dx,
|
||||
int dy)
|
||||
{
|
||||
Node *node;
|
||||
|
||||
node = g_new0 (Node, 1);
|
||||
node->parent = parent;
|
||||
|
||||
if (depth > 0)
|
||||
{
|
||||
node->left = make_tree (node, depth - 1, x - dx, y + dy, dx / 2, dy);
|
||||
node->right = make_tree (node, depth - 1, x + dx, y + dy, dx / 2, dy);
|
||||
}
|
||||
|
||||
node->x = x;
|
||||
node->y = y;
|
||||
|
||||
node->x_var = gtk_constraint_solver_create_variable (solver, NULL, "x", x);
|
||||
node->y_var = gtk_constraint_solver_create_variable (solver, NULL, "y", y);
|
||||
|
||||
/* weak stay for the current position */
|
||||
gtk_constraint_solver_add_stay_variable (solver, node->x_var, GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
gtk_constraint_solver_add_stay_variable (solver, node->y_var, GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
|
||||
/* require to stay in area */
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
node->x_var,
|
||||
GTK_CONSTRAINT_RELATION_GE,
|
||||
gtk_constraint_expression_new (0.0),
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
node->x_var,
|
||||
GTK_CONSTRAINT_RELATION_LE,
|
||||
gtk_constraint_expression_new (1600.0),
|
||||
//gtk_constraint_expression_new_from_variable (width_var),
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
node->y_var,
|
||||
GTK_CONSTRAINT_RELATION_GE,
|
||||
gtk_constraint_expression_new (0.0),
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
node->y_var,
|
||||
GTK_CONSTRAINT_RELATION_LE,
|
||||
gtk_constraint_expression_new (600.0),
|
||||
//gtk_constraint_expression_new_from_variable (height_var),
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
|
||||
if (node->left)
|
||||
{
|
||||
GtkConstraintExpressionBuilder builder;
|
||||
|
||||
/* left.y = right.y */
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
node->left->y_var,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
gtk_constraint_expression_new_from_variable (node->right->y_var),
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
|
||||
/* left.y >= parent.y + 10 */
|
||||
gtk_constraint_expression_builder_init (&builder, solver);
|
||||
gtk_constraint_expression_builder_term (&builder, node->y_var);
|
||||
gtk_constraint_expression_builder_plus (&builder);
|
||||
gtk_constraint_expression_builder_constant (&builder, 10.0);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
node->left->y_var,
|
||||
GTK_CONSTRAINT_RELATION_GE,
|
||||
gtk_constraint_expression_builder_finish (&builder),
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
|
||||
/* right.y >= parent.y + 10 */
|
||||
gtk_constraint_expression_builder_init (&builder, solver);
|
||||
gtk_constraint_expression_builder_term (&builder, node->y_var);
|
||||
gtk_constraint_expression_builder_plus (&builder);
|
||||
gtk_constraint_expression_builder_constant (&builder, 10.0);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
node->right->y_var,
|
||||
GTK_CONSTRAINT_RELATION_GE,
|
||||
gtk_constraint_expression_builder_finish (&builder),
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
/* parent.x = (left.x + right.x) / 2 */
|
||||
gtk_constraint_expression_builder_init (&builder, solver);
|
||||
gtk_constraint_expression_builder_term (&builder, node->left->x_var);
|
||||
gtk_constraint_expression_builder_plus (&builder);
|
||||
gtk_constraint_expression_builder_term (&builder, node->right->x_var);
|
||||
gtk_constraint_expression_builder_divide_by (&builder);
|
||||
gtk_constraint_expression_builder_constant (&builder, 2.0);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
node->x_var,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
gtk_constraint_expression_builder_finish (&builder),
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static void
|
||||
draw_node (Node *node, cairo_t *cr)
|
||||
{
|
||||
if (node->left)
|
||||
draw_node (node->left, cr);
|
||||
if (node->right)
|
||||
draw_node (node->right, cr);
|
||||
|
||||
if (node->parent)
|
||||
{
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
cairo_move_to (cr, node->parent->x, node->parent->y);
|
||||
cairo_line_to (cr, node->x, node->y);
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
|
||||
if (node == drag_node)
|
||||
cairo_set_source_rgb (cr, 1, 0, 0);
|
||||
else
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
|
||||
cairo_move_to (cr, node->x, node->y);
|
||||
cairo_arc (cr, node->x, node->y, 5, 0, 2*M_PI);
|
||||
cairo_close_path (cr);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_func (GtkDrawingArea *da,
|
||||
cairo_t *cr,
|
||||
int width,
|
||||
int height,
|
||||
gpointer data)
|
||||
{
|
||||
cairo_set_line_width (cr, 1);
|
||||
cairo_set_source_rgb (cr, 1, 1, 1);
|
||||
cairo_paint (cr);
|
||||
|
||||
draw_node (tree, cr);
|
||||
}
|
||||
|
||||
static Node *
|
||||
find_node (Node *node,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
Node *ret;
|
||||
|
||||
double dx = x - node->x;
|
||||
double dy = y - node->y;
|
||||
|
||||
if (dx*dx + dy*dy < 10*10)
|
||||
return node;
|
||||
|
||||
if (node->left)
|
||||
{
|
||||
ret = find_node (node->left, x, y);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (node->right)
|
||||
{
|
||||
ret = find_node (node->right, x, y);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin (GtkGestureDrag *drag,
|
||||
double start_x,
|
||||
double start_y,
|
||||
gpointer data)
|
||||
{
|
||||
drag_node = find_node (tree, start_x, start_y);
|
||||
if (!drag_node)
|
||||
return;
|
||||
|
||||
drag_start_x = start_x;
|
||||
drag_start_y = start_y;
|
||||
gtk_widget_queue_draw (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (drag)));
|
||||
|
||||
gtk_constraint_solver_add_edit_variable (solver,
|
||||
drag_node->x_var,
|
||||
GTK_CONSTRAINT_WEIGHT_STRONG);
|
||||
gtk_constraint_solver_add_edit_variable (solver,
|
||||
drag_node->y_var,
|
||||
GTK_CONSTRAINT_WEIGHT_STRONG);
|
||||
gtk_constraint_solver_begin_edit (solver);
|
||||
}
|
||||
|
||||
static void
|
||||
update_tree (Node *node)
|
||||
{
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
node->x = gtk_constraint_variable_get_value (node->x_var);
|
||||
node->y = gtk_constraint_variable_get_value (node->y_var);
|
||||
|
||||
update_tree (node->left);
|
||||
update_tree (node->right);
|
||||
}
|
||||
|
||||
static void
|
||||
drag_update (GtkGestureDrag *drag,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
gpointer data)
|
||||
{
|
||||
if (!drag_node)
|
||||
return;
|
||||
|
||||
gtk_constraint_solver_suggest_value (solver,
|
||||
drag_node->x_var,
|
||||
drag_start_x + offset_x);
|
||||
gtk_constraint_solver_suggest_value (solver,
|
||||
drag_node->y_var,
|
||||
drag_start_y + offset_y);
|
||||
gtk_constraint_solver_resolve (solver);
|
||||
|
||||
update_tree (tree);
|
||||
|
||||
gtk_widget_queue_draw (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (drag)));
|
||||
}
|
||||
|
||||
static void
|
||||
drag_end (GtkGestureDrag *drag,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
gpointer data)
|
||||
{
|
||||
if (!drag_node)
|
||||
return;
|
||||
|
||||
gtk_constraint_solver_remove_edit_variable (solver, drag_node->x_var);
|
||||
gtk_constraint_solver_remove_edit_variable (solver, drag_node->y_var);
|
||||
gtk_constraint_solver_end_edit (solver);
|
||||
|
||||
drag_node = NULL;
|
||||
|
||||
gtk_widget_queue_draw (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (drag)));
|
||||
}
|
||||
|
||||
static void
|
||||
size_change (GtkWidget *da,
|
||||
int width,
|
||||
int height,
|
||||
int baseline,
|
||||
gpointer data)
|
||||
{
|
||||
gtk_constraint_variable_set_value (width_var, width);
|
||||
gtk_constraint_variable_set_value (height_var, height);
|
||||
gtk_constraint_solver_resolve (solver);
|
||||
}
|
||||
|
||||
static void
|
||||
reset_tree (Node *node,
|
||||
int x,
|
||||
int y,
|
||||
int dx,
|
||||
int dy)
|
||||
{
|
||||
node->x = x;
|
||||
node->y = y;
|
||||
|
||||
gtk_constraint_solver_remove_stay_variable (solver, node->x_var);
|
||||
gtk_constraint_solver_remove_stay_variable (solver, node->y_var);
|
||||
gtk_constraint_variable_set_value (node->x_var, x);
|
||||
gtk_constraint_variable_set_value (node->y_var, y);
|
||||
gtk_constraint_solver_add_stay_variable (solver, node->x_var, GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
gtk_constraint_solver_add_stay_variable (solver, node->y_var, GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
|
||||
if (node->left)
|
||||
reset_tree (node->left, x - dx, y + dy, dx / 2, dy);
|
||||
if (node->right)
|
||||
reset_tree (node->right, x + dx, y + dy, dx / 2, dy);
|
||||
}
|
||||
|
||||
static void
|
||||
reset (GtkButton *button,
|
||||
GtkWidget *da)
|
||||
{
|
||||
int width, height;
|
||||
|
||||
width = gtk_widget_get_allocated_width (da);
|
||||
height = gtk_widget_get_allocated_height (da);
|
||||
|
||||
gtk_constraint_solver_freeze (solver);
|
||||
reset_tree (tree, width / 2, 20, width / 4 - 40, (height - 40) / 7);
|
||||
gtk_constraint_solver_thaw (solver);
|
||||
|
||||
gtk_widget_queue_draw (da);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *header;
|
||||
GtkWidget *button;
|
||||
GtkWidget *da;
|
||||
GtkGesture *drag;
|
||||
int width = 1600;
|
||||
int height = 600;
|
||||
|
||||
gtk_init ();
|
||||
|
||||
da = gtk_drawing_area_new ();
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
button = gtk_button_new_with_label ("Reset");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (reset), da);
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
|
||||
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), width);
|
||||
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), height);
|
||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), draw_func, NULL, NULL);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (window), da);
|
||||
|
||||
drag = gtk_gesture_drag_new ();
|
||||
g_signal_connect (drag, "drag-begin", G_CALLBACK (drag_begin), NULL);
|
||||
g_signal_connect (drag, "drag-update", G_CALLBACK (drag_update), NULL);
|
||||
g_signal_connect (drag, "drag-end", G_CALLBACK (drag_end), NULL);
|
||||
gtk_widget_add_controller (da, GTK_EVENT_CONTROLLER (drag));
|
||||
|
||||
solver = g_object_new (g_type_from_name ("GtkConstraintSolver"), NULL);
|
||||
gtk_constraint_solver_freeze (solver);
|
||||
|
||||
width_var = gtk_constraint_solver_create_variable (solver, NULL, "width", width);
|
||||
height_var = gtk_constraint_solver_create_variable (solver, NULL, "height", height);
|
||||
gtk_constraint_solver_add_stay_variable (solver, width_var, GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
gtk_constraint_solver_add_stay_variable (solver, height_var, GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
|
||||
g_signal_connect (da, "size-allocate", G_CALLBACK (size_change), NULL);
|
||||
|
||||
tree = make_tree (NULL, 7, width / 2, 20, width / 4 - 40, (height - 40) / 7);
|
||||
|
||||
gtk_constraint_solver_thaw (solver);
|
||||
|
||||
gtk_widget_show (window);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+1
-9
@@ -1,10 +1,5 @@
|
||||
gtk_tests = [
|
||||
# testname, optional extra sources
|
||||
['constrainttree', [
|
||||
'../gtk/gtkconstraintsolver.c',
|
||||
'../gtk/gtkconstraintexpression.c',
|
||||
], ['-DGTK_COMPILATION', '-UG_ENABLE_DEBUG', '-DGTK_TEST_EXTERNAL']
|
||||
],
|
||||
['rendernode'],
|
||||
['rendernode-create-tests'],
|
||||
['overlayscroll'],
|
||||
@@ -147,12 +142,9 @@ test_args = ['-DGTK_SRCDIR="@0@"'.format(meson.current_source_dir())]
|
||||
foreach t: gtk_tests
|
||||
test_name = t.get(0)
|
||||
test_srcs = ['@0@.c'.format(test_name), t.get(1, [])]
|
||||
test_extra_cargs = t.get(2, [])
|
||||
test_extra_ldflags = t.get(3, [])
|
||||
executable(test_name, test_srcs,
|
||||
include_directories: [confinc, gdkinc],
|
||||
c_args: test_args + test_extra_cargs,
|
||||
link_args : test_extra_ldflags,
|
||||
c_args: test_args,
|
||||
dependencies: [libgtk_dep, libm])
|
||||
endforeach
|
||||
|
||||
|
||||
@@ -1,326 +0,0 @@
|
||||
/* Copyright (C) 2019 Red Hat, Inc.
|
||||
*
|
||||
* 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 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/>.
|
||||
*/
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define GTK_TYPE_GIZMO (gtk_gizmo_get_type ())
|
||||
#define GTK_GIZMO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_GIZMO, GtkGizmo))
|
||||
#define GTK_GIZMO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_GIZMO, GtkGizmoClass))
|
||||
#define GTK_IS_GIZMO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_GIZMO))
|
||||
#define GTK_IS_GIZMO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_GIZMO))
|
||||
#define GTK_GIZMO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_GIZMO, GtkGizmoClass))
|
||||
|
||||
typedef struct _GtkGizmo GtkGizmo;
|
||||
|
||||
struct _GtkGizmo {
|
||||
GtkWidget parent;
|
||||
|
||||
int min_width;
|
||||
int min_height;
|
||||
int nat_width;
|
||||
int nat_height;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
typedef GtkWidgetClass GtkGizmoClass;
|
||||
|
||||
G_DEFINE_TYPE (GtkGizmo, gtk_gizmo, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
gtk_gizmo_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
GtkGizmo *self = GTK_GIZMO (widget);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
*minimum = self->min_width;
|
||||
*natural = self->nat_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
*minimum = self->min_height;
|
||||
*natural = self->nat_height;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gizmo_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
GtkGizmo *self = GTK_GIZMO (widget);
|
||||
|
||||
self->width = width;
|
||||
self->height = height;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gizmo_class_init (GtkGizmoClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
widget_class->measure = gtk_gizmo_measure;
|
||||
widget_class->size_allocate = gtk_gizmo_size_allocate;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gizmo_init (GtkGizmo *self)
|
||||
{
|
||||
}
|
||||
|
||||
/* Create a layout with three children
|
||||
*
|
||||
* +--------+--------+
|
||||
* | child1 | child2 |
|
||||
* +--------+--------+
|
||||
* | child3 |
|
||||
* +-----------------+
|
||||
*
|
||||
* Verify that
|
||||
* - the layout has the expected min and nat sizes
|
||||
* - the children get their >=nat width when the layout does
|
||||
* - test that allocating the layout larger keeps
|
||||
* child1 and child2 at the same size
|
||||
*/
|
||||
static void
|
||||
test_simple_layout (void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *parent;
|
||||
GtkLayoutManager *layout;
|
||||
GtkConstraintLayout *manager;
|
||||
GtkGizmo *child1;
|
||||
GtkGizmo *child2;
|
||||
GtkGizmo *child3;
|
||||
int minimum, natural;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
parent = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
gtk_widget_set_name (parent, "parent");
|
||||
gtk_container_add (GTK_CONTAINER (window), parent);
|
||||
|
||||
layout = gtk_constraint_layout_new ();
|
||||
gtk_widget_set_layout_manager (parent, layout);
|
||||
manager = GTK_CONSTRAINT_LAYOUT (layout);
|
||||
|
||||
child1 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
child2 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
child3 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
|
||||
gtk_widget_set_name (GTK_WIDGET (child1), "child1");
|
||||
child1->min_width = 10;
|
||||
child1->min_height = 10;
|
||||
child1->nat_width = 50;
|
||||
child1->nat_height = 50;
|
||||
gtk_widget_set_name (GTK_WIDGET (child2), "child2");
|
||||
child2->min_width = 20;
|
||||
child2->min_height = 20;
|
||||
child2->nat_width = 50;
|
||||
child2->nat_height = 50;
|
||||
gtk_widget_set_name (GTK_WIDGET (child3), "child3");
|
||||
child3->min_width = 50;
|
||||
child3->min_height = 10;
|
||||
child3->nat_width = 50;
|
||||
child3->nat_height = 50;
|
||||
|
||||
gtk_widget_set_parent (GTK_WIDGET (child1), parent);
|
||||
gtk_widget_set_parent (GTK_WIDGET (child2), parent);
|
||||
gtk_widget_set_parent (GTK_WIDGET (child3), parent);
|
||||
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (child1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (child1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (child1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (child1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (child2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (child3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (child1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (child2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (child3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
|
||||
#if 0
|
||||
gtk_widget_show (window);
|
||||
|
||||
g_timeout_add (1000, (GSourceFunc)gtk_main_quit, NULL);
|
||||
gtk_main ();
|
||||
#endif
|
||||
|
||||
gtk_layout_manager_measure (layout,
|
||||
parent,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
-1,
|
||||
&minimum,
|
||||
&natural,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
g_assert_cmpint (minimum, ==, 50);
|
||||
g_assert_cmpint (natural, ==, 100);
|
||||
|
||||
gtk_layout_manager_measure (layout,
|
||||
parent,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
-1,
|
||||
&minimum,
|
||||
&natural,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
g_assert_cmpint (minimum, ==, 40);
|
||||
g_assert_cmpint (natural, ==, 100);
|
||||
|
||||
gtk_layout_manager_allocate (layout, parent, 100, 100, 0);
|
||||
|
||||
g_assert_cmpint (child1->width, ==, 50);
|
||||
g_assert_cmpint (child2->width, ==, 50);
|
||||
g_assert_cmpint (child3->width, ==, 100);
|
||||
|
||||
g_assert_cmpint (child1->height, ==, 50);
|
||||
g_assert_cmpint (child2->height, ==, 50);
|
||||
g_assert_cmpint (child3->height, ==, 50);
|
||||
|
||||
gtk_widget_unparent (GTK_WIDGET (child1));
|
||||
gtk_widget_unparent (GTK_WIDGET (child2));
|
||||
gtk_widget_unparent (GTK_WIDGET (child3));
|
||||
|
||||
gtk_widget_destroy (parent);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
gtk_test_init (&argc, &argv);
|
||||
|
||||
g_test_add_func ("/constraint-layout/simple", test_simple_layout);
|
||||
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
@@ -16,7 +16,7 @@ constraint_solver_simple (void)
|
||||
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
x, GTK_CONSTRAINT_RELATION_EQ, e,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
|
||||
double x_value = gtk_constraint_variable_get_value (x);
|
||||
double y_value = gtk_constraint_variable_get_value (y);
|
||||
@@ -39,8 +39,8 @@ constraint_solver_stay (void)
|
||||
GtkConstraintVariable *x = gtk_constraint_solver_create_variable (solver, NULL, "x", 5.0);
|
||||
GtkConstraintVariable *y = gtk_constraint_solver_create_variable (solver, NULL, "y", 10.0);
|
||||
|
||||
gtk_constraint_solver_add_stay_variable (solver, x, GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
gtk_constraint_solver_add_stay_variable (solver, y, GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
gtk_constraint_solver_add_stay_variable (solver, x, GTK_CONSTRAINT_STRENGTH_WEAK);
|
||||
gtk_constraint_solver_add_stay_variable (solver, y, GTK_CONSTRAINT_STRENGTH_WEAK);
|
||||
|
||||
double x_value = gtk_constraint_variable_get_value (x);
|
||||
double y_value = gtk_constraint_variable_get_value (y);
|
||||
@@ -64,7 +64,7 @@ constraint_solver_variable_geq_constant (void)
|
||||
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
x, GTK_CONSTRAINT_RELATION_GE, e,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
|
||||
double x_value = gtk_constraint_variable_get_value (x);
|
||||
|
||||
@@ -85,7 +85,7 @@ constraint_solver_variable_leq_constant (void)
|
||||
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
x, GTK_CONSTRAINT_RELATION_LE, e,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
|
||||
double x_value = gtk_constraint_variable_get_value (x);
|
||||
|
||||
@@ -106,7 +106,7 @@ constraint_solver_variable_eq_constant (void)
|
||||
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
x, GTK_CONSTRAINT_RELATION_EQ, e,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
|
||||
double x_value = gtk_constraint_variable_get_value (x);
|
||||
|
||||
@@ -133,11 +133,11 @@ constraint_solver_eq_with_stay (void)
|
||||
gtk_constraint_expression_builder_term (&builder, width);
|
||||
GtkConstraintExpression *right = gtk_constraint_expression_builder_finish (&builder);
|
||||
|
||||
gtk_constraint_solver_add_stay_variable (solver, width, GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
gtk_constraint_solver_add_stay_variable (solver, right_min, GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
gtk_constraint_solver_add_stay_variable (solver, width, GTK_CONSTRAINT_STRENGTH_WEAK);
|
||||
gtk_constraint_solver_add_stay_variable (solver, right_min, GTK_CONSTRAINT_STRENGTH_WEAK);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
right_min, GTK_CONSTRAINT_RELATION_EQ, right,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
|
||||
double x_value = gtk_constraint_variable_get_value (x);
|
||||
double width_value = gtk_constraint_variable_get_value (width);
|
||||
@@ -165,22 +165,22 @@ constraint_solver_cassowary (void)
|
||||
e = gtk_constraint_expression_new_from_variable (y);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
x, GTK_CONSTRAINT_RELATION_LE, e,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
|
||||
e = gtk_constraint_expression_plus_constant (gtk_constraint_expression_new_from_variable (x), 3.0);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
y, GTK_CONSTRAINT_RELATION_EQ, e,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
|
||||
e = gtk_constraint_expression_new (10.0);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
x, GTK_CONSTRAINT_RELATION_EQ, e,
|
||||
GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
GTK_CONSTRAINT_STRENGTH_WEAK);
|
||||
|
||||
e = gtk_constraint_expression_new (10.0);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
y, GTK_CONSTRAINT_RELATION_EQ, e,
|
||||
GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
GTK_CONSTRAINT_STRENGTH_WEAK);
|
||||
|
||||
double x_val = gtk_constraint_variable_get_value (x);
|
||||
double y_val = gtk_constraint_variable_get_value (y);
|
||||
@@ -205,11 +205,11 @@ constraint_solver_edit_var_required (void)
|
||||
GtkConstraintSolver *solver = gtk_constraint_solver_new ();
|
||||
|
||||
GtkConstraintVariable *a = gtk_constraint_solver_create_variable (solver, NULL, "a", 0.0);
|
||||
gtk_constraint_solver_add_stay_variable (solver, a, GTK_CONSTRAINT_WEIGHT_STRONG);
|
||||
gtk_constraint_solver_add_stay_variable (solver, a, GTK_CONSTRAINT_STRENGTH_STRONG);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (a), 0.0, 0.001);
|
||||
|
||||
gtk_constraint_solver_add_edit_variable (solver, a, GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
gtk_constraint_solver_add_edit_variable (solver, a, GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_solver_begin_edit (solver);
|
||||
gtk_constraint_solver_suggest_value (solver, a, 2.0);
|
||||
gtk_constraint_solver_resolve (solver);
|
||||
@@ -236,19 +236,19 @@ constraint_solver_edit_var_suggest (void)
|
||||
GtkConstraintVariable *a = gtk_constraint_solver_create_variable (solver, NULL, "a", 0.0);
|
||||
GtkConstraintVariable *b = gtk_constraint_solver_create_variable (solver, NULL, "b", 0.0);
|
||||
|
||||
gtk_constraint_solver_add_stay_variable (solver, a, GTK_CONSTRAINT_WEIGHT_STRONG);
|
||||
gtk_constraint_solver_add_stay_variable (solver, a, GTK_CONSTRAINT_STRENGTH_STRONG);
|
||||
|
||||
GtkConstraintExpression *e = gtk_constraint_expression_new_from_variable (b);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
a, GTK_CONSTRAINT_RELATION_EQ, e,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
|
||||
gtk_constraint_solver_resolve (solver);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (a), 0.0, 0.001);
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (b), 0.0, 0.001);
|
||||
|
||||
gtk_constraint_solver_add_edit_variable (solver, a, GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
gtk_constraint_solver_add_edit_variable (solver, a, GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_solver_begin_edit (solver);
|
||||
|
||||
gtk_constraint_solver_suggest_value (solver, a, 2.0);
|
||||
@@ -302,7 +302,7 @@ constraint_solver_paper (void)
|
||||
expr = gtk_constraint_expression_builder_finish (&builder);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
middle, GTK_CONSTRAINT_RELATION_EQ, expr,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
|
||||
gtk_constraint_expression_builder_init (&builder, solver);
|
||||
gtk_constraint_expression_builder_term (&builder, left);
|
||||
@@ -311,17 +311,17 @@ constraint_solver_paper (void)
|
||||
expr = gtk_constraint_expression_builder_finish (&builder);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
right, GTK_CONSTRAINT_RELATION_EQ, expr,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
|
||||
expr = gtk_constraint_expression_new (100.0);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
right, GTK_CONSTRAINT_RELATION_LE, expr,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
|
||||
expr = gtk_constraint_expression_new (0.0);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
left, GTK_CONSTRAINT_RELATION_GE, expr,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
|
||||
g_test_message ("Check constraints hold");
|
||||
|
||||
@@ -335,7 +335,7 @@ constraint_solver_paper (void)
|
||||
g_assert_cmpfloat (gtk_constraint_variable_get_value (left), >=, 0.0);
|
||||
|
||||
gtk_constraint_variable_set_value (middle, 45.0);
|
||||
gtk_constraint_solver_add_stay_variable (solver, middle, GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
gtk_constraint_solver_add_stay_variable (solver, middle, GTK_CONSTRAINT_STRENGTH_WEAK);
|
||||
|
||||
g_test_message ("Check constraints hold after setting middle");
|
||||
|
||||
|
||||
@@ -300,6 +300,44 @@ test_submodel_add (void)
|
||||
g_object_unref (flat);
|
||||
}
|
||||
|
||||
static void
|
||||
test_submodel_add2 (void)
|
||||
{
|
||||
GtkFlattenListModel *flat;
|
||||
GListStore *model, *store[2];
|
||||
|
||||
model = g_list_store_new (G_TYPE_LIST_MODEL);
|
||||
flat = new_model (model);
|
||||
assert_model (flat, "");
|
||||
assert_changes (flat, "");
|
||||
|
||||
store[0] = add_store (model, 1, 0, 0);
|
||||
store[1] = add_store (model, 1, 0, 0);
|
||||
store[2] = add_store (model, 1, 0, 0);
|
||||
|
||||
assert_model (flat, "");
|
||||
assert_changes (flat, "");
|
||||
|
||||
add (store[0], 1);
|
||||
assert_model (flat, "1");
|
||||
assert_changes (flat, "+0");
|
||||
|
||||
add (store[1], 3);
|
||||
assert_model (flat, "1 3");
|
||||
assert_changes (flat, "+1");
|
||||
|
||||
add (store[0], 2);
|
||||
assert_model (flat, "1 2 3");
|
||||
assert_changes (flat, "+1");
|
||||
|
||||
add (store[1], 4);
|
||||
assert_model (flat, "1 2 3 4");
|
||||
assert_changes (flat, "+3");
|
||||
|
||||
g_object_unref (model);
|
||||
g_object_unref (flat);
|
||||
}
|
||||
|
||||
static void
|
||||
test_model_remove (void)
|
||||
{
|
||||
@@ -365,6 +403,7 @@ main (int argc, char *argv[])
|
||||
g_test_add_func ("/flattenlistmodel/model/add", test_model_add);
|
||||
#if GLIB_CHECK_VERSION (2, 58, 0) /* g_list_store_splice() is broken before 2.58 */
|
||||
g_test_add_func ("/flattenlistmodel/submodel/add", test_submodel_add);
|
||||
g_test_add_func ("/flattenlistmodel/submodel/add2", test_submodel_add2);
|
||||
g_test_add_func ("/flattenlistmodel/model/remove", test_model_remove);
|
||||
g_test_add_func ("/flattenlistmodel/submodel/remove", test_submodel_remove);
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,681 @@
|
||||
/* Copyright (C) 2019 Red Hat, Inc.
|
||||
*
|
||||
* 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 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/>.
|
||||
*/
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define GTK_TYPE_GIZMO (gtk_gizmo_get_type ())
|
||||
#define GTK_GIZMO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_GIZMO, GtkGizmo))
|
||||
#define GTK_GIZMO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_GIZMO, GtkGizmoClass))
|
||||
#define GTK_IS_GIZMO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_GIZMO))
|
||||
#define GTK_IS_GIZMO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_GIZMO))
|
||||
#define GTK_GIZMO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_GIZMO, GtkGizmoClass))
|
||||
|
||||
typedef struct _GtkGizmo GtkGizmo;
|
||||
|
||||
struct _GtkGizmo {
|
||||
GtkWidget parent;
|
||||
|
||||
const char *name;
|
||||
int min_width;
|
||||
int min_height;
|
||||
int nat_width;
|
||||
int nat_height;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
typedef GtkWidgetClass GtkGizmoClass;
|
||||
|
||||
G_DEFINE_TYPE (GtkGizmo, gtk_gizmo, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
gtk_gizmo_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
GtkGizmo *self = GTK_GIZMO (widget);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
*minimum = self->min_width;
|
||||
*natural = self->nat_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
*minimum = self->min_height;
|
||||
*natural = self->nat_height;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gizmo_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
GtkGizmo *self = GTK_GIZMO (widget);
|
||||
|
||||
self->width = width;
|
||||
self->height = height;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gizmo_class_init (GtkGizmoClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
widget_class->measure = gtk_gizmo_measure;
|
||||
widget_class->size_allocate = gtk_gizmo_size_allocate;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gizmo_init (GtkGizmo *self)
|
||||
{
|
||||
}
|
||||
|
||||
/* Create a grid with three children in row
|
||||
*
|
||||
* +--------+--------+--------+
|
||||
* | child1 | child2 | child3 |
|
||||
* +--------+--------+--------+
|
||||
*
|
||||
* Verify that
|
||||
* - the layout has the expected min and nat sizes
|
||||
* - the children get their nat width when the layout does
|
||||
* - they all get the same height
|
||||
*/
|
||||
static void
|
||||
test_simple_row (void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *parent;
|
||||
GtkLayoutManager *layout;
|
||||
GtkGizmo *child1;
|
||||
GtkGizmo *child2;
|
||||
GtkGizmo *child3;
|
||||
GtkLayoutChild *lc;
|
||||
int minimum, natural;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
parent = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), parent);
|
||||
|
||||
layout = gtk_grid_layout_new ();
|
||||
gtk_widget_set_layout_manager (parent, layout);
|
||||
|
||||
child1 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
child2 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
child3 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
|
||||
child1->name = "child1";
|
||||
child1->min_width = 10;
|
||||
child1->min_height = 10;
|
||||
child1->nat_width = 20;
|
||||
child1->nat_height = 20;
|
||||
child2->name = "child2";
|
||||
child2->min_width = 20;
|
||||
child2->min_height = 20;
|
||||
child2->nat_width = 30;
|
||||
child2->nat_height = 30;
|
||||
child3->name = "child3";
|
||||
child3->min_width = 30;
|
||||
child3->min_height = 30;
|
||||
child3->nat_width = 40;
|
||||
child3->nat_height = 40;
|
||||
|
||||
gtk_widget_set_parent (GTK_WIDGET (child1), parent);
|
||||
gtk_widget_set_parent (GTK_WIDGET (child2), parent);
|
||||
gtk_widget_set_parent (GTK_WIDGET (child3), parent);
|
||||
|
||||
lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child1));
|
||||
gtk_grid_layout_child_set_left_attach (GTK_GRID_LAYOUT_CHILD (lc), 0);
|
||||
lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child2));
|
||||
gtk_grid_layout_child_set_left_attach (GTK_GRID_LAYOUT_CHILD (lc), 1);
|
||||
lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child3));
|
||||
gtk_grid_layout_child_set_left_attach (GTK_GRID_LAYOUT_CHILD (lc), 2);
|
||||
|
||||
#if 0
|
||||
gtk_widget_show (window);
|
||||
|
||||
g_timeout_add (1000, (GSourceFunc)gtk_main_quit, NULL);
|
||||
gtk_main ();
|
||||
#endif
|
||||
|
||||
gtk_layout_manager_measure (layout,
|
||||
parent,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
-1,
|
||||
&minimum,
|
||||
&natural,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
g_assert_cmpint (minimum, ==, 10 + 20 + 30);
|
||||
g_assert_cmpint (natural, ==, 20 + 30 + 40);
|
||||
|
||||
gtk_layout_manager_measure (layout,
|
||||
parent,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
-1,
|
||||
&minimum,
|
||||
&natural,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
g_assert_cmpint (minimum, ==, 30);
|
||||
g_assert_cmpint (natural, ==, 40);
|
||||
|
||||
gtk_layout_manager_allocate (layout, parent, 90, 40, 0);
|
||||
|
||||
g_assert_cmpint (child1->width, ==, 20);
|
||||
g_assert_cmpint (child2->width, ==, 30);
|
||||
g_assert_cmpint (child3->width, ==, 40);
|
||||
|
||||
g_assert_cmpint (child1->height, ==, 40);
|
||||
g_assert_cmpint (child2->height, ==, 40);
|
||||
g_assert_cmpint (child3->height, ==, 40);
|
||||
|
||||
gtk_widget_unparent (GTK_WIDGET (child1));
|
||||
gtk_widget_unparent (GTK_WIDGET (child2));
|
||||
gtk_widget_unparent (GTK_WIDGET (child3));
|
||||
|
||||
gtk_widget_destroy (parent);
|
||||
}
|
||||
|
||||
/* same as the previous test, with a column
|
||||
*/
|
||||
static void
|
||||
test_simple_column (void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *parent;
|
||||
GtkLayoutManager *layout;
|
||||
GtkGizmo *child1;
|
||||
GtkGizmo *child2;
|
||||
GtkGizmo *child3;
|
||||
GtkLayoutChild *lc;
|
||||
int minimum, natural;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
parent = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), parent);
|
||||
|
||||
layout = gtk_grid_layout_new ();
|
||||
gtk_widget_set_layout_manager (parent, layout);
|
||||
|
||||
child1 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
child2 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
child3 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
|
||||
child1->name = "child1";
|
||||
child1->min_width = 10;
|
||||
child1->min_height = 10;
|
||||
child1->nat_width = 20;
|
||||
child1->nat_height = 20;
|
||||
child2->name = "child2";
|
||||
child2->min_width = 20;
|
||||
child2->min_height = 20;
|
||||
child2->nat_width = 30;
|
||||
child2->nat_height = 30;
|
||||
child3->name = "child3";
|
||||
child3->min_width = 30;
|
||||
child3->min_height = 30;
|
||||
child3->nat_width = 40;
|
||||
child3->nat_height = 40;
|
||||
|
||||
gtk_widget_set_parent (GTK_WIDGET (child1), parent);
|
||||
gtk_widget_set_parent (GTK_WIDGET (child2), parent);
|
||||
gtk_widget_set_parent (GTK_WIDGET (child3), parent);
|
||||
|
||||
lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child1));
|
||||
gtk_grid_layout_child_set_top_attach (GTK_GRID_LAYOUT_CHILD (lc), 0);
|
||||
lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child2));
|
||||
gtk_grid_layout_child_set_top_attach (GTK_GRID_LAYOUT_CHILD (lc), 1);
|
||||
lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child3));
|
||||
gtk_grid_layout_child_set_top_attach (GTK_GRID_LAYOUT_CHILD (lc), 2);
|
||||
|
||||
#if 0
|
||||
gtk_widget_show (window);
|
||||
|
||||
g_timeout_add (1000, (GSourceFunc)gtk_main_quit, NULL);
|
||||
gtk_main ();
|
||||
#endif
|
||||
|
||||
gtk_layout_manager_measure (layout,
|
||||
parent,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
-1,
|
||||
&minimum,
|
||||
&natural,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
g_assert_cmpint (minimum, ==, 30);
|
||||
g_assert_cmpint (natural, ==, 40);
|
||||
|
||||
gtk_layout_manager_measure (layout,
|
||||
parent,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
-1,
|
||||
&minimum,
|
||||
&natural,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
g_assert_cmpint (minimum, ==, 10 + 20 + 30);
|
||||
g_assert_cmpint (natural, ==, 20 + 30 + 40);
|
||||
|
||||
gtk_layout_manager_allocate (layout, parent, 40, 90, 0);
|
||||
|
||||
g_assert_cmpint (child1->width, ==, 40);
|
||||
g_assert_cmpint (child2->width, ==, 40);
|
||||
g_assert_cmpint (child3->width, ==, 40);
|
||||
|
||||
g_assert_cmpint (child1->height, ==, 20);
|
||||
g_assert_cmpint (child2->height, ==, 30);
|
||||
g_assert_cmpint (child3->height, ==, 40);
|
||||
|
||||
gtk_widget_unparent (GTK_WIDGET (child1));
|
||||
gtk_widget_unparent (GTK_WIDGET (child2));
|
||||
gtk_widget_unparent (GTK_WIDGET (child3));
|
||||
|
||||
gtk_widget_destroy (parent);
|
||||
}
|
||||
|
||||
/* Create a grid with spanning children
|
||||
*
|
||||
* +--------+-----------------+
|
||||
* | child1 | child2 |
|
||||
* +--------+--------+--------+
|
||||
* | child3 | child4 |
|
||||
* +-----------------+--------+
|
||||
*
|
||||
* Verify that
|
||||
* - the layout has the expected min and nat sizes
|
||||
* - the children get their nat width when the layout does
|
||||
*/
|
||||
static void
|
||||
test_spans (void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *parent;
|
||||
GtkLayoutManager *layout;
|
||||
GtkGizmo *child1;
|
||||
GtkGizmo *child2;
|
||||
GtkGizmo *child3;
|
||||
GtkGizmo *child4;
|
||||
GtkLayoutChild *lc;
|
||||
int minimum, natural;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
parent = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), parent);
|
||||
|
||||
layout = gtk_grid_layout_new ();
|
||||
gtk_widget_set_layout_manager (parent, layout);
|
||||
|
||||
child1 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
child2 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
child3 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
child4 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
|
||||
child1->name = "child1";
|
||||
child1->min_width = 10;
|
||||
child1->min_height = 10;
|
||||
child1->nat_width = 20;
|
||||
child1->nat_height = 20;
|
||||
child2->name = "child2";
|
||||
child2->min_width = 20;
|
||||
child2->min_height = 20;
|
||||
child2->nat_width = 30;
|
||||
child2->nat_height = 30;
|
||||
child3->name = "child3";
|
||||
child3->min_width = 30;
|
||||
child3->min_height = 30;
|
||||
child3->nat_width = 40;
|
||||
child3->nat_height = 40;
|
||||
child4->name = "child4";
|
||||
child4->min_width = 30;
|
||||
child4->min_height = 30;
|
||||
child4->nat_width = 40;
|
||||
child4->nat_height = 40;
|
||||
|
||||
gtk_widget_set_parent (GTK_WIDGET (child1), parent);
|
||||
gtk_widget_set_parent (GTK_WIDGET (child2), parent);
|
||||
gtk_widget_set_parent (GTK_WIDGET (child3), parent);
|
||||
gtk_widget_set_parent (GTK_WIDGET (child4), parent);
|
||||
|
||||
lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child1));
|
||||
gtk_grid_layout_child_set_top_attach (GTK_GRID_LAYOUT_CHILD (lc), 0);
|
||||
gtk_grid_layout_child_set_left_attach (GTK_GRID_LAYOUT_CHILD (lc), 0);
|
||||
|
||||
lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child2));
|
||||
gtk_grid_layout_child_set_top_attach (GTK_GRID_LAYOUT_CHILD (lc), 0);
|
||||
gtk_grid_layout_child_set_left_attach (GTK_GRID_LAYOUT_CHILD (lc), 1);
|
||||
gtk_grid_layout_child_set_column_span (GTK_GRID_LAYOUT_CHILD (lc), 2);
|
||||
|
||||
lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child3));
|
||||
gtk_grid_layout_child_set_top_attach (GTK_GRID_LAYOUT_CHILD (lc), 1);
|
||||
gtk_grid_layout_child_set_left_attach (GTK_GRID_LAYOUT_CHILD (lc), 0);
|
||||
gtk_grid_layout_child_set_column_span (GTK_GRID_LAYOUT_CHILD (lc), 2);
|
||||
|
||||
lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child4));
|
||||
gtk_grid_layout_child_set_top_attach (GTK_GRID_LAYOUT_CHILD (lc), 1);
|
||||
gtk_grid_layout_child_set_left_attach (GTK_GRID_LAYOUT_CHILD (lc), 2);
|
||||
|
||||
#if 0
|
||||
gtk_widget_show (window);
|
||||
|
||||
g_timeout_add (1000, (GSourceFunc)gtk_main_quit, NULL);
|
||||
gtk_main ();
|
||||
#endif
|
||||
|
||||
gtk_layout_manager_measure (layout,
|
||||
parent,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
-1,
|
||||
&minimum,
|
||||
&natural,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
g_assert_cmpint (minimum, ==, 60);
|
||||
g_assert_cmpint (natural, ==, 80);
|
||||
|
||||
gtk_layout_manager_measure (layout,
|
||||
parent,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
-1,
|
||||
&minimum,
|
||||
&natural,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
g_assert_cmpint (minimum, ==, 50);
|
||||
g_assert_cmpint (natural, ==, 70);
|
||||
|
||||
gtk_layout_manager_allocate (layout, parent, 80, 70, 0);
|
||||
|
||||
g_assert_cmpint (child1->width, ==, 30);
|
||||
g_assert_cmpint (child2->width, ==, 50);
|
||||
g_assert_cmpint (child3->width, ==, 40);
|
||||
g_assert_cmpint (child4->width, ==, 40);
|
||||
|
||||
g_assert_cmpint (child1->height, ==, 30);
|
||||
g_assert_cmpint (child2->height, ==, 30);
|
||||
g_assert_cmpint (child3->height, ==, 40);
|
||||
g_assert_cmpint (child4->height, ==, 40);
|
||||
|
||||
gtk_widget_unparent (GTK_WIDGET (child1));
|
||||
gtk_widget_unparent (GTK_WIDGET (child2));
|
||||
gtk_widget_unparent (GTK_WIDGET (child3));
|
||||
gtk_widget_unparent (GTK_WIDGET (child4));
|
||||
|
||||
gtk_widget_destroy (parent);
|
||||
}
|
||||
|
||||
/* Create a 2x2 homogeneous grid and verify
|
||||
* all children get the same size.
|
||||
*/
|
||||
static void
|
||||
test_homogeneous (void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *parent;
|
||||
GtkLayoutManager *layout;
|
||||
GtkGizmo *child1;
|
||||
GtkGizmo *child2;
|
||||
GtkGizmo *child3;
|
||||
GtkGizmo *child4;
|
||||
GtkLayoutChild *lc;
|
||||
int minimum, natural;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
parent = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), parent);
|
||||
|
||||
layout = gtk_grid_layout_new ();
|
||||
gtk_grid_layout_set_row_homogeneous (GTK_GRID_LAYOUT (layout), TRUE);
|
||||
gtk_grid_layout_set_column_homogeneous (GTK_GRID_LAYOUT (layout), TRUE);
|
||||
gtk_widget_set_layout_manager (parent, layout);
|
||||
|
||||
child1 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
child2 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
child3 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
child4 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
|
||||
child1->name = "child1";
|
||||
child1->min_width = 10;
|
||||
child1->min_height = 10;
|
||||
child1->nat_width = 20;
|
||||
child1->nat_height = 20;
|
||||
child2->name = "child2";
|
||||
child2->min_width = 20;
|
||||
child2->min_height = 20;
|
||||
child2->nat_width = 30;
|
||||
child2->nat_height = 30;
|
||||
child3->name = "child3";
|
||||
child3->min_width = 30;
|
||||
child3->min_height = 30;
|
||||
child3->nat_width = 40;
|
||||
child3->nat_height = 40;
|
||||
child4->name = "child4";
|
||||
child4->min_width = 30;
|
||||
child4->min_height = 30;
|
||||
child4->nat_width = 40;
|
||||
child4->nat_height = 40;
|
||||
|
||||
gtk_widget_set_parent (GTK_WIDGET (child1), parent);
|
||||
gtk_widget_set_parent (GTK_WIDGET (child2), parent);
|
||||
gtk_widget_set_parent (GTK_WIDGET (child3), parent);
|
||||
gtk_widget_set_parent (GTK_WIDGET (child4), parent);
|
||||
|
||||
lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child1));
|
||||
gtk_grid_layout_child_set_top_attach (GTK_GRID_LAYOUT_CHILD (lc), 0);
|
||||
gtk_grid_layout_child_set_left_attach (GTK_GRID_LAYOUT_CHILD (lc), 0);
|
||||
|
||||
lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child2));
|
||||
gtk_grid_layout_child_set_top_attach (GTK_GRID_LAYOUT_CHILD (lc), 0);
|
||||
gtk_grid_layout_child_set_left_attach (GTK_GRID_LAYOUT_CHILD (lc), 1);
|
||||
|
||||
lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child3));
|
||||
gtk_grid_layout_child_set_top_attach (GTK_GRID_LAYOUT_CHILD (lc), 1);
|
||||
gtk_grid_layout_child_set_left_attach (GTK_GRID_LAYOUT_CHILD (lc), 0);
|
||||
|
||||
lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child4));
|
||||
gtk_grid_layout_child_set_top_attach (GTK_GRID_LAYOUT_CHILD (lc), 1);
|
||||
gtk_grid_layout_child_set_left_attach (GTK_GRID_LAYOUT_CHILD (lc), 1);
|
||||
|
||||
#if 0
|
||||
gtk_widget_show (window);
|
||||
|
||||
g_timeout_add (1000, (GSourceFunc)gtk_main_quit, NULL);
|
||||
gtk_main ();
|
||||
#endif
|
||||
|
||||
gtk_layout_manager_measure (layout,
|
||||
parent,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
-1,
|
||||
&minimum,
|
||||
&natural,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
g_assert_cmpint (minimum, ==, 60);
|
||||
g_assert_cmpint (natural, ==, 80);
|
||||
|
||||
gtk_layout_manager_measure (layout,
|
||||
parent,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
-1,
|
||||
&minimum,
|
||||
&natural,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
g_assert_cmpint (minimum, ==, 60);
|
||||
g_assert_cmpint (natural, ==, 80);
|
||||
|
||||
gtk_layout_manager_allocate (layout, parent, 80, 80, 0);
|
||||
|
||||
g_assert_cmpint (child1->width, ==, 40);
|
||||
g_assert_cmpint (child2->width, ==, 40);
|
||||
g_assert_cmpint (child3->width, ==, 40);
|
||||
g_assert_cmpint (child4->width, ==, 40);
|
||||
|
||||
g_assert_cmpint (child1->height, ==, 40);
|
||||
g_assert_cmpint (child2->height, ==, 40);
|
||||
g_assert_cmpint (child3->height, ==, 40);
|
||||
g_assert_cmpint (child4->height, ==, 40);
|
||||
|
||||
gtk_widget_unparent (GTK_WIDGET (child1));
|
||||
gtk_widget_unparent (GTK_WIDGET (child2));
|
||||
gtk_widget_unparent (GTK_WIDGET (child3));
|
||||
gtk_widget_unparent (GTK_WIDGET (child4));
|
||||
|
||||
gtk_widget_destroy (parent);
|
||||
}
|
||||
|
||||
/* Create a layout with three children
|
||||
*
|
||||
* +--------+--------+
|
||||
* | child1 | child2 |
|
||||
* +--------+--------+
|
||||
* | child3 |
|
||||
* +-----------------+
|
||||
*
|
||||
* This is a layout that we also reproduce with
|
||||
* constraints, for comparison. Among the contraints:
|
||||
* - child1.width == child2.width
|
||||
* - child1.height == child2.height == child3.height
|
||||
*/
|
||||
static void
|
||||
test_simple_layout (void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *parent;
|
||||
GtkLayoutManager *layout;
|
||||
GtkLayoutChild *lc;
|
||||
GtkGizmo *child1;
|
||||
GtkGizmo *child2;
|
||||
GtkGizmo *child3;
|
||||
int minimum, natural;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
parent = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), parent);
|
||||
|
||||
layout = gtk_grid_layout_new ();
|
||||
gtk_grid_layout_set_row_homogeneous (GTK_GRID_LAYOUT (layout), TRUE);
|
||||
gtk_grid_layout_set_column_homogeneous (GTK_GRID_LAYOUT (layout), TRUE);
|
||||
gtk_widget_set_layout_manager (parent, layout);
|
||||
|
||||
child1 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
child2 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
child3 = g_object_new (GTK_TYPE_GIZMO, NULL);
|
||||
|
||||
child1->name = "child1";
|
||||
child1->min_width = 10;
|
||||
child1->min_height = 10;
|
||||
child1->nat_width = 50;
|
||||
child1->nat_height = 50;
|
||||
child2->name = "child2";
|
||||
child2->min_width = 20;
|
||||
child2->min_height = 20;
|
||||
child2->nat_width = 50;
|
||||
child2->nat_height = 50;
|
||||
child3->name = "child3";
|
||||
child3->min_width = 50;
|
||||
child3->min_height = 10;
|
||||
child3->nat_width = 50;
|
||||
child3->nat_height = 50;
|
||||
|
||||
gtk_widget_set_parent (GTK_WIDGET (child1), parent);
|
||||
gtk_widget_set_parent (GTK_WIDGET (child2), parent);
|
||||
gtk_widget_set_parent (GTK_WIDGET (child3), parent);
|
||||
|
||||
lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child1));
|
||||
gtk_grid_layout_child_set_top_attach (GTK_GRID_LAYOUT_CHILD (lc), 0);
|
||||
gtk_grid_layout_child_set_left_attach (GTK_GRID_LAYOUT_CHILD (lc), 0);
|
||||
|
||||
lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child2));
|
||||
gtk_grid_layout_child_set_top_attach (GTK_GRID_LAYOUT_CHILD (lc), 0);
|
||||
gtk_grid_layout_child_set_left_attach (GTK_GRID_LAYOUT_CHILD (lc), 1);
|
||||
|
||||
lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child3));
|
||||
gtk_grid_layout_child_set_top_attach (GTK_GRID_LAYOUT_CHILD (lc), 1);
|
||||
gtk_grid_layout_child_set_left_attach (GTK_GRID_LAYOUT_CHILD (lc), 0);
|
||||
gtk_grid_layout_child_set_column_span (GTK_GRID_LAYOUT_CHILD (lc), 2);
|
||||
|
||||
gtk_layout_manager_measure (layout,
|
||||
parent,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
-1,
|
||||
&minimum,
|
||||
&natural,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
g_assert_cmpint (minimum, ==, 50);
|
||||
g_assert_cmpint (natural, ==, 100);
|
||||
|
||||
gtk_layout_manager_measure (layout,
|
||||
parent,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
-1,
|
||||
&minimum,
|
||||
&natural,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
g_assert_cmpint (minimum, ==, 40);
|
||||
g_assert_cmpint (natural, ==, 100);
|
||||
|
||||
gtk_layout_manager_allocate (layout, parent, 100, 100, 0);
|
||||
|
||||
g_assert_cmpint (child1->width, ==, 50);
|
||||
g_assert_cmpint (child2->width, ==, 50);
|
||||
g_assert_cmpint (child3->width, ==, 100);
|
||||
|
||||
g_assert_cmpint (child1->height, ==, 50);
|
||||
g_assert_cmpint (child2->height, ==, 50);
|
||||
g_assert_cmpint (child3->height, ==, 50);
|
||||
|
||||
gtk_widget_unparent (GTK_WIDGET (child1));
|
||||
gtk_widget_unparent (GTK_WIDGET (child2));
|
||||
gtk_widget_unparent (GTK_WIDGET (child3));
|
||||
|
||||
gtk_widget_destroy (parent);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
gtk_test_init (&argc, &argv);
|
||||
|
||||
g_test_add_func ("/grid-layout/row", test_simple_row);
|
||||
g_test_add_func ("/grid-layout/column", test_simple_column);
|
||||
g_test_add_func ("/grid-layout/span", test_spans);
|
||||
g_test_add_func ("/grid-layout/homogeneous", test_homogeneous);
|
||||
g_test_add_func ("/grid-layout/simple", test_simple_layout);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
@@ -17,7 +17,6 @@ tests = [
|
||||
['builderparser'],
|
||||
['cellarea'],
|
||||
['check-icon-names'],
|
||||
['constraint-layout'],
|
||||
['constraint-solver', [
|
||||
'../../gtk/gtkconstraintsolver.c',
|
||||
'../../gtk/gtkconstraintexpression.c',
|
||||
@@ -34,6 +33,7 @@ tests = [
|
||||
['focus'],
|
||||
['gestures'],
|
||||
['grid'],
|
||||
['grid-layout'],
|
||||
['gtkmenu'],
|
||||
['icontheme'],
|
||||
['keyhash', ['../../gtk/gtkkeyhash.c', gtkresources, '../../gtk/gtkprivate.c'], gtk_cargs],
|
||||
|
||||
Reference in New Issue
Block a user