Compare commits

..

25 Commits

Author SHA1 Message Date
Matthias Clasen 463dffe48d constraint solver: Fix repeat suggestions
We were not storing the previous value, causing
the first two suggestions to work, but not later
ones.

Fixes the test added in the previous commit.
2019-06-28 16:59:39 +00:00
Matthias Clasen d42c26b117 Amend a constraint solver test
Make the 'repeat edit' test make more than to
suggestions in a single edit phase. It turns out
that this does not work, whereas just doing
two in a row does.
2019-06-28 16:36:46 +00:00
Matthias Clasen 12d45c01b0 Add an interactive constraints demo 2019-06-28 13:11:22 +01:00
Matthias Clasen fc3f4aafe5 Make the constraints demo more interesting
Add a max size to the buttons, to force the
space to open up.
2019-06-28 13:11:22 +01:00
Matthias Clasen ffd8b19a87 Add GtkConstraintGuide
This is meant to be a flexible space.
2019-06-28 13:11:22 +01:00
Emmanuele Bassi 20c4a4bb21 Use generic pointers for constraint targets
Since GtkWidget implements GtkConstraintTarget, we can omit the explicit
cast, and validate the type at run time.
2019-06-28 13:11:22 +01:00
Matthias Clasen f8647b02eb Redefine constraints with GtkConstraintTarget
This is in preparation for allowing non-widgets
to act as constraint targets.
2019-06-28 13:11:22 +01:00
Matthias Clasen 4b11e73be6 widget: Implement GtkConstraintTarget 2019-06-28 13:11:22 +01:00
Matthias Clasen 4de3e99fbe Add GtkConstraintTarget
This is an marker interface that we will
use to accept other things that widgets
in constraints.
2019-06-28 13:11:22 +01:00
Emmanuele Bassi c81e04755d Notify a layout change when adding and removing constraints
Changing the set of constraints should cause a relayout.
2019-06-28 13:11:22 +01:00
Emmanuele Bassi e4466dd4fe Fix the opposite size measurement in GtkConstraintLayout
We cannot use the given "for size" when querying our children, because
the constraint layout has no idea about the opposite size of its
children until the layout is complete.

Additionally, we should only suggest an opposite size for the layout if
we have one, instead of suggesting a weak zero size.
2019-06-28 13:11:22 +01:00
Emmanuele Bassi 19e7d412e3 Remove size constraints from ConstraintLayoutChild
The size constraints are transient to measurement and allocation, so
they don't really need to be stored inside the GtkLayoutChild subclass
created by a GtkConstraintLayout.
2019-06-27 17:38:02 +01:00
Matthias Clasen 80c27061c6 constraints: Make internal consistency required
The relations between left, right, width
and top, bottom, height are required for
internal consistency. It doesn't make sense
to ever drop these.

Changing the strength of these relations makes
my systems behave much more stable.
2019-06-27 17:38:02 +01:00
Matthias Clasen bd5c558646 Add gtk_constraint_layout_remove_constraint
Otherwise, you can't do many interesting things.
2019-06-27 17:38:02 +01:00
Emmanuele Bassi ad40630008 Do not release reference on the subject of an expression
We don't own the reference in the first place.
2019-06-27 17:38:02 +01:00
Matthias Clasen f07ba4ac5b constraints solver: Avoid critials
When the solver is finalized with existing
constraints, we end up with criticals when
the constraints ref finalize code calls
back into the hash table. Avoid that by
emptying the hash table beforehand.
2019-06-27 17:38:02 +01:00
Matthias Clasen 391add73ec constraint solver: Fix thawing
There was an obviously wrong precondition here.
2019-06-27 17:38:02 +01:00
Emmanuele Bassi a21562f270 Do not leak LayoutChild instances
Since the LayoutManager owns the LayoutChild it creates, it's also
responsible for mopping them up.
2019-06-27 17:38:02 +01:00
Emmanuele Bassi 124607d1e8 Add GtkConstraintLayout demo 2019-06-27 17:38:02 +01:00
Emmanuele Bassi 9756cb9482 Add GtkConstraintLayout
A layout manager using GtkConstraintSolver to measure and allocate
children.
2019-06-27 17:38:02 +01:00
Emmanuele Bassi 92f93a603b Propagate rooting and unrooting widgets to layout managers
Layout managers may need to get access to data attached to the root of a
scene graph.
2019-06-27 17:38:02 +01:00
Emmanuele Bassi e7cd3d4633 window: Create a GtkConstraintSolver
Implement the GtkRoot getter for GtkConstraintSolver.
2019-06-27 17:38:02 +01:00
Emmanuele Bassi 5780ec4bf1 Assign a GtkConstraintSolver to each GtkRoot
Constraints need to work across different parents, so it's better to
have a single constraint solver per top level.
2019-06-27 17:38:02 +01:00
Emmanuele Bassi ec14c1f605 Move the Root interface to a private header
We don't expect out of tree implementations of GtkRoot, and having the
interface structure private to the GTK code allows us to add virtual
functions involving private types.
2019-06-27 17:38:02 +01:00
Emmanuele Bassi c09fada79e Add constraint solver
GtkConstraintSolver is an implementation of the Cassowary constraint
solving algorithm:

  http://constraints.cs.washington.edu/cassowary/

The Cassowary method allows to incrementally solve a tableau of linear
equations, in the form of:

  x = y × coefficient + constant

with different weights, or strengths, applied to each one.

These equations can be used to describe constraints applied to a layout
of UI elements, which allows layout managers using the Cassowary method
to quickly, and efficiently, lay out widgets in complex relations
between themselves and their parent container.
2019-06-27 17:38:02 +01:00
283 changed files with 34018 additions and 70147 deletions
+18 -17
View File
@@ -1,7 +1,7 @@
stages:
- build
- flatpak
# - deploy
- deploy
.cache-paths: &cache-paths
paths:
@@ -101,19 +101,20 @@ flatpak-master:icon-browser:
APPID: org.gtk.IconBrowser4
<<: *flatpak-master
#pages:
# image: registry.gitlab.gnome.org/gnome/gtk/master:v6
# stage: deploy
# script:
# - meson -Dgtk_doc=true _build .
# - ninja -C _build
# - ninja -C _build gdk4-doc gsk4-doc gtk4-doc
# - mkdir -p public/
# - mv _build/docs/reference/gtk/html/ public/gtk/
# - mv _build/docs/reference/gdk/html/ public/gdk/
# - mv _build/docs/reference/gsk/html/ public/gsk/
# artifacts:
# paths:
# - public
# only:
# - master
pages:
image: registry.gitlab.gnome.org/gnome/gtk/master:v6
stage: deploy
script:
- meson -Ddocumentation=true _build .
- ninja -C _build
- ninja -C _build gdk4-doc gsk4-doc gtk4-doc
- mkdir -p public/
- mv _build/docs/reference/gtk/html/ public/gtk/
- mv _build/docs/reference/gdk/html/ public/gdk/
- mv _build/docs/reference/gsk/html/ public/gsk/
artifacts:
paths:
- public
only:
- master
+9
View File
@@ -56,6 +56,12 @@
/* 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
@@ -185,6 +191,9 @@
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#mesondefine LT_OBJDIR
/* Define if <X11/extensions/XIproto.h> needed for xReply */
#mesondefine NEED_XIPROTO_H_FOR_XREPLY
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
#mesondefine NO_MINUS_C_MINUS_O
@@ -1,115 +0,0 @@
/*
* 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);
}
@@ -1,28 +0,0 @@
/*
* 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);
@@ -1,639 +0,0 @@
/*
* 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);
}
@@ -1,34 +0,0 @@
/*
* 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);
@@ -1,82 +0,0 @@
<?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>
-656
View File
@@ -1,656 +0,0 @@
/*
* 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);
}
@@ -1,12 +0,0 @@
constraintview {
background: black;
color: white;
}
constraintview .child {
background: red;
}
constraintview .guide {
background: blue;
}
@@ -1,9 +0,0 @@
<?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,34 +0,0 @@
/*
* 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_TYPE (constraint_editor_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintEditor, constraint_editor, CONSTRAINT, EDITOR, GtkWidget)
ConstraintEditor * constraint_editor_new (GListModel *model,
GtkConstraint *constraint);
void constraint_editor_serialize_constraint (GString *str,
int indent,
GtkConstraint *constraint);
char *constraint_editor_constraint_to_string (GtkConstraint *constraint);
@@ -1,163 +0,0 @@
<?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>
@@ -1,93 +0,0 @@
/*
* 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);
@@ -1,44 +0,0 @@
/*
* 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);
-343
View File
@@ -1,343 +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>
#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;
}
-44
View File
@@ -1,44 +0,0 @@
/*
* 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);
-411
View File
@@ -1,411 +0,0 @@
/*
* 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);
}
-32
View File
@@ -1,32 +0,0 @@
/*
* 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);
-188
View File
@@ -1,188 +0,0 @@
<?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>
-28
View File
@@ -1,28 +0,0 @@
/*
* 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);
}
-20
View File
@@ -1,20 +0,0 @@
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,
link_args: extra_demo_ldflags,
install: false)
+15 -22
View File
@@ -44,21 +44,20 @@ simple_grid_class_init (SimpleGridClass *klass)
/* Layout:
*
* +-------------------------------------+
* | +-----------++-------++-----------+ |
* | | Child 1 || Space || Child 2 | |
* | +-----------++-------++-----------+ |
* | +---------------------------------+ |
* | | Child 3 | |
* | +---------------------------------+ |
* +-------------------------------------+
* +-----------------------------+
* | +-----------+ +-----------+ |
* | | Child 1 | | Child 2 | |
* | +-----------+ +-----------+ |
* | +-------------------------+ |
* | | Child 3 | |
* | +-------------------------+ |
* +-----------------------------+
*
* Constraints:
*
* super.start = child1.start - 8
* child1.width = child2.width
* child1.end = space.start
* space.end = child2.start
* child1.end = child2.start - 12
* child2.end = super.end - 8
* super.start = child3.start - 8
* child3.end = super.end - 8
@@ -70,12 +69,6 @@ simple_grid_class_init (SimpleGridClass *klass)
* child3.height = child2.height
* child3.bottom = super.bottom - 8
*
* To add some flexibility, we make the space
* stretchable:
*
* space.width >= 10
* space.width = 100
* space.width <= 200
*/
static void
build_constraints (SimpleGrid *self,
@@ -83,12 +76,12 @@ build_constraints (SimpleGrid *self,
{
GtkConstraintGuide *guide;
guide = gtk_constraint_guide_new ();
gtk_constraint_guide_set_name (guide, "space");
gtk_constraint_guide_set_min_size (guide, 10, 10);
gtk_constraint_guide_set_nat_size (guide, 100, 10);
gtk_constraint_guide_set_max_size (guide, 200, 20);
gtk_constraint_guide_set_strength (guide, GTK_CONSTRAINT_STRENGTH_STRONG);
guide = g_object_new (GTK_TYPE_CONSTRAINT_GUIDE,
"min-width", 10,
"min-height", 10,
"nat-width", 100,
"nat-height", 10,
NULL);
gtk_constraint_layout_add_guide (manager, guide);
gtk_constraint_layout_add_constraint (manager,
-165
View File
@@ -1,165 +0,0 @@
/* Constraints/VFL
*
* 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 (VflGrid, vfl_grid, VFL, GRID, GtkWidget)
struct _VflGrid
{
GtkWidget parent_instance;
GtkWidget *button1, *button2;
GtkWidget *button3;
};
G_DEFINE_TYPE (VflGrid, vfl_grid, GTK_TYPE_WIDGET)
static void
vfl_grid_destroy (GtkWidget *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);
GTK_WIDGET_CLASS (vfl_grid_parent_class)->destroy (widget);
}
static void
vfl_grid_class_init (VflGridClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
widget_class->destroy = vfl_grid_destroy;
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
}
/* Layout:
*
* +-----------------------------+
* | +-----------+ +-----------+ |
* | | 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 (VflGrid *self,
GtkConstraintLayout *manager)
{
const char * const vfl[] = {
"H:|-[button1(==button2)]-12-[button2]-|",
"H:|-[button3]-|",
"V:|-[button1]-12-[button3(==button1)]-|",
"V:|-[button2]-12-[button3(==button2)]-|",
};
GError *error = NULL;
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
vfl_grid_init (VflGrid *self)
{
GtkWidget *widget = GTK_WIDGET (self);
self->button1 = gtk_button_new_with_label ("Child 1");
gtk_widget_set_parent (self->button1, widget);
gtk_widget_set_name (self->button1, "button1");
self->button2 = gtk_button_new_with_label ("Child 2");
gtk_widget_set_parent (self->button2, widget);
gtk_widget_set_name (self->button2, "button2");
self->button3 = gtk_button_new_with_label ("Child 3");
gtk_widget_set_parent (self->button3, widget);
gtk_widget_set_name (self->button3, "button3");
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
}
GtkWidget *
do_constraints3 (GtkWidget *do_widget)
{
static GtkWidget *window;
if (!window)
{
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), "Constraints");
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_container_add (GTK_CONTAINER (window), box);
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);
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 (gtk_widget_destroy), window);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}
-5
View File
@@ -152,7 +152,6 @@
<file>combobox.c</file>
<file>constraints.c</file>
<file>constraints2.c</file>
<file>constraints3.c</file>
<file>css_accordion.c</file>
<file>css_basics.c</file>
<file>css_blendmodes.c</file>
@@ -174,7 +173,6 @@
<file>foreigndrawing.c</file>
<file>font_features.c</file>
<file>fontplane.c</file>
<file>fontrendering.c</file>
<file>gestures.c</file>
<file>glarea.c</file>
<file>headerbar.c</file>
@@ -282,9 +280,6 @@
<gresource prefix="/fixed">
<file>fixed.css</file>
</gresource>
<gresource prefix="/fontrendering">
<file>fontrendering.ui</file>
</gresource>
<gresource prefix="/org/gtk/Demo4">
<file>icons/16x16/actions/application-exit.png</file>
<file>icons/16x16/actions/document-new.png</file>
-1
View File
@@ -306,7 +306,6 @@ do_fishbowl (GtkWidget *do_widget)
G_CALLBACK (gtk_widget_destroyed), &window);
gtk_widget_realize (window);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
-288
View File
@@ -1,288 +0,0 @@
/* Pango/Font rendering
*
* Demonstrates various aspects of font rendering.
*/
#include <gtk/gtk.h>
static GtkWidget *window = NULL;
static GtkWidget *font_button = NULL;
static GtkWidget *entry = NULL;
static GtkWidget *image = NULL;
static GtkWidget *hinting = NULL;
static GtkWidget *hint_metrics = NULL;
static GtkWidget *up_button = NULL;
static GtkWidget *down_button = NULL;
static GtkWidget *text_radio = NULL;
static GtkWidget *show_grid = NULL;
static GtkWidget *show_extents = NULL;
static PangoContext *context;
static int scale = 10;
static void
on_destroy (gpointer data)
{
window = NULL;
}
static void
update_image (void)
{
const char *text;
PangoFontDescription *desc;
PangoLayout *layout;
PangoRectangle ink, pink, logical;
int baseline;
cairo_surface_t *surface;
cairo_t *cr;
GdkPixbuf *pixbuf;
GdkPixbuf *pixbuf2;
const char *hint;
cairo_font_options_t *fopt;
cairo_hint_style_t hintstyle;
cairo_hint_metrics_t hintmetrics;
int i;
if (!context)
context = gtk_widget_create_pango_context (image);
text = gtk_editable_get_text (GTK_EDITABLE (entry));
desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (font_button));
fopt = cairo_font_options_copy (pango_cairo_context_get_font_options (context));
hint = gtk_combo_box_get_active_id (GTK_COMBO_BOX (hinting));
if (strcmp (hint, "none") == 0)
hintstyle = CAIRO_HINT_STYLE_NONE;
else if (strcmp (hint, "slight") == 0)
hintstyle = CAIRO_HINT_STYLE_SLIGHT;
else if (strcmp (hint, "medium") == 0)
hintstyle = CAIRO_HINT_STYLE_MEDIUM;
else if (strcmp (hint, "full") == 0)
hintstyle = CAIRO_HINT_STYLE_FULL;
else
hintstyle = CAIRO_HINT_STYLE_DEFAULT;
cairo_font_options_set_hint_style (fopt, hintstyle);
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (hint_metrics)))
hintmetrics = CAIRO_HINT_METRICS_ON;
else
hintmetrics = CAIRO_HINT_METRICS_OFF;
cairo_font_options_set_hint_metrics (fopt, hintmetrics);
pango_cairo_context_set_font_options (context, fopt);
cairo_font_options_destroy (fopt);
pango_context_changed (context);
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (text_radio)))
{
layout = pango_layout_new (context);
pango_layout_set_font_description (layout, desc);
pango_layout_set_text (layout, text, -1);
pango_layout_get_extents (layout, &ink, &logical);
pink = ink;
baseline = pango_layout_get_baseline (layout);
pango_extents_to_pixels (&ink, NULL);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ink.width + 20, ink.height + 20);
cr = cairo_create (surface);
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_paint (cr);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_move_to (cr, 10, 10);
pango_cairo_show_layout (cr, layout);
cairo_destroy (cr);
g_object_unref (layout);
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface));
pixbuf2 = gdk_pixbuf_scale_simple (pixbuf, gdk_pixbuf_get_width (pixbuf) * scale, gdk_pixbuf_get_height (pixbuf) * scale, GDK_INTERP_NEAREST);
g_object_unref (pixbuf);
cairo_surface_destroy (surface);
surface = cairo_image_surface_create_for_data (gdk_pixbuf_get_pixels (pixbuf2),
CAIRO_FORMAT_ARGB32,
gdk_pixbuf_get_width (pixbuf2),
gdk_pixbuf_get_height (pixbuf2),
gdk_pixbuf_get_rowstride (pixbuf2));
cr = cairo_create (surface);
cairo_set_line_width (cr, 1);
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_grid)))
{
cairo_set_source_rgba (cr, 0.2, 0, 0, 0.2);
for (i = 1; i < ink.height + 20; i++)
{
cairo_move_to (cr, 0, scale * i - 0.5);
cairo_line_to (cr, scale * (ink.width + 20), scale * i - 0.5);
cairo_stroke (cr);
}
for (i = 1; i < ink.width + 20; i++)
{
cairo_move_to (cr, scale * i - 0.5, 0);
cairo_line_to (cr, scale * i - 0.5, scale * (ink.height + 20));
cairo_stroke (cr);
}
}
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_extents)))
{
cairo_set_source_rgba (cr, 0, 0, 1, 1);
cairo_rectangle (cr,
scale * (10 + pango_units_to_double (logical.x)) - 0.5,
scale * (10 + pango_units_to_double (logical.y)) - 0.5,
scale * pango_units_to_double (logical.width) + 1,
scale * pango_units_to_double (logical.height) + 1);
cairo_stroke (cr);
cairo_move_to (cr, scale * (10 + pango_units_to_double (logical.x)) - 0.5,
scale * (10 + pango_units_to_double (baseline)) - 0.5);
cairo_line_to (cr, scale * (10 + pango_units_to_double (logical.x + logical.width)) + 1,
scale * (10 + pango_units_to_double (baseline)) - 0.5);
cairo_stroke (cr);
cairo_set_source_rgba (cr, 1, 0, 0, 1);
cairo_rectangle (cr,
scale * (10 + pango_units_to_double (pink.x)) + 0.5,
scale * (10 + pango_units_to_double (pink.y)) + 0.5,
scale * pango_units_to_double (pink.width) - 1,
scale * pango_units_to_double (pink.height) - 1);
cairo_stroke (cr);
}
cairo_surface_destroy (surface);
cairo_destroy (cr);
}
else
{
PangoLayoutIter *iter;
PangoLayoutRun *run;
PangoGlyphInfo *g;
int i, j;
layout = pango_layout_new (context);
pango_layout_set_font_description (layout, desc);
pango_layout_set_text (layout, "aaaa", -1);
pango_layout_get_extents (layout, &ink, &logical);
pango_extents_to_pixels (&logical, NULL);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, logical.width * 3 / 2, 4*logical.height);
cr = cairo_create (surface);
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_paint (cr);
iter = pango_layout_get_iter (layout);
run = pango_layout_iter_get_run (iter);
cairo_set_source_rgb (cr, 0, 0, 0);
for (i = 0; i < 4; i++)
{
g = &(run->glyphs->glyphs[i]);
g->geometry.width = PANGO_UNITS_ROUND (g->geometry.width * 3 / 2);
}
for (j = 0; j < 4; j++)
{
for (i = 0; i < 4; i++)
{
g = &(run->glyphs->glyphs[i]);
g->geometry.x_offset = i * (PANGO_SCALE / 4);
g->geometry.y_offset = j * (PANGO_SCALE / 4);
}
cairo_move_to (cr, 0, j * logical.height);
pango_cairo_show_layout (cr, layout);
}
cairo_destroy (cr);
pango_layout_iter_free (iter);
g_object_unref (layout);
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface));
pixbuf2 = gdk_pixbuf_scale_simple (pixbuf, gdk_pixbuf_get_width (pixbuf) * scale, gdk_pixbuf_get_height (pixbuf) * scale, GDK_INTERP_NEAREST);
g_object_unref (pixbuf);
cairo_surface_destroy (surface);
}
gtk_picture_set_pixbuf (GTK_PICTURE (image), pixbuf2);
g_object_unref (pixbuf2);
pango_font_description_free (desc);
}
static void
update_buttons (void)
{
gtk_widget_set_sensitive (up_button, scale < 32);
gtk_widget_set_sensitive (down_button, scale > 1);
}
static void
scale_up (void)
{
scale += 1;
update_buttons ();
update_image ();
}
static void
scale_down (void)
{
scale -= 1;
update_buttons ();
update_image ();
}
GtkWidget *
do_fontrendering (GtkWidget *do_widget)
{
if (!window)
{
GtkBuilder *builder;
builder = gtk_builder_new_from_resource ("/fontrendering/fontrendering.ui");
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_signal_connect (window, "destroy",
G_CALLBACK (on_destroy), NULL);
g_object_set_data_full (G_OBJECT (window), "builder", builder, g_object_unref);
font_button = GTK_WIDGET (gtk_builder_get_object (builder, "font_button"));
up_button = GTK_WIDGET (gtk_builder_get_object (builder, "up_button"));
down_button = GTK_WIDGET (gtk_builder_get_object (builder, "down_button"));
entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
image = GTK_WIDGET (gtk_builder_get_object (builder, "image"));
hinting = GTK_WIDGET (gtk_builder_get_object (builder, "hinting"));
hint_metrics = GTK_WIDGET (gtk_builder_get_object (builder, "hint_metrics"));
text_radio = GTK_WIDGET (gtk_builder_get_object (builder, "text_radio"));
show_grid = GTK_WIDGET (gtk_builder_get_object (builder, "show_grid"));
show_extents = GTK_WIDGET (gtk_builder_get_object (builder, "show_extents"));
g_signal_connect (up_button, "clicked", G_CALLBACK (scale_up), NULL);
g_signal_connect (down_button, "clicked", G_CALLBACK (scale_down), NULL);
g_signal_connect (entry, "notify::text", G_CALLBACK (update_image), NULL);
g_signal_connect (font_button, "notify::font-desc", G_CALLBACK (update_image), NULL);
g_signal_connect (hinting, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (hint_metrics, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (text_radio, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (show_grid, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (show_extents, "notify::active", G_CALLBACK (update_image), NULL);
update_image ();
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}
-215
View File
@@ -1,215 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkAdjustment" id="scale_adj">
<property name="upper">24</property>
<property name="step-increment">1</property>
<property name="page-increment">4</property>
</object>
<object class="GtkWindow" id="window">
<property name="default-width">600</property>
<property name="default-height">300</property>
<property name="title">Font rendering</property>
<child>
<object class="GtkGrid">
<property name="margin-top">10</property>
<property name="row-spacing">10</property>
<property name="column-spacing">10</property>
<child>
<object class="GtkLabel">
<property name="margin-start">10</property>
<property name="label">Text</property>
<property name="xalign">1</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkEntry" id="entry">
<property name="text">Fonts render</property>
<layout>
<property name="left-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="margin-start">10</property>
<property name="label">Font</property>
<property name="xalign">1</property>
<style>
<class name="dim-label"/>
</style>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkFontButton" id="font_button">
<layout>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Hinting</property>
<property name="xalign">1</property>
<style>
<class name="dim-label"/>
</style>
<layout>
<property name="left-attach">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkComboBoxText" id="hinting">
<property name="active">0</property>
<property name="valign">center</property>
<items>
<item translatable="yes" id="none">None</item>
<item translatable="yes" id="slight">Slight</item>
<item translatable="yes" id="medium">Medium</item>
<item translatable="yes" id="full">Full</item>
</items>
<layout>
<property name="left-attach">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="hint_metrics">
<child>
<object class="GtkLabel">
<property name="label">Hint Metrics</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<layout>
<property name="left-attach">3</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="show_extents">
<property name="active">1</property>
<child>
<object class="GtkLabel">
<property name="label">Show Extents</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<layout>
<property name="left-attach">4</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="show_grid">
<property name="active">1</property>
<child>
<object class="GtkLabel">
<property name="label">Show Grid</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<layout>
<property name="left-attach">4</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton" id="up_button">
<property name="icon-name">list-add-symbolic</property>
<style>
<class name="circular"/>
</style>
<layout>
<property name="left-attach">5</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton" id="down_button">
<property name="icon-name">list-remove-symbolic</property>
<style>
<class name="circular"/>
</style>
<layout>
<property name="left-attach">5</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="hexpand">1</property>
<layout>
<property name="left-attach">6</property>
</layout>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="halign">center</property>
<property name="valign">center</property>
<style><class name="linked"/></style>
<child>
<object class="GtkRadioButton" id="text_radio">
<property name="draw-indicator">0</property>
<property name="label">Text</property>
</object>
</child>
<child>
<object class="GtkRadioButton" id="grid_radio">
<property name="draw-indicator">0</property>
<property name="label">Grid</property>
<property name="group">text_radio</property>
</object>
</child>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
<property name="column-span">7</property>
</layout>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="propagate-natural-height">1</property>
<property name="shadow-type">in</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<child>
<object class="GtkPicture" id="image">
<property name="halign">center</property>
<property name="valign">center</property>
<property name="can-shrink">0</property>
</object>
</child>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">4</property>
<property name="column-span">7</property>
</layout>
</object>
</child>
</object>
</child>
</object>
</interface>
+1 -1
View File
@@ -202,7 +202,7 @@ languages_variant_init (const char *variant)
else
g_warning ("Failed to load '%s': %s\n", filename, error->message);
g_clear_error (&error);
g_free (error);
g_free (filename);
g_free (buf);
}
-2
View File
@@ -10,7 +10,6 @@ demos = files([
'combobox.c',
'constraints.c',
'constraints2.c',
'constraints3.c',
'css_accordion.c',
'css_basics.c',
'css_blendmodes.c',
@@ -28,7 +27,6 @@ demos = files([
'filtermodel.c',
'fishbowl.c',
'fixed.c',
'fontrendering.c',
'foreigndrawing.c',
'gestures.c',
'glarea.c',
+1 -1
View File
@@ -378,7 +378,7 @@
378|GTK+ and friends|GTKtoolkit|#GNUStep gets #GTK+ theming http://is.gd/95vHl more at http://is.gd/95wt8|1267029498|0||0|1
379|GTK+ and friends|GTKtoolkit|GTK+ 2.19.6 released: http://mail.gnome.org/archives/gtk-devel-list/2010-February/msg00050.html #gtk|1266966985|0||0|0
380|GTK+ and friends|GTKtoolkit|Did you know that #GTK+ is the official toolkit for the #LiMo software stack? http://bit.ly/cuEdHx|1266925406|0||0|0
381|GTK+ and friends|GTKtoolkit|@lmedinas publishes a #javascript #example on how to put a status icon with #Gtk+ http://bit.ly/9py1uC Thanks a lot Luis!|1266886644|0||1|1
381|GTK+ and friends|GTKtoolkit|@lmedinas publishes a #javascript #example on how to put an status icon with #Gtk+ http://bit.ly/9py1uC Thanks a lot Luis!|1266886644|0||1|1
382|GTK+ and friends|GTKtoolkit|♺ @ebassi: I should really finish up the GDom API as well|1266880653|0||0|0
383|GTK+ and friends|GTKtoolkit|♺ @ebassi: I hope to work on this for the next GIO release, and the GTK+ side for 3.0|1266880641|0||0|0
384|GTK+ and friends|GTKtoolkit|♺ @ebassi: just updated the ApplicationClass design wiki page with the stuff @Cwiiis did for Mx - http://bit.ly/cfAOJk|1266880559|0||0|0
+1 -1
View File
@@ -6,7 +6,7 @@
* GTK uses for videos. This allows treating the icon like a
* regular video, so we can for example attach controls to it.
*
* After all, what good is a media_stream if one cannot pause
* After all, what good is an media_stream if one cannot pause
* it.
*/
+1 -1
View File
@@ -285,7 +285,7 @@ user-trash=The icon for the user's “Trash” place in the file system
user-trash-full=The icon for the user's “Trash” in the file system, when there are items in the “Trash” waiting for disposal or recovery
emblem-system=The icon used as an emblem for directories that contain system libraries, settings, and data
avatar-default=The generic avatar icon, which is used to represent a user that doesn't have a personalized avatar
emblem-synchronizing=The icon used as an emblem to indicate that a synchronizing operation is in process
emblem-synchronizing=The icon used as an emblem to indicate that a a synchronizing operation is in process
emblem-shared=The icon used as an emblem for files and directories that are shared to other users
help-browser=The icon used for the desktop's help browsing application
-1
View File
@@ -1,4 +1,3 @@
subdir('constraint-editor')
subdir('gtk-demo')
subdir('icon-browser')
subdir('node-editor')
-8
View File
@@ -707,14 +707,6 @@ static void
node_editor_window_unrealize (GtkWidget *widget)
{
NodeEditorWindow *self = NODE_EDITOR_WINDOW (widget);
guint i;
for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (self->renderers)); i ++)
{
gpointer item = g_list_model_get_item (G_LIST_MODEL (self->renderers), i);
gsk_renderer_unrealize (gtk_renderer_paintable_get_renderer (item));
g_object_unref (item);
}
g_list_store_remove_all (self->renderers);
+7 -13
View File
@@ -1405,10 +1405,8 @@ text_view_add_to_context_menu (GtkTextView *text_view)
item = g_menu_item_new (_("Underline"), "format.underline");
g_menu_item_set_attribute (item, "touch-icon", "s", "format-text-underline-symbolic");
g_menu_append_item (G_MENU (menu), item);
g_object_unref (item);
gtk_text_view_set_extra_menu (text_view, G_MENU_MODEL (menu));
g_object_unref (menu);
g_signal_connect (gtk_text_view_get_buffer (text_view), "changed", G_CALLBACK (text_changed), NULL);
g_signal_connect (gtk_text_view_get_buffer (text_view), "mark-set", G_CALLBACK (text_changed), NULL);
@@ -1603,14 +1601,14 @@ reset_icon_size (GtkWidget *iv)
gtk_widget_queue_resize (iv);
}
static char *
scale_format_value_blank (GtkScale *scale, double value, gpointer user_data)
static gchar *
scale_format_value_blank (GtkScale *scale, gdouble value)
{
return g_strdup (" ");
}
static char *
scale_format_value (GtkScale *scale, double value, gpointer user_data)
static gchar *
scale_format_value (GtkScale *scale, gdouble value)
{
return g_strdup_printf ("%0.*f", 1, value);
}
@@ -1709,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_APPLICATION);
GTK_STYLE_PROVIDER_PRIORITY_USER);
g_object_unref (provider);
builder = gtk_builder_new_from_resource ("/org/gtk/WidgetFactory4/widget-factory.ui");
@@ -1724,6 +1722,8 @@ activate (GApplication *app)
gtk_builder_add_callback_symbol (builder, "increase_icon_size", (GCallback)increase_icon_size);
gtk_builder_add_callback_symbol (builder, "decrease_icon_size", (GCallback)decrease_icon_size);
gtk_builder_add_callback_symbol (builder, "reset_icon_size", (GCallback)reset_icon_size);
gtk_builder_add_callback_symbol (builder, "scale_format_value", (GCallback)scale_format_value);
gtk_builder_add_callback_symbol (builder, "scale_format_value_blank", (GCallback)scale_format_value_blank);
gtk_builder_add_callback_symbol (builder, "osd_frame_pressed", (GCallback)osd_frame_pressed);
gtk_builder_connect_signals (builder, NULL);
@@ -1943,12 +1943,6 @@ activate (GApplication *app)
widget = (GtkWidget *)gtk_builder_get_object (builder, "extra_info_entry");
g_timeout_add (100, (GSourceFunc)pulse_it, widget);
widget = (GtkWidget *)gtk_builder_get_object (builder, "scale3");
gtk_scale_set_format_value_func (GTK_SCALE (widget), scale_format_value, NULL, NULL);
widget = (GtkWidget *)gtk_builder_get_object (builder, "scale4");
gtk_scale_set_format_value_func (GTK_SCALE (widget), scale_format_value_blank, NULL, NULL);
widget = (GtkWidget *)gtk_builder_get_object (builder, "box_for_context");
model = (GMenuModel *)gtk_builder_get_object (builder, "new_style_context_menu_model");
set_up_context_popover (widget, model);
+2 -1
View File
@@ -1019,6 +1019,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="fill-level">75</property>
<property name="digits">-1</property>
<property name="halign">end</property>
<signal name="format-value" handler="scale_format_value"/>
</object>
</child>
<child>
@@ -1032,6 +1033,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="fill-level">75</property>
<property name="digits">-1</property>
<property name="halign">start</property>
<signal name="format-value" handler="scale_format_value_blank"/>
</object>
</child>
</object>
@@ -3433,7 +3435,6 @@ bad things might happen.</property>
<property name="halign">end</property>
<property name="icon-name">emblem-system-symbolic</property>
<property name="menu-model">gear_menu</property>
<property name="tooltip-text">This is a menu button</property>
<layout>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
+1 -1
View File
@@ -99,7 +99,7 @@ if wayland_enabled
src_dir += [ gdkwayland_inc ]
endif
if get_option('gtk_doc')
if get_option('documentation')
configure_file(input: 'version.xml.in', output: 'version.xml', configuration: version_conf)
gnome.gtkdoc('gdk4',
+1 -1
View File
@@ -34,7 +34,7 @@ private_headers = [
images = [
]
if get_option('gtk_doc')
if get_option('documentation')
configure_file(input: 'version.xml.in', output: 'version.xml', configuration: version_conf)
gnome.gtkdoc('gsk4',
+4 -4
View File
@@ -355,8 +355,8 @@ How to compile GTK itself
</group>
<sbr/>
<group>
<arg choice="plain">-Dgtk_doc=true</arg>
<arg choice="plain">-Dgtk_doc=false</arg>
<arg choice="plain">-Ddocumentation=true</arg>
<arg choice="plain">-Ddocumentation=false</arg>
</group>
<sbr/>
<group>
@@ -382,7 +382,7 @@ How to compile GTK itself
</formalpara>
<formalpara>
<title><systemitem>gtk_doc</systemitem> and
<title><systemitem>documentation</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>gtk_doc</systemitem>.
in <systemitem>documentation</systemitem>.
</para>
<para>
Additionally, some tools provided by GTK have their own
-3
View File
@@ -109,9 +109,6 @@
<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">
+2 -94
View File
@@ -136,7 +136,6 @@ gtk_accel_map_get_type
GtkAccelLabel
gtk_accel_label_new
gtk_accel_label_set_accel_closure
gtk_accel_label_get_accel_closure
gtk_accel_label_get_accel_widget
gtk_accel_label_set_accel_widget
gtk_accel_label_get_accel_width
@@ -4433,6 +4432,7 @@ gtk_widget_realize
gtk_widget_unrealize
gtk_widget_queue_draw
gtk_widget_queue_resize
gtk_widget_queue_resize_no_redraw
gtk_widget_queue_allocate
gtk_widget_get_frame_clock
gtk_widget_get_scale_factor
@@ -4604,6 +4604,7 @@ gtk_widget_get_vexpand
gtk_widget_set_vexpand
gtk_widget_get_vexpand_set
gtk_widget_set_vexpand_set
gtk_widget_queue_compute_expand
gtk_widget_compute_expand
<SUBSECTION Templates>
@@ -4815,13 +4816,6 @@ gtk_get_event_target
gtk_get_event_target_with_type
gtk_propagate_event
<SUBSECTION>
gtk_set_supported_themes
gtk_set_unsupported_themes
gtk_set_prefer_dark_theme
gtk_get_current_theme
gtk_theme_is_dark
<SUBSECTION Private>
gtk_init_abi_check
gtk_init_check_abi_check
@@ -6745,8 +6739,6 @@ gtk_gesture_drag_get_type
<TITLE>GtkGestureLongPress</TITLE>
GtkGestureLongPress
gtk_gesture_long_press_new
gtk_gesture_long_press_set_delay_factor
gtk_gesture_long_press_get_delay_factor
<SUBSECTION Standard>
GTK_TYPE_GESTURE_LONG_PRESS
@@ -7295,87 +7287,3 @@ 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,7 +49,7 @@
files for icon themes.
</para>
<para>
It expects to be given the <replaceable>PATH</replaceable> to an icon theme
It expects to be given the <replaceable>PATH</replaceable> to a icon theme
directory containing an <filename>index.theme</filename>, e.g.
<filename>/usr/share/icons/hicolor</filename>, and writes a
<filename>icon-theme.cache</filename> containing cached information about
-4
View File
@@ -49,10 +49,6 @@ 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
+1 -8
View File
@@ -23,13 +23,6 @@ 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',
@@ -401,7 +394,7 @@ else
types_conf.set('DISABLE_ON_QUARTZ', '')
endif
if get_option('gtk_doc')
if get_option('documentation')
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)
+9 -4
View File
@@ -11,10 +11,7 @@ GTK is released under the GNU Library General Public License
applications. GTK has a C-based object-oriented architecture that
allows for maximum flexibility. Bindings for many other languages have
been written, including C++, Objective-C, Guile/Scheme, Perl, Python,
TOM, Ada95, Free Pascal, and Eiffel. The GTK library itself contains
<firstterm>widgets</firstterm>, that is, GUI components such as GtkButton
or GtkTextView.
TOM, Ada95, Free Pascal, and Eiffel.
</para>
<para>
GTK depends on the following libraries:
@@ -108,6 +105,14 @@ and rendering it using different rendering APIs. GSK provides renderers
for OpenGL, Vulkan and cairo.
</para></listitem>
</varlistentry>
<varlistentry>
<term>GTK</term>
<listitem><para>
The GTK library itself contains <firstterm>widgets</firstterm>,
that is, GUI components such as GtkButton or GtkTextView.
</para></listitem>
</varlistentry>
</variablelist>
</para>
</partintro>
+1 -1
View File
@@ -1,4 +1,4 @@
if get_option('gtk_doc')
if get_option('documentation')
glib_prefix = dependency('glib-2.0').get_pkgconfig_variable('prefix')
glib_docpath = join_paths(glib_prefix, 'share', 'gtk-doc', 'html')
+1 -1
View File
@@ -1,4 +1,4 @@
if x11_enabled and get_option('gtk_doc')
if x11_enabled and get_option('documentation')
doc_shooter_sources = [
'shadow.c',
'shooter.c',
+1 -1
View File
@@ -6,7 +6,7 @@ anyone who hopes to work with the code in the future.
HOW THE GTKTREEVIEW CALCULATES SIZE:
====================================
When the view is given a new model, the first thing it does is walk
through the model at the top level, creating a GtkRBNode for each
through the model at the top level, creating an GtkRBNode for each
element of the model. Each node has a height of 0. The RBTree is kept
updated as the models structure changes. Additionally, the user can
expand, collapse, and select rows at this stage. The RBTree is accurate
+1 -3
View File
@@ -98,9 +98,7 @@ _gdk_broadway_display_size_changed (GdkDisplay *display,
GdkBroadwaySurface *toplevel = l->data;
if (toplevel->maximized)
gdk_broadway_surface_move_resize (GDK_SURFACE (toplevel),
0, 0,
msg->width, msg->height);
gdk_surface_move_resize (GDK_SURFACE (toplevel), 0, 0, msg->width, msg->height);
}
}
-6
View File
@@ -70,12 +70,6 @@ void _gdk_broadway_surface_grab_check_unmap (GdkSurface *surface,
gulong serial);
void gdk_broadway_surface_update_popups (GdkSurface *surface);
void gdk_broadway_surface_move_resize (GdkSurface *surface,
gint x,
gint y,
gint width,
gint height);
void _gdk_keymap_keys_changed (GdkDisplay *display);
gint _gdk_broadway_get_group_for_state (GdkDisplay *display,
GdkModifierType state);
+24 -106
View File
@@ -88,10 +88,10 @@ gdk_broadway_surface_finalize (GObject *object)
}
static gboolean
thaw_updates_cb (GdkSurface *surface)
thaw_clock_cb (GdkFrameClock *clock)
{
gdk_surface_thaw_updates (surface);
g_object_unref (surface);
_gdk_frame_clock_thaw (clock);
g_object_unref (clock);
return G_SOURCE_REMOVE;
}
@@ -109,9 +109,9 @@ _gdk_broadway_roundtrip_notify (GdkSurface *surface,
/* If there is no remote web client, rate limit update to once a second */
if (local_reply)
g_timeout_add_seconds (1, (GSourceFunc)thaw_updates_cb, g_object_ref (surface));
g_timeout_add_seconds (1, (GSourceFunc)thaw_clock_cb, g_object_ref (clock));
else
gdk_surface_thaw_updates (surface);
_gdk_frame_clock_thaw (clock);
if (timings)
{
@@ -140,7 +140,7 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
GdkBroadwayDisplay *broadway_display;
impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
gdk_surface_freeze_updates (surface);
_gdk_frame_clock_freeze (gdk_surface_get_frame_clock (surface));
broadway_display = GDK_BROADWAY_DISPLAY (display);
@@ -368,12 +368,12 @@ gdk_broadway_surface_withdraw (GdkSurface *surface)
}
static void
gdk_broadway_surface_move_resize_internal (GdkSurface *surface,
gboolean with_move,
gint x,
gint y,
gint width,
gint height)
gdk_broadway_surface_move_resize (GdkSurface *surface,
gboolean with_move,
gint x,
gint y,
gint width,
gint height)
{
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
GdkBroadwayDisplay *broadway_display;
@@ -424,84 +424,6 @@ gdk_broadway_surface_move_resize_internal (GdkSurface *surface,
}
}
void
gdk_broadway_surface_move_resize (GdkSurface *surface,
gint x,
gint y,
gint width,
gint height)
{
gdk_broadway_surface_move_resize_internal (surface, TRUE,
x, y,
width, height);
}
static void
gdk_broadway_surface_toplevel_resize (GdkSurface *surface,
gint width,
gint height)
{
gdk_broadway_surface_move_resize_internal (surface, FALSE,
0, 0,
width, height);
}
static void
gdk_broadway_surface_move (GdkSurface *surface,
gint x,
gint y)
{
gdk_broadway_surface_move_resize_internal (surface, TRUE, x, y, -1, -1);
}
static void
gdk_broadway_surface_moved_to_rect (GdkSurface *surface,
GdkRectangle final_rect)
{
GdkSurface *toplevel;
int x, y;
if (surface->surface_type == GDK_SURFACE_POPUP)
toplevel = surface->parent;
else
toplevel = surface->transient_for;
gdk_surface_get_origin (toplevel, &x, &y);
x += final_rect.x;
y += final_rect.y;
if (final_rect.width != surface->width ||
final_rect.height != surface->height)
{
gdk_broadway_surface_move_resize (surface,
x, y,
final_rect.width, final_rect.height);
}
else
{
gdk_broadway_surface_move (surface, x, y);
}
}
static void
gdk_broadway_surface_move_to_rect (GdkSurface *surface,
const GdkRectangle *rect,
GdkGravity rect_anchor,
GdkGravity surface_anchor,
GdkAnchorHints anchor_hints,
gint rect_anchor_dx,
gint rect_anchor_dy)
{
gdk_surface_move_to_rect_helper (surface,
rect,
rect_anchor,
surface_anchor,
anchor_hints,
rect_anchor_dx,
rect_anchor_dy,
gdk_broadway_surface_moved_to_rect);
}
static void
gdk_broadway_surface_raise (GdkSurface *surface)
{
@@ -773,9 +695,9 @@ gdk_broadway_surface_maximize (GdkSurface *surface)
monitor = gdk_display_get_primary_monitor (display);
gdk_monitor_get_geometry (monitor, &geom);
gdk_broadway_surface_move_resize (surface,
geom.x, geom.y,
geom.width, geom.height);
gdk_surface_move_resize (surface,
geom.x, geom.y,
geom.width, geom.height);
}
static void
@@ -796,11 +718,11 @@ gdk_broadway_surface_unmaximize (GdkSurface *surface)
gdk_synthesize_surface_state (surface, GDK_SURFACE_STATE_MAXIMIZED, 0);
gdk_broadway_surface_move_resize (surface,
impl->pre_maximize_x,
impl->pre_maximize_y,
impl->pre_maximize_width,
impl->pre_maximize_height);
gdk_surface_move_resize (surface,
impl->pre_maximize_x,
impl->pre_maximize_y,
impl->pre_maximize_width,
impl->pre_maximize_height);
}
static void
@@ -891,9 +813,7 @@ gdk_broadway_surface_update_popups (GdkSurface *parent)
int new_y = parent->y + popup_impl->offset_y;
if (new_x != popup->x || new_y != popup->y)
gdk_broadway_surface_move_resize (popup,
new_x, new_y,
popup->width, popup->height);
gdk_broadway_surface_move_resize (popup, TRUE, new_x, new_y, popup->width, popup->height);
gdk_broadway_surface_restack_toplevel (popup, parent, TRUE);
}
}
@@ -1015,8 +935,7 @@ update_pos (MoveResizeData *mv_resize,
w, h, &w, &h);
}
gdk_broadway_surface_move_resize (mv_resize->moveresize_surface,
x, y, w, h);
gdk_surface_move_resize (mv_resize->moveresize_surface, x, y, w, h);
}
else
{
@@ -1025,7 +944,7 @@ update_pos (MoveResizeData *mv_resize,
x = mv_resize->moveresize_orig_x + dx;
y = mv_resize->moveresize_orig_y + dy;
gdk_broadway_surface_move (mv_resize->moveresize_surface, x, y);
gdk_surface_move (mv_resize->moveresize_surface, x, y);
}
}
@@ -1392,8 +1311,7 @@ gdk_broadway_surface_class_init (GdkBroadwaySurfaceClass *klass)
impl_class->raise = gdk_broadway_surface_raise;
impl_class->lower = gdk_broadway_surface_lower;
impl_class->restack_toplevel = gdk_broadway_surface_restack_toplevel;
impl_class->toplevel_resize = gdk_broadway_surface_toplevel_resize;
impl_class->move_to_rect = gdk_broadway_surface_move_to_rect;
impl_class->move_resize = gdk_broadway_surface_move_resize;
impl_class->get_geometry = gdk_broadway_surface_get_geometry;
impl_class->get_root_coords = gdk_broadway_surface_get_root_coords;
impl_class->get_device_state = gdk_broadway_surface_get_device_state;
+1 -1
View File
@@ -1312,7 +1312,7 @@ gdk_event_get_scroll_deltas (const GdkEvent *event,
* stop scroll event is the signal that a widget may trigger kinetic
* scrolling based on the current velocity.
*
* Stop scroll events always have a delta of 0/0.
* Stop scroll events always have a a delta of 0/0.
*
* Returns: %TRUE if the event is a scroll stop event
*/
+2 -44
View File
@@ -97,14 +97,10 @@ struct _GdkFrameClockPrivate
gint n_timings;
gint current;
GdkFrameTimings *timings[FRAME_HISTORY_MAX_LENGTH];
gint n_freeze_inhibitors;
};
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkFrameClock, gdk_frame_clock, G_TYPE_OBJECT)
static void
_gdk_frame_clock_freeze (GdkFrameClock *clock);
static void
gdk_frame_clock_finalize (GObject *object)
{
@@ -118,21 +114,12 @@ gdk_frame_clock_finalize (GObject *object)
G_OBJECT_CLASS (gdk_frame_clock_parent_class)->finalize (object);
}
static void
gdk_frame_clock_constructed (GObject *object)
{
G_OBJECT_CLASS (gdk_frame_clock_parent_class)->constructed (object);
_gdk_frame_clock_freeze (GDK_FRAME_CLOCK (object));
}
static void
gdk_frame_clock_class_init (GdkFrameClockClass *klass)
{
GObjectClass *gobject_class = (GObjectClass*) klass;
gobject_class->finalize = gdk_frame_clock_finalize;
gobject_class->constructed = gdk_frame_clock_constructed;
/**
* GdkFrameClock::flush-events:
@@ -348,7 +335,7 @@ gdk_frame_clock_end_updating (GdkFrameClock *frame_clock)
GDK_FRAME_CLOCK_GET_CLASS (frame_clock)->end_updating (frame_clock);
}
static void
void
_gdk_frame_clock_freeze (GdkFrameClock *clock)
{
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
@@ -357,7 +344,7 @@ _gdk_frame_clock_freeze (GdkFrameClock *clock)
}
static void
void
_gdk_frame_clock_thaw (GdkFrameClock *clock)
{
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
@@ -365,35 +352,6 @@ _gdk_frame_clock_thaw (GdkFrameClock *clock)
GDK_FRAME_CLOCK_GET_CLASS (clock)->thaw (clock);
}
void
_gdk_frame_clock_inhibit_freeze (GdkFrameClock *clock)
{
GdkFrameClockPrivate *priv;
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
priv = clock->priv;
priv->n_freeze_inhibitors++;
if (priv->n_freeze_inhibitors == 1)
_gdk_frame_clock_thaw (clock);
}
void
_gdk_frame_clock_uninhibit_freeze (GdkFrameClock *clock)
{
GdkFrameClockPrivate *priv;
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
priv = clock->priv;
priv->n_freeze_inhibitors--;
if (priv->n_freeze_inhibitors == 0)
_gdk_frame_clock_freeze (clock);
}
/**
* gdk_frame_clock_get_frame_counter:
* @frame_clock: a #GdkFrameClock
+2 -2
View File
@@ -105,8 +105,8 @@ struct _GdkFrameTimings
guint slept_before : 1;
};
void _gdk_frame_clock_inhibit_freeze (GdkFrameClock *clock);
void _gdk_frame_clock_uninhibit_freeze (GdkFrameClock *clock);
void _gdk_frame_clock_freeze (GdkFrameClock *clock);
void _gdk_frame_clock_thaw (GdkFrameClock *clock);
void _gdk_frame_clock_begin_frame (GdkFrameClock *clock);
void _gdk_frame_clock_debug_print_timings (GdkFrameClock *clock,
+1 -1
View File
@@ -770,7 +770,7 @@ gdk_gl_context_set_is_legacy (GdkGLContext *context,
* @use_es: whether the context should use OpenGL ES instead of OpenGL,
* or -1 to allow auto-detection
*
* Requests that GDK create an OpenGL ES context instead of an OpenGL one,
* Requests that GDK create a OpenGL ES context instead of an OpenGL one,
* if the platform and windowing system allows it.
*
* The @context must not have been realized.
+10
View File
@@ -264,6 +264,16 @@ void gdk_surface_get_geometry (GdkSurface *surface,
gint *width,
gint *height);
void gdk_surface_move (GdkSurface *surface,
gint x,
gint y);
void gdk_surface_move_resize (GdkSurface *surface,
gint x,
gint y,
gint width,
gint height);
GdkGLContext *gdk_surface_get_shared_data_gl_context (GdkSurface *surface);
G_END_DECLS
+1 -6
View File
@@ -401,12 +401,7 @@ gdk_monitor_get_connector (GdkMonitor *monitor)
* gdk_monitor_get_manufacturer:
* @monitor: a #GdkMonitor
*
* Gets the name or PNP ID of the monitor's manufacturer, if available.
*
* Note that this value might also vary depending on actual
* display backend.
*
* PNP ID registry is located at https://uefi.org/pnp_id_list
* Gets the name of the monitor's manufacturer, if available.
*
* Returns: (transfer none) (nullable): the name of the manufacturer, or %NULL
*/
+1 -1
View File
@@ -28,7 +28,7 @@
/**
* SECTION:gdkseat
* @Short_description: Object representing a user seat
* @Short_description: Object representing an user seat
* @Title: GdkSeat
* @See_also: #GdkDisplay, #GdkDevice
*
+1 -1
View File
@@ -65,7 +65,7 @@ gdk_text_property_to_utf8_list_for_display (GdkDisplay *display,
* gdk_utf8_to_string_target:
* @str: a UTF-8 string
*
* Converts a UTF-8 string into the best possible representation
* Converts an UTF-8 string into the best possible representation
* as a STRING. The representation of characters not in STRING
* is not specified; it may be as pseudo-escape sequences
* \x{ABCD}, or it may be in some other form of approximation.
+136 -69
View File
@@ -246,15 +246,14 @@ maybe_flip_position (gint bounds_pos,
return primary;
}
void
gdk_surface_move_to_rect_helper (GdkSurface *surface,
const GdkRectangle *rect,
GdkGravity rect_anchor,
GdkGravity surface_anchor,
GdkAnchorHints anchor_hints,
gint rect_anchor_dx,
gint rect_anchor_dy,
GdkSurfaceMovedToRect moved_to_rect)
static void
gdk_surface_real_move_to_rect (GdkSurface *surface,
const GdkRectangle *rect,
GdkGravity rect_anchor,
GdkGravity surface_anchor,
GdkAnchorHints anchor_hints,
gint rect_anchor_dx,
gint rect_anchor_dy)
{
GdkSurface *toplevel;
GdkDisplay *display;
@@ -363,14 +362,17 @@ gdk_surface_move_to_rect_helper (GdkSurface *surface,
final_rect.width += surface->shadow_left + surface->shadow_right;
final_rect.height += surface->shadow_top + surface->shadow_bottom;
if (final_rect.width != surface->width || final_rect.height != surface->height)
gdk_surface_move_resize (surface, final_rect.x, final_rect.y, final_rect.width, final_rect.height);
else
gdk_surface_move (surface, final_rect.x, final_rect.y);
gdk_surface_get_origin (toplevel, &x, &y);
final_rect.x -= x;
final_rect.y -= y;
flipped_rect.x -= x;
flipped_rect.y -= y;
moved_to_rect (surface, final_rect);
g_signal_emit_by_name (surface,
"moved-to-rect",
&flipped_rect,
@@ -409,6 +411,7 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
object_class->get_property = gdk_surface_get_property;
klass->beep = gdk_surface_real_beep;
klass->move_to_rect = gdk_surface_real_move_to_rect;
/**
* GdkSurface:cursor:
@@ -1338,14 +1341,10 @@ gdk_surface_schedule_update (GdkSurface *surface)
{
GdkFrameClock *frame_clock;
g_return_if_fail (surface);
if (surface->update_freeze_count ||
gdk_surface_is_toplevel_frozen (surface))
{
surface->pending_schedule_update = TRUE;
return;
}
if (surface &&
(surface->update_freeze_count ||
gdk_surface_is_toplevel_frozen (surface)))
return;
/* If there's no frame clock (a foreign surface), then the invalid
* region will just stick around unless gdk_surface_process_updates()
@@ -1401,6 +1400,7 @@ gdk_surface_paint_on_clock (GdkFrameClock *clock,
void *data)
{
GdkSurface *surface = GDK_SURFACE (data);
GList *l;
g_return_if_fail (GDK_IS_SURFACE (surface));
@@ -1421,6 +1421,9 @@ gdk_surface_paint_on_clock (GdkFrameClock *clock,
gdk_surface_remove_update_surface (surface);
}
for (l = surface->children; l; l = l->next)
gdk_surface_paint_on_clock (clock, l->data);
g_object_unref (surface);
}
@@ -1578,17 +1581,13 @@ gdk_surface_freeze_updates (GdkSurface *surface)
g_return_if_fail (GDK_IS_SURFACE (surface));
surface->update_freeze_count++;
if (surface->update_freeze_count == 1)
_gdk_frame_clock_uninhibit_freeze (surface->frame_clock);
}
/**
* gdk_surface_thaw_updates:
* @surface: a #GdkSurface
*
* Thaws a surface frozen with gdk_surface_freeze_updates(). Note that this
* will not necessarily schedule updates if the surface freeze count reaches
* zero.
* Thaws a surface frozen with gdk_surface_freeze_updates().
**/
void
gdk_surface_thaw_updates (GdkSurface *surface)
@@ -1598,15 +1597,7 @@ gdk_surface_thaw_updates (GdkSurface *surface)
g_return_if_fail (surface->update_freeze_count > 0);
if (--surface->update_freeze_count == 0)
{
_gdk_frame_clock_inhibit_freeze (surface->frame_clock);
if (surface->pending_schedule_update)
{
surface->pending_schedule_update = FALSE;
gdk_surface_schedule_update (surface);
}
}
gdk_surface_schedule_update (surface);
}
void
@@ -1615,7 +1606,7 @@ gdk_surface_freeze_toplevel_updates (GdkSurface *surface)
g_return_if_fail (GDK_IS_SURFACE (surface));
surface->update_and_descendants_freeze_count++;
gdk_surface_freeze_updates (surface);
_gdk_frame_clock_freeze (gdk_surface_get_frame_clock (surface));
}
void
@@ -1625,9 +1616,9 @@ gdk_surface_thaw_toplevel_updates (GdkSurface *surface)
g_return_if_fail (surface->update_and_descendants_freeze_count > 0);
surface->update_and_descendants_freeze_count--;
gdk_surface_schedule_update (surface);
gdk_surface_thaw_updates (surface);
_gdk_frame_clock_thaw (gdk_surface_get_frame_clock (surface));
gdk_surface_schedule_update (surface);
}
/**
@@ -2069,6 +2060,59 @@ G_GNUC_END_IGNORE_DEPRECATIONS
GDK_SURFACE_GET_CLASS (surface)->hide (surface);
}
static void
gdk_surface_move_resize_toplevel (GdkSurface *surface,
gboolean with_move,
gint x,
gint y,
gint width,
gint height)
{
GDK_SURFACE_GET_CLASS (surface)->move_resize (surface, with_move, x, y, width, height);
}
static void
gdk_surface_move_resize_internal (GdkSurface *surface,
gboolean with_move,
gint x,
gint y,
gint width,
gint height)
{
g_return_if_fail (GDK_IS_SURFACE (surface));
if (surface->destroyed)
return;
gdk_surface_move_resize_toplevel (surface, with_move, x, y, width, height);
}
/*
* gdk_surface_move:
* @surface: a #GdkSurface
* @x: X coordinate relative to surfaces parent
* @y: Y coordinate relative to surfaces parent
*
* Repositions a surface relative to its parent surface.
* For toplevel surfaces, window managers may ignore or modify the move;
* you should probably use gtk_window_move() on a #GtkWindow widget
* anyway, instead of using GDK functions. For child surfaces,
* the move will reliably succeed.
*
* If youre also planning to resize the surface, use gdk_surface_move_resize()
* to both move and resize simultaneously, for a nicer visual effect.
**/
void
gdk_surface_move (GdkSurface *surface,
gint x,
gint y)
{
gdk_surface_move_resize_internal (surface, TRUE, x, y, -1, -1);
}
/**
* gdk_surface_resize:
* @surface: a #GdkSurface
@@ -2086,7 +2130,31 @@ gdk_surface_resize (GdkSurface *surface,
gint width,
gint height)
{
GDK_SURFACE_GET_CLASS (surface)->toplevel_resize (surface, width, height);
gdk_surface_move_resize_internal (surface, FALSE, 0, 0, width, height);
}
/*
* gdk_surface_move_resize:
* @surface: a #GdkSurface
* @x: new X position relative to surfaces parent
* @y: new Y position relative to surfaces parent
* @width: new width
* @height: new height
*
* Equivalent to calling gdk_surface_move() and gdk_surface_resize(),
* except that both operations are performed at once, avoiding strange
* visual effects. (i.e. the user may be able to see the surface first
* move, then resize, if you dont use gdk_surface_move_resize().)
**/
void
gdk_surface_move_resize (GdkSurface *surface,
gint x,
gint y,
gint width,
gint height)
{
gdk_surface_move_resize_internal (surface, TRUE, x, y, width, height);
}
/**
@@ -2883,7 +2951,8 @@ gdk_surface_set_modal_hint (GdkSurface *surface,
* this is to constrain user resizing, but the windowing system
* will typically (but is not required to) also constrain the
* current size of the surface to the provided values and
* constrain programatic resizing via gdk_surface_resize().
* constrain programatic resizing via gdk_surface_resize() or
* gdk_surface_move_resize().
*
* Note that on X11, this effect has no effect on surfaces
* of type %GDK_SURFACE_TEMP since these surfaces are not resizable
@@ -3634,42 +3703,40 @@ gdk_surface_set_frame_clock (GdkSurface *surface,
if (clock)
{
g_object_ref (clock);
g_signal_connect (G_OBJECT (clock),
"flush-events",
G_CALLBACK (gdk_surface_flush_events),
surface);
g_signal_connect (G_OBJECT (clock),
"resume-events",
G_CALLBACK (gdk_surface_resume_events),
surface);
g_signal_connect (G_OBJECT (clock),
"paint",
G_CALLBACK (gdk_surface_paint_on_clock),
surface);
if (surface->update_freeze_count == 0)
_gdk_frame_clock_inhibit_freeze (clock);
if (surface->parent == NULL)
{
g_signal_connect (G_OBJECT (clock),
"flush-events",
G_CALLBACK (gdk_surface_flush_events),
surface);
g_signal_connect (G_OBJECT (clock),
"resume-events",
G_CALLBACK (gdk_surface_resume_events),
surface);
g_signal_connect (G_OBJECT (clock),
"paint",
G_CALLBACK (gdk_surface_paint_on_clock),
surface);
}
}
if (surface->frame_clock)
{
if (surface->frame_clock_events_paused)
gdk_surface_resume_events (surface->frame_clock, G_OBJECT (surface));
g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock),
G_CALLBACK (gdk_surface_flush_events),
surface);
g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock),
G_CALLBACK (gdk_surface_resume_events),
surface);
g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock),
G_CALLBACK (gdk_surface_paint_on_clock),
surface);
if (surface->update_freeze_count == 0)
_gdk_frame_clock_uninhibit_freeze (surface->frame_clock);
if (surface->parent == NULL)
{
if (surface->frame_clock_events_paused)
gdk_surface_resume_events (surface->frame_clock, G_OBJECT (surface));
g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock),
G_CALLBACK (gdk_surface_flush_events),
surface);
g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock),
G_CALLBACK (gdk_surface_resume_events),
surface);
g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock),
G_CALLBACK (gdk_surface_paint_on_clock),
surface);
}
g_object_unref (surface->frame_clock);
}
+4 -15
View File
@@ -49,7 +49,6 @@ struct _GdkSurface
cairo_region_t *update_area;
guint update_freeze_count;
gboolean pending_schedule_update;
/* This is the update_area that was in effect when the current expose
started. It may be smaller than the expose area if we'e painting
more than we have to, but it represents the "true" damage. */
@@ -113,7 +112,10 @@ struct _GdkSurfaceClass
GdkSurface *sibling,
gboolean above);
void (* toplevel_resize) (GdkSurface *surface,
void (* move_resize) (GdkSurface *surface,
gboolean with_move,
gint x,
gint y,
gint width,
gint height);
void (* move_to_rect) (GdkSurface *surface,
@@ -255,19 +257,6 @@ struct _GdkSurfaceClass
void gdk_surface_set_state (GdkSurface *surface,
GdkSurfaceState new_state);
typedef void (* GdkSurfaceMovedToRect) (GdkSurface *surface,
GdkRectangle final_rect);
void
gdk_surface_move_to_rect_helper (GdkSurface *surface,
const GdkRectangle *rect,
GdkGravity rect_anchor,
GdkGravity surface_anchor,
GdkAnchorHints anchor_hints,
gint rect_anchor_dx,
gint rect_anchor_dy,
GdkSurfaceMovedToRect moved_to_rect);
G_END_DECLS
#endif /* __GDK_SURFACE_PRIVATE_H__ */
+13 -51
View File
@@ -1237,61 +1237,24 @@ window_quartz_move_resize (GdkSurface *window,
}
static void
gdk_surface_quartz_toplevel_resize (GdkSurface *surface,
gint width,
gint height)
gdk_surface_quartz_move_resize (GdkSurface *window,
gboolean with_move,
gint x,
gint y,
gint width,
gint height)
{
window_quartz_resize (window, width, height);
}
static void
gdk_quartz_surface_moved_to_rect (GdkSurface *surface,
GdkRectangle final_rect)
{
GdkSurface *toplevel;
int x, y;
if (surface->surface_type == GDK_SURFACE_POPUP)
toplevel = surface->parent;
else
toplevel = surface->transient_for;
gdk_surface_get_origin (toplevel, &x, &y);
x += final_rect.x;
y += final_rect.y;
if (final_rect.width != surface->width ||
final_rect.height != surface->height)
{
window_quartz_move_resize (surface,
x, y,
final_rect.width, final_rect.height);
}
if (with_move && (width < 0 && height < 0))
window_quartz_move (window, x, y);
else
{
window_quartz_resize (surface, final_rect.width, final_rect.height);
if (with_move)
window_quartz_move_resize (window, x, y, width, height);
else
window_quartz_resize (window, width, height);
}
}
static void
gdk_quartz_surface_move_to_rect (GdkSurface *surface,
const GdkRectangle *rect,
GdkGravity rect_anchor,
GdkGravity surface_anchor,
GdkAnchorHints anchor_hints,
gint rect_anchor_dx,
gint rect_anchor_dy)
{
gdk_surface_move_to_rect_helper (surface,
rect,
rect_anchor,
surface_anchor,
anchor_hints,
rect_anchor_dx,
rect_anchor_dy,
gdk_quartz_surface_moved_to_rect);
}
/* Get the toplevel ordering from NSApp and update our own list. We do
* this on demand since the NSApps list is not up to date directly
* after we get windowDidBecomeMain.
@@ -2678,8 +2641,7 @@ gdk_surface_impl_quartz_class_init (GdkSurfaceImplQuartzClass *klass)
impl_class->raise = gdk_surface_quartz_raise;
impl_class->lower = gdk_surface_quartz_lower;
impl_class->restack_toplevel = gdk_surface_quartz_restack_toplevel;
impl_class->toplevel_resize = gdk_surface_quartz_toplevel_resize;
impl_class->move_to_rect = gdk_surface_quartz_move_to_rect;
impl_class->move_resize = gdk_surface_quartz_move_resize;
impl_class->get_geometry = gdk_surface_quartz_get_geometry;
impl_class->get_root_coords = gdk_surface_quartz_get_root_coords;
impl_class->get_device_state = gdk_surface_quartz_get_device_state;
+2 -10
View File
@@ -93,7 +93,6 @@
#define GTK_SHELL1_VERSION 2
#define OUTPUT_VERSION_WITH_DONE 2
#define NO_XDG_OUTPUT_DONE_SINCE_VERSION 3
static void _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *display_wayland);
@@ -532,7 +531,7 @@ gdk_registry_handle_global (void *data,
}
else if (strcmp(interface, "zxdg_output_manager_v1") == 0)
{
display_wayland->xdg_output_manager_version = MIN (version, 3);
display_wayland->xdg_output_manager_version = MIN (version, 2);
display_wayland->xdg_output_manager =
wl_registry_bind (display_wayland->wl_registry, id,
&zxdg_output_manager_v1_interface,
@@ -2218,9 +2217,6 @@ should_update_monitor (GdkWaylandMonitor *monitor)
static void
apply_monitor_change (GdkWaylandMonitor *monitor)
{
GdkDisplay *display = GDK_MONITOR (monitor)->display;
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
GDK_NOTE (MISC,
g_message ("monitor %d changed position %d %d, size %d %d",
monitor->id,
@@ -2231,11 +2227,7 @@ apply_monitor_change (GdkWaylandMonitor *monitor)
gdk_monitor_set_size (GDK_MONITOR (monitor), monitor->width, monitor->height);
gdk_monitor_set_connector (GDK_MONITOR (monitor), monitor->name);
monitor->wl_output_done = FALSE;
/* xdg_output v3 marks xdg_output.done as deprecated, so if using
* that version, no need to wait for xdg-output.done event.
*/
monitor->xdg_output_done =
(display_wayland->xdg_output_manager_version >= NO_XDG_OUTPUT_DONE_SINCE_VERSION);
monitor->xdg_output_done = FALSE;
update_scale (GDK_MONITOR (monitor)->display);
}
+101 -165
View File
@@ -150,20 +150,9 @@ struct _GdkWaylandSurface
} pending_move_to_rect;
struct {
struct {
int width;
int height;
GdkSurfaceState state;
} toplevel;
struct {
int x;
int y;
int width;
int height;
} popup;
uint32_t serial;
int width;
int height;
GdkSurfaceState state;
} pending;
struct {
@@ -181,12 +170,10 @@ struct _GdkWaylandSurfaceClass
GdkSurfaceClass parent_class;
};
static void gdk_wayland_surface_maybe_resize (GdkSurface *surface,
int width,
int height,
int scale);
static void gdk_wayland_surface_configure (GdkSurface *surface);
static void gdk_wayland_surface_maybe_configure (GdkSurface *surface,
int width,
int height,
int scale);
static void maybe_set_gtk_surface_dbus_properties (GdkSurface *surface);
static void maybe_set_gtk_surface_modal (GdkSurface *surface);
@@ -197,12 +184,6 @@ static void gdk_wayland_surface_sync_opaque_region (GdkSurface *surface);
static void unset_transient_for_exported (GdkSurface *surface);
static void gdk_wayland_surface_move_resize (GdkSurface *surface,
gint x,
gint y,
gint width,
gint height);
static void calculate_moved_to_rect_result (GdkSurface *surface,
int x,
int y,
@@ -368,7 +349,7 @@ frame_callback (void *data,
return;
impl->awaiting_frame = FALSE;
gdk_surface_thaw_updates (surface);
_gdk_frame_clock_thaw (clock);
timings = gdk_frame_clock_get_timings (clock, impl->pending_frame_counter);
impl->pending_frame_counter = 0;
@@ -484,9 +465,8 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
g_signal_emit (impl, signals[COMMITTED], 0);
}
if (impl->awaiting_frame &&
impl->pending_frame_counter == gdk_frame_clock_get_frame_counter (clock))
gdk_surface_freeze_updates (surface);
if (impl->awaiting_frame)
_gdk_frame_clock_freeze (clock);
}
void
@@ -511,9 +491,7 @@ gdk_wayland_surface_update_scale (GdkSurface *surface)
}
/* Notify app that scale changed */
gdk_wayland_surface_maybe_resize (surface,
surface->width, surface->height,
scale);
gdk_wayland_surface_maybe_configure (surface, surface->width, surface->height, scale);
}
static void gdk_wayland_surface_create_surface (GdkSurface *surface);
@@ -670,10 +648,10 @@ gdk_wayland_surface_finalize (GObject *object)
}
static void
gdk_wayland_surface_resize (GdkSurface *surface,
int width,
int height,
int scale)
gdk_wayland_surface_configure (GdkSurface *surface,
int width,
int height,
int scale)
{
GdkDisplay *display;
GdkEvent *event;
@@ -723,10 +701,10 @@ static void gdk_wayland_surface_show (GdkSurface *surface,
static void gdk_wayland_surface_hide (GdkSurface *surface);
static void
gdk_wayland_surface_maybe_resize (GdkSurface *surface,
int width,
int height,
int scale)
gdk_wayland_surface_maybe_configure (GdkSurface *surface,
int width,
int height,
int scale)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
gboolean is_xdg_popup;
@@ -749,7 +727,7 @@ gdk_wayland_surface_maybe_resize (GdkSurface *surface,
if (is_xdg_popup && is_visible && !impl->initial_configure_received)
gdk_wayland_surface_hide (surface);
gdk_wayland_surface_resize (surface, width, height, scale);
gdk_wayland_surface_configure (surface, width, height, scale);
if (is_xdg_popup && is_visible && !impl->initial_configure_received)
gdk_wayland_surface_show (surface, FALSE);
@@ -1060,27 +1038,44 @@ gdk_wayland_surface_create_surface (GdkSurface *surface)
}
static void
gdk_wayland_surface_configure_toplevel (GdkSurface *surface)
gdk_wayland_surface_handle_configure (GdkSurface *surface,
uint32_t serial)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkWaylandDisplay *display_wayland =
GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
GdkSurfaceState new_state;
int width, height;
int width = impl->pending.width;
int height = impl->pending.height;
gboolean fixed_size;
gboolean saved_size;
new_state = impl->pending.toplevel.state;
impl->pending.toplevel.state = 0;
if (!impl->initial_configure_received)
{
gdk_surface_thaw_updates (surface);
impl->initial_configure_received = TRUE;
}
if (impl->display_server.xdg_popup)
{
xdg_surface_ack_configure (impl->display_server.xdg_surface, serial);
return;
}
else if (impl->display_server.zxdg_popup_v6)
{
zxdg_surface_v6_ack_configure (impl->display_server.zxdg_surface_v6,
serial);
return;
}
new_state = impl->pending.state;
impl->pending.state = 0;
fixed_size =
new_state & (GDK_SURFACE_STATE_MAXIMIZED |
GDK_SURFACE_STATE_FULLSCREEN |
GDK_SURFACE_STATE_TILED);
width = impl->pending.toplevel.width;
height = impl->pending.toplevel.height;
saved_size = (width == 0 && height == 0);
/* According to xdg_shell, an xdg_surface.configure with size 0x0
* should be interpreted as that it is up to the client to set a
@@ -1117,7 +1112,7 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface)
_gdk_wayland_surface_save_size (surface);
}
gdk_wayland_surface_resize (surface, width, height, impl->scale);
gdk_wayland_surface_configure (surface, width, height, impl->scale);
}
GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS,
@@ -1133,12 +1128,11 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface)
switch (display_wayland->shell_variant)
{
case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL:
xdg_surface_ack_configure (impl->display_server.xdg_surface,
impl->pending.serial);
xdg_surface_ack_configure (impl->display_server.xdg_surface, serial);
break;
case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
zxdg_surface_v6_ack_configure (impl->display_server.zxdg_surface_v6,
impl->pending.serial);
serial);
break;
default:
g_assert_not_reached ();
@@ -1149,87 +1143,6 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface)
gdk_wayland_surface_update_dialogs (surface);
}
static void
gdk_wayland_surface_configure_popup (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
int x, y, width, height;
GdkRectangle flipped_rect;
GdkRectangle final_rect;
gboolean flipped_x;
gboolean flipped_y;
g_return_if_fail (impl->transient_for);
if (impl->display_server.xdg_popup)
{
xdg_surface_ack_configure (impl->display_server.xdg_surface,
impl->pending.serial);
}
else if (impl->display_server.zxdg_popup_v6)
{
zxdg_surface_v6_ack_configure (impl->display_server.zxdg_surface_v6,
impl->pending.serial);
}
if (impl->position_method != POSITION_METHOD_MOVE_TO_RECT)
return;
x = impl->pending.popup.x;
y = impl->pending.popup.y;
width = impl->pending.popup.width;
height = impl->pending.popup.height;
gdk_wayland_surface_resize (surface, width, height, impl->scale);
calculate_moved_to_rect_result (surface,
x, y,
width, height,
&flipped_rect,
&final_rect,
&flipped_x,
&flipped_y);
impl->position_method = POSITION_METHOD_MOVE_TO_RECT;
g_signal_emit_by_name (surface,
"moved-to-rect",
&flipped_rect,
&final_rect,
flipped_x,
flipped_y);
}
static void
gdk_wayland_surface_configure (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
if (!impl->initial_configure_received)
{
gdk_surface_thaw_updates (surface);
impl->initial_configure_received = TRUE;
}
if (is_realized_popup (surface))
gdk_wayland_surface_configure_popup (surface);
else if (is_realized_toplevel (surface))
gdk_wayland_surface_configure_toplevel (surface);
else
g_warn_if_reached ();
}
static void
gdk_wayland_surface_handle_configure (GdkSurface *surface,
uint32_t serial)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
impl->pending.serial = serial;
gdk_wayland_surface_configure (surface);
}
static void
gdk_wayland_surface_handle_configure_toplevel (GdkSurface *surface,
int32_t width,
@@ -1238,9 +1151,9 @@ gdk_wayland_surface_handle_configure_toplevel (GdkSurface *surface,
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
impl->pending.toplevel.state |= state;
impl->pending.toplevel.width = width;
impl->pending.toplevel.height = height;
impl->pending.state |= state;
impl->pending.width = width;
impl->pending.height = height;
}
static void
@@ -1519,11 +1432,30 @@ gdk_wayland_surface_handle_configure_popup (GdkSurface *surface,
int32_t height)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkRectangle flipped_rect;
GdkRectangle final_rect;
gboolean flipped_x;
gboolean flipped_y;
impl->pending.popup.x = x;
impl->pending.popup.y = y;
impl->pending.popup.width = width;
impl->pending.popup.height = height;
g_return_if_fail (impl->transient_for);
if (impl->position_method != POSITION_METHOD_MOVE_TO_RECT)
return;
calculate_moved_to_rect_result (surface, x, y, width, height,
&flipped_rect,
&final_rect,
&flipped_x,
&flipped_y);
impl->position_method = POSITION_METHOD_MOVE_TO_RECT;
g_signal_emit_by_name (surface,
"moved-to-rect",
&flipped_rect,
&final_rect,
flipped_x,
flipped_y);
}
static void
@@ -1969,9 +1901,9 @@ calculate_moved_to_rect_result (GdkSurface *surface,
surface_width = width + surface->shadow_left + surface->shadow_right;
surface_height = height + surface->shadow_top + surface->shadow_bottom;
gdk_wayland_surface_move_resize (surface,
surface_x, surface_y,
surface_width, surface_height);
gdk_surface_move_resize (surface,
surface_x, surface_y,
surface_width, surface_height);
calculate_popup_rect (surface,
impl->pending_move_to_rect.rect_anchor,
@@ -2645,8 +2577,12 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
if (impl->awaiting_frame)
{
GdkFrameClock *frame_clock;
impl->awaiting_frame = FALSE;
gdk_surface_thaw_updates (surface);
frame_clock = gdk_surface_get_frame_clock (surface);
if (frame_clock)
_gdk_frame_clock_thaw (frame_clock);
}
if (impl->display_server.gtk_surface)
@@ -2714,6 +2650,7 @@ gdk_wayland_surface_restack_toplevel (GdkSurface *surface,
static void
gdk_wayland_surface_move_resize (GdkSurface *surface,
gboolean with_move,
gint x,
gint y,
gint width,
@@ -2721,21 +2658,22 @@ gdk_wayland_surface_move_resize (GdkSurface *surface,
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
surface->x = x;
surface->y = y;
gdk_wayland_surface_maybe_resize (surface, width, height, impl->scale);
}
if (with_move)
{
/* Each toplevel has in its own "root" coordinate system */
if (GDK_SURFACE_TYPE (surface) != GDK_SURFACE_TOPLEVEL)
{
surface->x = x;
surface->y = y;
impl->position_method = POSITION_METHOD_MOVE_RESIZE;
}
}
static void
gdk_wayland_surface_toplevel_resize (GdkSurface *surface,
gint width,
gint height)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
gdk_wayland_surface_maybe_resize (surface,
width, height,
impl->scale);
/* If this function is called with width and height = -1 then that means
* just move the surface - don't update its size
*/
if (width > 0 && height > 0)
gdk_wayland_surface_maybe_configure (surface, width, height, impl->scale);
}
/* Avoid zero width/height as this is a protocol error */
@@ -2989,7 +2927,7 @@ gtk_surface_configure (void *data,
}
}
impl->pending.toplevel.state |= new_state;
impl->pending.state |= new_state;
}
static void
@@ -3026,7 +2964,7 @@ gtk_surface_configure_edges (void *data,
}
}
impl->pending.toplevel.state |= new_state;
impl->pending.state |= new_state;
}
static const struct gtk_surface1_listener gtk_surface_listener = {
@@ -3728,9 +3666,7 @@ gdk_wayland_surface_set_shadow_width (GdkSurface *surface,
(impl->margin_left + impl->margin_right) + (left + right);
new_height = surface->height -
(impl->margin_top + impl->margin_bottom) + (top + bottom);
gdk_wayland_surface_maybe_resize (surface,
new_width, new_height,
impl->scale);
gdk_wayland_surface_maybe_configure (surface, new_width, new_height, impl->scale);
impl->margin_left = left;
impl->margin_right = right;
@@ -3813,7 +3749,7 @@ gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass)
impl_class->raise = gdk_wayland_surface_raise;
impl_class->lower = gdk_wayland_surface_lower;
impl_class->restack_toplevel = gdk_wayland_surface_restack_toplevel;
impl_class->toplevel_resize = gdk_wayland_surface_toplevel_resize;
impl_class->move_resize = gdk_wayland_surface_move_resize;
impl_class->move_to_rect = gdk_wayland_surface_move_to_rect;
impl_class->get_geometry = gdk_wayland_surface_get_geometry;
impl_class->get_root_coords = gdk_wayland_surface_get_root_coords;
+6 -11
View File
@@ -736,9 +736,9 @@ move_drag_surface (GdkDrag *drag,
g_assert (_win32_main_thread == NULL ||
_win32_main_thread == g_thread_self ());
gdk_win32_surface_move (drag_win32->drag_surface,
x_root - drag_win32->hot_x,
y_root - drag_win32->hot_y);
gdk_surface_move (drag_win32->drag_surface,
x_root - drag_win32->hot_x,
y_root - drag_win32->hot_y);
gdk_surface_raise (drag_win32->drag_surface);
}
@@ -2090,7 +2090,6 @@ gdk_drag_anim_timeout (gpointer data)
gint64 current_time;
double f;
double t;
gint x, y;
if (!frame_clock)
return G_SOURCE_REMOVE;
@@ -2105,13 +2104,9 @@ gdk_drag_anim_timeout (gpointer data)
t = ease_out_cubic (f);
gdk_surface_show (drag->drag_surface);
x = (drag->util_data.last_x +
(drag->start_x - drag->util_data.last_x) * t -
drag->hot_x);
y = (drag->util_data.last_y +
(drag->start_y - drag->util_data.last_y) * t -
drag->hot_y);
gdk_win32_surface_move (drag->drag_surface, x, y);
gdk_surface_move (drag->drag_surface,
drag->util_data.last_x + (drag->start_x - drag->util_data.last_x) * t - drag->hot_x,
drag->util_data.last_y + (drag->start_y - drag->util_data.last_y) * t - drag->hot_y);
gdk_surface_set_opacity (drag->drag_surface, 1.0 - f);
return G_SOURCE_CONTINUE;
+1 -3
View File
@@ -1588,9 +1588,7 @@ handle_dpi_changed (GdkSurface *window,
_gdk_win32_adjust_client_rect (window, rect);
if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE)
gdk_win32_surface_move_resize (window,
window->x, window->y,
window->width, window->height);
gdk_surface_move_resize (window, window->x, window->y, window->width, window->height);
else
gdk_surface_resize (window, window->width, window->height);
}
+1 -1
View File
@@ -749,7 +749,7 @@ update_keymap (GdkKeymap *gdk_keymap)
/* First, handle those virtual keys that we always want
* as special GDK_* keysyms, even if ToAsciiEx might
* turn some them into an ASCII character (like TAB and
* turn some them into a ASCII character (like TAB and
* ESC).
*/
handle_special (vk, ksymp, level);
+25 -104
View File
@@ -824,7 +824,7 @@ show_window_internal (GdkSurface *window,
_gdk_win32_surface_state_to_string (window->state),
(deiconify ? " deiconify" : "")));
/* If asked to show (not deiconify) a withdrawn and iconified
/* If asked to show (not deiconify) an withdrawn and iconified
* window, do that.
*/
if (!deiconify &&
@@ -1098,8 +1098,8 @@ gdk_win32_surface_withdraw (GdkSurface *window)
}
static void
gdk_win32_surface_do_move (GdkSurface *window,
gint x, gint y)
gdk_win32_surface_move (GdkSurface *window,
gint x, gint y)
{
RECT outer_rect;
GdkWin32Surface *impl;
@@ -1174,11 +1174,11 @@ gdk_win32_surface_resize (GdkSurface *window,
}
static void
gdk_win32_surface_do_move_resize (GdkSurface *window,
gint x,
gint y,
gint width,
gint height)
gdk_win32_surface_move_resize_internal (GdkSurface *window,
gint x,
gint y,
gint width,
gint height)
{
RECT outer_rect;
GdkWin32Surface *impl;
@@ -1224,12 +1224,12 @@ gdk_win32_surface_do_move_resize (GdkSurface *window,
}
static void
gdk_win32_surface_move_resize_internal (GdkSurface *window,
gboolean with_move,
gint x,
gint y,
gint width,
gint height)
gdk_win32_surface_move_resize (GdkSurface *window,
gboolean with_move,
gint x,
gint y,
gint width,
gint height)
{
GdkWin32Surface *surface = GDK_WIN32_SURFACE (window);
@@ -1242,13 +1242,13 @@ gdk_win32_surface_move_resize_internal (GdkSurface *window,
if (with_move && (width < 0 && height < 0))
{
gdk_win32_surface_do_move (window, x, y);
gdk_win32_surface_move (window, x, y);
}
else
{
if (with_move)
{
gdk_win32_surface_do_move_resize (window, x, y, width, height);
gdk_win32_surface_move_resize_internal (window, x, y, width, height);
}
else
{
@@ -1262,80 +1262,6 @@ gdk_win32_surface_move_resize_internal (GdkSurface *window,
_gdk_win32_emit_configure_event (window);
}
void
gdk_win32_surface_move_resize (GdkSurface *window,
gint x,
gint y,
gint width,
gint height)
{
gdk_win32_surface_move_resize_internal (window, TRUE, x, y, width, height);
}
static void
gdk_win32_surface_toplevel_resize (GdkSurface *surface,
gint width,
gint height)
{
gdk_win32_surface_move_resize_internal (surface, FALSE, 0, 0, width, height);
}
void
gdk_win32_surface_move (GdkSurface *surface,
gint x,
gint y)
{
gdk_win32_surface_move_resize_internal (surface, TRUE, x, y, -1, -1);
}
static void
gdk_win32_surface_moved_to_rect (GdkSurface *surface,
GdkRectangle final_rect)
{
GdkSurface *toplevel;
int x, y;
if (surface->surface_type == GDK_SURFACE_POPUP)
toplevel = surface->parent;
else
toplevel = surface->transient_for;
gdk_surface_get_origin (toplevel, &x, &y);
x += final_rect.x;
y += final_rect.y;
if (final_rect.width != surface->width ||
final_rect.height != surface->height)
{
gdk_win32_surface_move_resize (surface,
x, y,
final_rect.width, final_rect.height);
}
else
{
gdk_win32_surface_move (surface, x, y);
}
}
static void
gdk_win32_surface_move_to_rect (GdkSurface *surface,
const GdkRectangle *rect,
GdkGravity rect_anchor,
GdkGravity surface_anchor,
GdkAnchorHints anchor_hints,
gint rect_anchor_dx,
gint rect_anchor_dy)
{
gdk_surface_move_to_rect_helper (surface,
rect,
rect_anchor,
surface_anchor,
anchor_hints,
rect_anchor_dx,
rect_anchor_dy,
gdk_win32_surface_moved_to_rect);
}
static void
gdk_win32_surface_raise (GdkSurface *window)
{
@@ -1962,7 +1888,7 @@ gdk_win32_surface_set_icon_name (GdkSurface *window,
{
/* In case I manage to confuse this again (or somebody else does):
* Please note that "icon name" here really *does* mean the name or
* title of a window minimized as an icon on the desktop, or in the
* title of an window minimized as an icon on the desktop, or in the
* taskbar. It has nothing to do with the freedesktop.org icon
* naming stuff.
*/
@@ -2592,8 +2518,8 @@ unsnap (GdkSurface *window,
GDK_NOTE (MISC, g_print ("Unsnapped window size %d x %d @ %d : %d\n", rect.width, rect.height, rect.x, rect.y));
gdk_win32_surface_move_resize (window, rect.x, rect.y,
rect.width, rect.height);
gdk_surface_move_resize (window, rect.x, rect.y,
rect.width, rect.height);
g_clear_pointer (&impl->snap_stash, g_free);
g_clear_pointer (&impl->snap_stash_int, g_free);
@@ -2698,7 +2624,7 @@ snap_up (GdkSurface *window)
width += impl->margins_x;
height += impl->margins_y;
gdk_win32_surface_move_resize (window, x, y, width, height);
gdk_surface_move_resize (window, x, y, width, height);
}
static void
@@ -2724,9 +2650,7 @@ snap_left (GdkSurface *window,
rect.width = rect.width + impl->margins_x;
rect.height = rect.height + impl->margins_y;
gdk_win32_surface_move_resize (window,
rect.x, rect.y,
rect.width, rect.height);
gdk_surface_move_resize (window, rect.x, rect.y, rect.width, rect.height);
}
static void
@@ -2753,9 +2677,7 @@ snap_right (GdkSurface *window,
rect.width = rect.width + impl->margins_x;
rect.height = rect.height + impl->margins_y;
gdk_win32_surface_move_resize (window,
rect.x, rect.y,
rect.width, rect.height);
gdk_surface_move_resize (window, rect.x, rect.y, rect.width, rect.height);
}
void
@@ -4006,8 +3928,8 @@ setup_drag_move_resize_context (GdkSurface *window,
GDK_NOTE (MISC, g_print ("Unsnapped window to %d : %d\n",
new_pos.x, new_pos.y));
discard_snapinfo (window);
gdk_win32_surface_move_resize (window, new_pos.x, new_pos.y,
new_pos.width, new_pos.height);
gdk_surface_move_resize (window, new_pos.x, new_pos.y,
new_pos.width, new_pos.height);
}
@@ -5160,8 +5082,7 @@ gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
impl_class->raise = gdk_win32_surface_raise;
impl_class->lower = gdk_win32_surface_lower;
impl_class->restack_toplevel = gdk_win32_surface_restack_toplevel;
impl_class->toplevel_resize = gdk_win32_surface_toplevel_resize;
impl_class->move_to_rect = gdk_win32_surface_move_to_rect;
impl_class->move_resize = gdk_win32_surface_move_resize;
impl_class->get_geometry = gdk_win32_surface_get_geometry;
impl_class->get_device_state = gdk_surface_win32_get_device_state;
impl_class->get_root_coords = gdk_win32_surface_get_root_coords;
+1 -10
View File
@@ -180,7 +180,7 @@ struct _GdkW32DragMoveResizeContext
*
* For drag-move: If it's FALSE,
* then the pointer have not yet hit a trigger, even if it is
* already within an edge region.
* already within a edge region.
* If it's TRUE, then the pointer did hit a trigger within an
* edge region, and have not yet left an edge region
* (passing from one edge region into another doesn't count).
@@ -361,15 +361,6 @@ void _gdk_win32_update_layered_window_from_cache (GdkSurface *window,
gboolean do_resize,
gboolean do_paint);
void gdk_win32_surface_move (GdkSurface *surface,
gint x,
gint y);
void gdk_win32_surface_move_resize (GdkSurface *window,
gint x,
gint y,
gint width,
gint height);
void
gdk_win32_surface_get_queued_window_rect (GdkSurface *surface,
+2 -2
View File
@@ -289,7 +289,7 @@ gdk_x11_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
files_count = g_list_length (files);
if (files_count == 0)
{
description = g_strdup_printf (_("Starting %s"), g_app_info_get_name (info));
description = g_strdup_printf (_("Starting %s"), g_app_info_get_name (info));
}
else if (files_count == 1)
{
@@ -302,7 +302,7 @@ gdk_x11_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
0, NULL, NULL);
display_name = get_display_name (files->data, fileinfo);
description = g_strdup_printf (_("Opening %s"), display_name);
description = g_strdup_printf (_("Opening %s"), display_name);
g_free (display_name);
}
else
+4
View File
@@ -47,6 +47,10 @@ in this Software without prior written authorization from The Open Group.
#include "gdkprivate-x11.h"
#include "gdkdisplay-x11.h"
#ifdef NEED_XIPROTO_H_FOR_XREPLY
#include <X11/extensions/XIproto.h>
#endif
#include <X11/Xlibint.h>
+1 -1
View File
@@ -1363,7 +1363,7 @@ scroll_valuators_changed (GdkX11DeviceXI2 *device,
}
/* We only care about focus events that indicate that _this_
* surface (not an ancestor or child) got or lost the focus
* surface (not a ancestor or child) got or lost the focus
*/
static void
_gdk_device_manager_xi2_handle_focus (GdkSurface *surface,
+2 -2
View File
@@ -874,7 +874,7 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
surface_impl->toplevel->frame_pending)
{
surface_impl->toplevel->frame_pending = FALSE;
gdk_surface_thaw_updates (event->any.surface);
_gdk_frame_clock_thaw (gdk_surface_get_frame_clock (event->any.surface));
}
if (toplevel)
@@ -1238,7 +1238,7 @@ _gdk_wm_protocols_filter (const XEvent *xevent,
if (surface_impl->toplevel->frame_pending)
{
surface_impl->toplevel->frame_pending = FALSE;
gdk_surface_thaw_updates (event->any.surface);
_gdk_frame_clock_thaw (clock);
}
gdk_frame_clock_get_refresh_info (clock,
+6 -6
View File
@@ -1459,9 +1459,9 @@ move_drag_surface (GdkDrag *drag,
{
GdkX11Drag *drag_x11 = GDK_X11_DRAG (drag);
gdk_x11_surface_move (drag_x11->drag_surface,
x_root - drag_x11->hot_x,
y_root - drag_x11->hot_y);
gdk_surface_move (drag_x11->drag_surface,
x_root - drag_x11->hot_x,
y_root - drag_x11->hot_y);
gdk_surface_raise (drag_x11->drag_surface);
}
@@ -1841,9 +1841,9 @@ gdk_drag_anim_timeout (gpointer data)
t = ease_out_cubic (f);
gdk_surface_show (drag->drag_surface);
gdk_x11_surface_move (drag->drag_surface,
drag->last_x + (drag->start_x - drag->last_x) * t,
drag->last_y + (drag->start_y - drag->last_y) * t);
gdk_surface_move (drag->drag_surface,
drag->last_x + (drag->start_x - drag->last_x) * t,
drag->last_y + (drag->start_y - drag->last_y) * t);
gdk_surface_set_opacity (drag->drag_surface, 1.0 - f);
return G_SOURCE_CONTINUE;
+1 -1
View File
@@ -676,7 +676,7 @@ gdk_x11_gl_context_realize (GdkGLContext *context,
/* Ensure that any other context is created with a legacy bit set */
gdk_gl_context_set_is_legacy (context, legacy_bit);
/* Ensure that any other context is created with an ES bit set */
/* Ensure that any other context is created with a ES bit set */
gdk_gl_context_set_use_es (context, es_bit);
xvisinfo = find_xvisinfo_for_fbconfig (display, context_x11->glx_config);
-47
View File
@@ -354,7 +354,6 @@ init_randr15 (GdkX11Screen *x11_screen, gboolean *changed)
GdkRectangle geometry;
GdkRectangle newgeo;
char *name;
char *manufacturer = NULL;
int refresh_rate = 0;
gdk_x11_display_error_trap_push (display);
@@ -406,50 +405,6 @@ init_randr15 (GdkX11Screen *x11_screen, gboolean *changed)
g_ptr_array_add (x11_display->monitors, monitor);
}
/* Fetch minimal manufacturer information (PNP ID) from EDID */
{
#define EDID_LENGTH 128
Atom actual_type, edid_atom;
char tmp[3];
int actual_format;
unsigned char *prop;
unsigned long nbytes, bytes_left;
Display *disp = GDK_DISPLAY_XDISPLAY (x11_display);
edid_atom = XInternAtom (disp, RR_PROPERTY_RANDR_EDID, FALSE);
XRRGetOutputProperty (disp, output,
edid_atom,
0,
EDID_LENGTH,
FALSE,
FALSE,
AnyPropertyType,
&actual_type,
&actual_format,
&nbytes,
&bytes_left,
&prop);
// Check partial EDID header (whole header: 00 ff ff ff ff ff ff 00)
if (nbytes >= EDID_LENGTH && prop[0] == 0x00 && prop[1] == 0xff)
{
/* decode the Vendor ID from three 5 bit words packed into 2 bytes
* /--08--\/--09--\
* 7654321076543210
* |\---/\---/\---/
* R C1 C2 C3 */
tmp[0] = 'A' + ((prop[8] & 0x7c) / 4) - 1;
tmp[1] = 'A' + ((prop[8] & 0x3) * 8) + ((prop[9] & 0xe0) / 32) - 1;
tmp[2] = 'A' + (prop[9] & 0x1f) - 1;
manufacturer = g_strndup (tmp, sizeof (tmp));
}
XFree(prop);
#undef EDID_LENGTH
}
gdk_monitor_get_geometry (GDK_MONITOR (monitor), &geometry);
name = g_strndup (output_info->name, output_info->nameLen);
@@ -478,8 +433,6 @@ init_randr15 (GdkX11Screen *x11_screen, gboolean *changed)
gdk_monitor_set_scale_factor (GDK_MONITOR (monitor), x11_screen->surface_scale);
gdk_monitor_set_model (GDK_MONITOR (monitor), name);
gdk_monitor_set_connector (GDK_MONITOR (monitor), name);
gdk_monitor_set_manufacturer (GDK_MONITOR (monitor), manufacturer);
g_free (manufacturer);
g_free (name);
if (rr_monitors[i].primary)
+1 -2
View File
@@ -503,7 +503,6 @@ gdk_x11_selection_output_stream_invoke_close (gpointer stream)
g_signal_handlers_disconnect_by_func (priv->display,
gdk_x11_selection_output_stream_xevent,
stream);
g_object_unref (stream);
return G_SOURCE_REMOVE;
}
@@ -513,7 +512,7 @@ gdk_x11_selection_output_stream_close (GOutputStream *stream,
GCancellable *cancellable,
GError **error)
{
g_main_context_invoke (NULL, gdk_x11_selection_output_stream_invoke_close, g_object_ref (stream));
g_main_context_invoke (NULL, gdk_x11_selection_output_stream_invoke_close, stream);
return TRUE;
}
+5 -72
View File
@@ -397,7 +397,7 @@ gdk_x11_surface_end_frame (GdkSurface *surface)
g_intern_static_string ("_NET_WM_FRAME_DRAWN")))
{
impl->toplevel->frame_pending = TRUE;
gdk_surface_freeze_updates (surface);
_gdk_frame_clock_freeze (gdk_surface_get_frame_clock (surface));
timings->cookie = impl->toplevel->current_counter_value;
}
}
@@ -1392,71 +1392,6 @@ gdk_x11_surface_move_resize (GdkSurface *surface,
}
}
static void
gdk_x11_surface_toplevel_resize (GdkSurface *surface,
gint width,
gint height)
{
x11_surface_resize (surface, width, height);
}
void
gdk_x11_surface_move (GdkSurface *surface,
gint x,
gint y)
{
gdk_x11_surface_move_resize (surface, TRUE, x, y, -1, -1);
}
static void
gdk_x11_surface_moved_to_rect (GdkSurface *surface,
GdkRectangle final_rect)
{
GdkSurface *toplevel;
int x, y;
if (surface->surface_type == GDK_SURFACE_POPUP)
toplevel = surface->parent;
else
toplevel = surface->transient_for;
gdk_surface_get_origin (toplevel, &x, &y);
x += final_rect.x;
y += final_rect.y;
if (final_rect.width != surface->width ||
final_rect.height != surface->height)
{
gdk_x11_surface_move_resize (surface,
TRUE,
x, y,
final_rect.width, final_rect.height);
}
else
{
gdk_x11_surface_move (surface, x, y);
}
}
static void
gdk_x11_surface_move_to_rect (GdkSurface *surface,
const GdkRectangle *rect,
GdkGravity rect_anchor,
GdkGravity surface_anchor,
GdkAnchorHints anchor_hints,
gint rect_anchor_dx,
gint rect_anchor_dy)
{
gdk_surface_move_to_rect_helper (surface,
rect,
rect_anchor,
surface_anchor,
anchor_hints,
rect_anchor_dx,
rect_anchor_dy,
gdk_x11_surface_moved_to_rect);
}
static void gdk_x11_surface_restack_toplevel (GdkSurface *surface,
GdkSurface *sibling,
gboolean above);
@@ -3310,7 +3245,7 @@ gdk_x11_surface_fullscreen_on_monitor (GdkSurface *surface,
return;
gdk_monitor_get_geometry (monitor, &geom);
gdk_x11_surface_move (surface, geom.x, geom.y);
gdk_surface_move (surface, geom.x, geom.y);
gdk_surface_set_fullscreen_mode (surface, GDK_FULLSCREEN_ON_CURRENT_MONITOR);
gdk_x11_surface_fullscreen (surface);
@@ -3952,8 +3887,7 @@ update_pos (MoveResizeData *mv_resize,
w, h, &w, &h);
}
gdk_x11_surface_move_resize (mv_resize->moveresize_surface, TRUE,
x, y, w, h);
gdk_surface_move_resize (mv_resize->moveresize_surface, x, y, w, h);
}
else
{
@@ -3962,7 +3896,7 @@ update_pos (MoveResizeData *mv_resize,
x = mv_resize->moveresize_orig_x + dx;
y = mv_resize->moveresize_orig_y + dy;
gdk_x11_surface_move (mv_resize->moveresize_surface, x, y);
gdk_surface_move (mv_resize->moveresize_surface, x, y);
}
}
@@ -4655,8 +4589,7 @@ gdk_x11_surface_class_init (GdkX11SurfaceClass *klass)
impl_class->raise = gdk_x11_surface_raise;
impl_class->lower = gdk_x11_surface_lower;
impl_class->restack_toplevel = gdk_x11_surface_restack_toplevel;
impl_class->toplevel_resize = gdk_x11_surface_toplevel_resize;
impl_class->move_to_rect = gdk_x11_surface_move_to_rect;
impl_class->move_resize = gdk_x11_surface_move_resize;
impl_class->get_geometry = gdk_x11_surface_get_geometry;
impl_class->get_root_coords = gdk_x11_surface_get_root_coords;
impl_class->get_device_state = gdk_x11_surface_get_device_state;
-4
View File
@@ -183,10 +183,6 @@ void _gdk_x11_surface_set_surface_scale (GdkSurface *window,
void gdk_x11_surface_pre_damage (GdkSurface *surface);
void gdk_x11_surface_move (GdkSurface *surface,
gint x,
gint y);
G_END_DECLS
#endif /* __GDK_X11_SURFACE__ */
+78 -68
View File
@@ -24,7 +24,6 @@
*/
#define MAX_FRAME_AGE (5 * 60)
#define MAX_GLYPH_SIZE 128 /* Will get its own texture if bigger */
static guint glyph_cache_hash (gconstpointer v);
static gboolean glyph_cache_equal (gconstpointer v1,
@@ -83,8 +82,6 @@ glyph_cache_equal (gconstpointer v1, gconstpointer v2)
return key1->font == key2->font &&
key1->glyph == key2->glyph &&
key1->xshift == key2->xshift &&
key1->yshift == key2->yshift &&
key1->scale == key2->scale;
}
@@ -93,11 +90,7 @@ glyph_cache_hash (gconstpointer v)
{
const GlyphCacheKey *key = v;
return GPOINTER_TO_UINT (key->font) ^
key->glyph ^
(key->xshift << 24) ^
(key->yshift << 26) ^
key->scale;
return GPOINTER_TO_UINT (key->font) ^ key->glyph ^ key->scale;
}
static void
@@ -200,10 +193,10 @@ upload_glyph (GlyphCacheKey *key,
if (render_glyph (key, value, &r))
{
glBindTexture (GL_TEXTURE_2D, value->texture_id);
glTexSubImage2D (GL_TEXTURE_2D, 0,
r.x, r.y, r.width, r.height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
r.data);
glTextureSubImage2D (value->texture_id, 0,
r.x, r.y, r.width, r.height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
r.data);
g_free (r.data);
}
@@ -213,70 +206,86 @@ upload_glyph (GlyphCacheKey *key,
static void
add_to_cache (GskGLGlyphCache *self,
GlyphCacheKey *key,
GskGLDriver *driver,
GskGLCachedGlyph *value)
{
const int width = value->draw_width * key->scale / 1024;
const int height = value->draw_height * key->scale / 1024;
GskGLTextureAtlas *atlas = NULL;
int packed_x = 0;
int packed_y = 0;
if (width < MAX_GLYPH_SIZE && height < MAX_GLYPH_SIZE)
{
GskGLTextureAtlas *atlas = NULL;
int packed_x = 0;
int packed_y = 0;
gsk_gl_texture_atlases_pack (self->atlases, width + 2, height + 2, &atlas, &packed_x, &packed_y);
gsk_gl_texture_atlases_pack (self->atlases, width + 2, height + 2, &atlas, &packed_x, &packed_y);
value->tx = (float)(packed_x + 1) / atlas->width;
value->ty = (float)(packed_y + 1) / atlas->height;
value->tw = (float)width / atlas->width;
value->th = (float)height / atlas->height;
value->used = TRUE;
value->tx = (float)(packed_x + 1) / atlas->width;
value->ty = (float)(packed_y + 1) / atlas->height;
value->tw = (float)width / atlas->width;
value->th = (float)height / atlas->height;
value->used = TRUE;
value->atlas = atlas;
value->texture_id = atlas->texture_id;
}
else
{
value->atlas = NULL;
value->texture_id = gsk_gl_driver_create_texture (driver, width, height);
gsk_gl_driver_bind_source_texture (driver, value->texture_id);
gsk_gl_driver_init_texture_empty (driver, value->texture_id, GL_LINEAR, GL_LINEAR);
value->tx = 0.0f;
value->ty = 0.0f;
value->tw = 1.0f;
value->th = 1.0f;
}
value->atlas = atlas;
value->texture_id = atlas->texture_id;
upload_glyph (key, value);
}
#define PHASE(x) ((int)(floor (4 * (x + 0.125)) - 4 * floor (x + 0.125)))
void
gsk_gl_glyph_cache_get_texture (GskGLDriver *driver,
PangoFont *font,
PangoGlyph glyph,
float scale,
GskGLCachedGlyph *value)
{
PangoRectangle ink_rect;
GlyphCacheKey key;
int width, height;
guint texture_id;
pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
pango_extents_to_pixels (&ink_rect, NULL);
key.font = font;
key.glyph = glyph;
key.scale = (guint)(scale * 1024);
value->atlas = NULL;
value->timestamp = 0;
value->draw_x = ink_rect.x;
value->draw_y = ink_rect.y;
value->draw_width = ink_rect.width;
value->draw_height = ink_rect.height;
value->tx = 0.0f;
value->ty = 0.0f;
value->tw = 1.0f;
value->th = 1.0f;
width = value->draw_width * key.scale / 1024;
height = value->draw_height * key.scale / 1024;
texture_id = gsk_gl_driver_create_texture (driver, width, height);
gsk_gl_driver_bind_source_texture (driver, texture_id);
gsk_gl_driver_init_texture_empty (driver, texture_id, GL_NEAREST, GL_NEAREST);
value->texture_id = texture_id;
upload_glyph (&key, value);
}
gboolean
gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
PangoFont *font,
PangoGlyph glyph,
float x,
float y,
float scale,
GskGLDriver *driver,
GskGLCachedGlyph *cached_glyph_out)
{
GskGLCachedGlyph *value;
guint xshift = PHASE (x);
guint yshift = PHASE (y);
const guint key_scale = (guint)(scale * 1024);
value = g_hash_table_lookup (cache->hash_table,
&(GlyphCacheKey) {
.font = font,
.glyph = glyph,
.xshift = xshift,
.yshift = yshift,
.scale = key_scale
.scale = (guint)(scale * 1024)
});
if (value)
@@ -301,15 +310,10 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
if (value == NULL)
{
GlyphCacheKey *key;
PangoRectangle ink_rect;
pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
pango_extents_to_pixels (&ink_rect, NULL);
if (xshift != 0)
ink_rect.width += 1;
if (yshift != 0)
ink_rect.height += 1;
value = g_new0 (GskGLCachedGlyph, 1);
@@ -320,21 +324,27 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
value->timestamp = cache->timestamp;
value->atlas = NULL; /* For now */
key = g_new0 (GlyphCacheKey, 1);
if (ink_rect.width < 128 && ink_rect.height < 128)
{
GlyphCacheKey *key;
key->font = g_object_ref (font);
key->glyph = glyph;
key->xshift = xshift;
key->yshift = yshift;
key->scale = key_scale;
key = g_new0 (GlyphCacheKey, 1);
if (key->scale > 0 &&
value->draw_width * key->scale / 1024 > 0 &&
value->draw_height * key->scale / 1024 > 0)
add_to_cache (cache, key, driver, value);
key->font = g_object_ref (font);
key->glyph = glyph;
key->scale = (guint)(scale * 1024);
*cached_glyph_out = *value;
g_hash_table_insert (cache->hash_table, key, value);
if (ink_rect.width > 0 && ink_rect.height > 0 && key->scale > 0)
add_to_cache (cache, key, value);
*cached_glyph_out = *value;
g_hash_table_insert (cache->hash_table, key, value);
}
else
{
*cached_glyph_out = *value;
glyph_cache_value_free (value);
}
}
else
{
+6 -6
View File
@@ -22,8 +22,6 @@ typedef struct
{
PangoFont *font;
PangoGlyph glyph;
guint xshift;
guint yshift;
guint scale; /* times 1024 */
} GlyphCacheKey;
@@ -57,10 +55,12 @@ void gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache
gboolean gsk_gl_glyph_cache_lookup (GskGLGlyphCache *self,
PangoFont *font,
PangoGlyph glyph,
float x,
float y,
float scale,
GskGLDriver *driver,
GskGLCachedGlyph *cached_glyph_out);
GskGLCachedGlyph *cached_glyph_out);
void gsk_gl_glyph_cache_get_texture (GskGLDriver *driver,
PangoFont *font,
PangoGlyph glyph,
float scale,
GskGLCachedGlyph *glyph_out);
#endif
+5 -20
View File
@@ -13,13 +13,11 @@ typedef struct
GskGLTextureAtlas *atlas;
int frame_age; /* Number of frames this icon is unused */
guint used: 1;
GdkTexture *source_texture;
} IconData;
static void
icon_data_free (gpointer p)
{
g_object_unref (((IconData *)p)->source_texture);
g_free (p);
}
@@ -138,7 +136,7 @@ upload_region_or_else (GskGLIconCache *self,
GskImageRegion *region)
{
glBindTexture (GL_TEXTURE_2D, texture_id);
glTexSubImage2D (GL_TEXTURE_2D, 0, region->x, region->y, region->width, region->height,
glTextureSubImage2D (texture_id, 0, region->x, region->y, region->width, region->height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, region->data);
}
@@ -184,7 +182,6 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
icon_data->atlas = atlas;
icon_data->frame_age = 0;
icon_data->used = TRUE;
icon_data->source_texture = g_object_ref (texture);
graphene_rect_init (&icon_data->texture_rect,
(float)(packed_x + 1) / atlas->width,
(float)(packed_y + 1) / atlas->height,
@@ -216,22 +213,10 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
cairo_surface_destroy (padded_surface);
#if 0
{
static int k;
const int stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, atlas->width);
guchar *data = g_malloc (atlas->height * stride);
cairo_surface_t *s;
char *filename = g_strdup_printf ("atlas_%u_%d.png", atlas->texture_id, k++);
glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
glGetTexImage (GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
s = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32, atlas->width, atlas->height, stride);
cairo_surface_write_to_png (s, filename);
cairo_surface_destroy (s);
g_free (data);
g_free (filename);
}
/* Some obvious debugging */
static int k;
gsk_gl_image_write_to_png (&atlas->image, self->gl_driver,
g_strdup_printf ("icon%d.png", k ++));
#endif
}
}
+50 -187
View File
@@ -340,7 +340,6 @@ struct _GskGLRenderer
Program border_program;
Program cross_fade_program;
Program blend_program;
Program repeat_program;
};
};
@@ -593,24 +592,29 @@ render_text_node (GskGLRenderer *self,
if (gi->glyph == PANGO_GLYPH_EMPTY)
continue;
cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
gsk_gl_glyph_cache_lookup (self->glyph_cache,
(PangoFont *)font,
gi->glyph,
x + cx,
+ y + cy,
text_scale,
self->gl_driver,
&glyph);
/* e.g. whitespace */
if (glyph.draw_width <= 0 || glyph.draw_height <= 0)
goto next;
if (glyph.texture_id == 0)
goto next;
/* big glyphs are not cached */
if (!glyph.texture_id)
{
gsk_gl_glyph_cache_get_texture (self->gl_driver,
(PangoFont *)font,
gi->glyph,
text_scale,
&glyph);
g_assert (glyph.texture_id != 0);
}
cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
ops_set_texture (builder, glyph.texture_id);
@@ -619,8 +623,8 @@ render_text_node (GskGLRenderer *self,
tx2 = tx + glyph.tw;
ty2 = ty + glyph.th;
glyph_x = floor (x + cx + 0.125) + glyph.draw_x;
glyph_y = floor (y + cy + 0.125) + glyph.draw_y;
glyph_x = x + cx + glyph.draw_x;
glyph_y = y + cy + glyph.draw_y;
glyph_w = glyph.draw_width;
glyph_h = glyph.draw_height;
@@ -804,8 +808,7 @@ upload_texture (GskGLRenderer *self,
int texture_id;
if (texture->width <= 128 &&
texture->height <= 128 &&
!GDK_IS_GL_TEXTURE (texture))
texture->height <= 128)
{
graphene_rect_t trect;
@@ -940,9 +943,11 @@ 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);
@@ -967,6 +972,7 @@ render_transform_node (GskGLRenderer *self,
&region, &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);
@@ -1011,49 +1017,12 @@ render_opacity_node (GskGLRenderer *self,
GskRenderNode *node,
RenderOpBuilder *builder)
{
GskRenderNode *child = gsk_opacity_node_get_child (node);
const float opacity = gsk_opacity_node_get_opacity (node);
float prev_opacity;
if (gsk_render_node_get_node_type (child) == GSK_CONTAINER_NODE)
{
const float min_x = builder->dx + node->bounds.origin.x;
const float min_y = builder->dy + node->bounds.origin.y;
const float max_x = min_x + node->bounds.size.width;
const float max_y = min_y + node->bounds.size.height;
gboolean is_offscreen;
TextureRegion region;
prev_opacity = ops_set_opacity (builder,
builder->current_opacity * gsk_opacity_node_get_opacity (node));
/* The semantics of an opacity node mandate that when, e.g., two color nodes overlap,
* there may not be any blending between them */
add_offscreen_ops (self, builder, &child->bounds,
child,
&region, &is_offscreen,
FORCE_OFFSCREEN | RESET_OPACITY | RESET_CLIP);
prev_opacity = ops_set_opacity (builder,
builder->current_opacity * opacity);
ops_set_program (builder, &self->blit_program);
ops_set_texture (builder, region.texture_id);
ops_draw (builder, (GskQuadVertex[GL_N_VERTICES]) {
{ { min_x, min_y }, { region.x, region.y2 }, },
{ { min_x, max_y }, { region.x, region.y }, },
{ { max_x, min_y }, { region.x2, region.y2 }, },
{ { max_x, max_y }, { region.x2, region.y }, },
{ { min_x, max_y }, { region.x, region.y }, },
{ { max_x, min_y }, { region.x2, region.y2 }, },
});
}
else
{
prev_opacity = ops_set_opacity (builder,
builder->current_opacity * opacity);
gsk_gl_renderer_add_render_ops (self, child, builder);
}
gsk_gl_renderer_add_render_ops (self, gsk_opacity_node_get_child (node), builder);
ops_set_opacity (builder, prev_opacity);
}
@@ -1323,7 +1292,7 @@ render_rounded_clip_node (GskGLRenderer *self,
{ { min_x, min_y }, { 0, 1 }, },
{ { min_x, max_y }, { 0, 0 }, },
{ { max_x, min_y }, { 1, 1 }, },
{ { max_x, max_y }, { 1, 0 }, },
{ { min_x, max_y }, { 0, 0 }, },
{ { max_x, min_y }, { 1, 1 }, },
@@ -1424,7 +1393,7 @@ render_blur_node (GskGLRenderer *self,
ops_set_program (builder, &self->blur_program);
op.op = OP_CHANGE_BLUR;
graphene_size_init_from_size (&op.blur.size, &node->bounds.size);
op.blur.radius = blur_radius;
op.blur.radius = gsk_blur_node_get_radius (node);
ops_add (builder, &op);
ops_set_texture (builder, region.texture_id);
@@ -1435,7 +1404,7 @@ render_blur_node (GskGLRenderer *self,
{ { min_x, min_y }, { 0, 1 }, },
{ { min_x, max_y }, { 0, 0 }, },
{ { max_x, min_y }, { 1, 1 }, },
{ { max_x, max_y }, { 1, 0 }, },
{ { min_x, max_y }, { 0, 0 }, },
{ { max_x, min_y }, { 1, 1 }, },
@@ -1886,10 +1855,10 @@ render_shadow_node (GskGLRenderer *self,
RenderOpBuilder *builder,
const GskQuadVertex *vertex_data)
{
float min_x;
float min_y;
float max_x;
float max_y;
float min_x = node->bounds.origin.x;
float min_y = node->bounds.origin.y;
float max_x = min_x + node->bounds.size.width;
float max_y = min_y + node->bounds.size.height;
GskRenderNode *original_child = gsk_shadow_node_get_child (node);
GskRenderNode *shadow_child = original_child;
gsize n_shadows = gsk_shadow_node_get_n_shadows (node);
@@ -1915,11 +1884,6 @@ render_shadow_node (GskGLRenderer *self,
shadow_child = gsk_color_matrix_node_get_child (shadow_child);
}
min_x = builder->dx + shadow_child->bounds.origin.x;
min_y = builder->dy + shadow_child->bounds.origin.y;
max_x = min_x + shadow_child->bounds.size.width;
max_y = min_y + shadow_child->bounds.size.height;
for (i = 0; i < n_shadows; i ++)
{
const GskShadow *shadow = gsk_shadow_node_peek_shadow (node, i);
@@ -1941,6 +1905,11 @@ render_shadow_node (GskGLRenderer *self,
if (gdk_rgba_is_clear (&shadow->color))
continue;
min_x = builder->dx + shadow_child->bounds.origin.x;
min_y = builder->dy + shadow_child->bounds.origin.y;
max_x = min_x + shadow_child->bounds.size.width;
max_y = min_y + shadow_child->bounds.size.height;
/* Draw the child offscreen, without the offset. */
add_offscreen_ops (self, builder,
&shadow_child->bounds,
@@ -2083,90 +2052,6 @@ render_blend_node (GskGLRenderer *self,
ops_draw (builder, vertex_data);
}
static inline void
render_repeat_node (GskGLRenderer *self,
GskRenderNode *node,
RenderOpBuilder *builder)
{
const float min_x = builder->dx + node->bounds.origin.x;
const float min_y = builder->dy + node->bounds.origin.y;
const float max_x = min_x + node->bounds.size.width;
const float max_y = min_y + node->bounds.size.height;
GskRenderNode *child = gsk_repeat_node_get_child (node);
const graphene_rect_t *child_bounds = gsk_repeat_node_peek_child_bounds (node);
TextureRegion region;
gboolean is_offscreen;
RenderOp op;
if (child_bounds != NULL &&
!graphene_rect_equal (child_bounds, &child->bounds))
{
/* TODO: Implement these repeat nodes. */
render_fallback_node (self, node, builder);
return;
}
/* Draw the entire child on a texture */
add_offscreen_ops (self, builder,
&child->bounds,
child,
&region, &is_offscreen,
RESET_CLIP | RESET_OPACITY);
ops_set_program (builder, &self->repeat_program);
ops_set_texture (builder, region.texture_id);
op.op = OP_CHANGE_REPEAT;
op.repeat.child_bounds[0] = 0; /* Both currently unused */
op.repeat.child_bounds[1] = 0;
op.repeat.child_bounds[2] = node->bounds.size.width / child_bounds->size.width;
op.repeat.child_bounds[3] = node->bounds.size.height / child_bounds->size.height;
op.repeat.texture_rect[0] = region.x;
op.repeat.texture_rect[2] = region.x2;
if (is_offscreen)
{
op.repeat.texture_rect[1] = region.y2;
op.repeat.texture_rect[3] = region.y;
}
else
{
op.repeat.texture_rect[1] = region.y;
op.repeat.texture_rect[3] = region.y2;
}
ops_add (builder, &op);
if (is_offscreen)
{
const GskQuadVertex offscreen_vertex_data[GL_N_VERTICES] = {
{ { min_x, min_y }, { region.x, region.y2 }, },
{ { min_x, max_y }, { region.x, region.y }, },
{ { max_x, min_y }, { region.x2, region.y2 }, },
{ { max_x, max_y }, { region.x2, region.y }, },
{ { min_x, max_y }, { region.x, region.y }, },
{ { max_x, min_y }, { region.x2, region.y2 }, },
};
ops_draw (builder, offscreen_vertex_data);
}
else
{
const GskQuadVertex onscreen_vertex_data[GL_N_VERTICES] = {
{ { min_x, min_y }, { region.x, region.y }, },
{ { min_x, max_y }, { region.x, region.y2 }, },
{ { max_x, min_y }, { region.x2, region.y }, },
{ { max_x, max_y }, { region.x2, region.y2 }, },
{ { min_x, max_y }, { region.x, region.y2 }, },
{ { max_x, min_y }, { region.x2, region.y }, },
};
ops_draw (builder, onscreen_vertex_data);
}
}
static inline void
apply_viewport_op (const Program *program,
const RenderOp *op)
@@ -2453,21 +2338,12 @@ apply_blend_op (const Program *program,
glUniform1i (program->blend.mode_location, op->blend.mode);
}
static inline void
apply_repeat_op (const Program *program,
const RenderOp *op)
{
glUniform4fv (program->repeat.child_bounds_location, 1, op->repeat.child_bounds);
glUniform4fv (program->repeat.texture_rect_location, 1, op->repeat.texture_rect);
}
static void
gsk_gl_renderer_dispose (GObject *gobject)
{
GskGLRenderer *self = GSK_GL_RENDERER (gobject);
g_clear_pointer (&self->render_ops, g_array_unref);
ops_free (&self->op_builder);
G_OBJECT_CLASS (gsk_gl_renderer_parent_class)->dispose (gobject);
}
@@ -2482,21 +2358,19 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
static const struct {
const char *name;
const char *fs;
const char *vs;
} program_definitions[] = {
{ "blit", "blit.fs.glsl" },
{ "color", "color.fs.glsl" },
{ "coloring", "coloring.fs.glsl" },
{ "color matrix", "color_matrix.fs.glsl" },
{ "linear gradient", "linear_gradient.fs.glsl" },
{ "blur", "blur.fs.glsl" },
{ "inset shadow", "inset_shadow.fs.glsl" },
{ "outset shadow", "outset_shadow.fs.glsl" },
{ "blit", "blit.fs.glsl" },
{ "color", "color.fs.glsl" },
{ "coloring", "coloring.fs.glsl" },
{ "color matrix", "color_matrix.fs.glsl" },
{ "linear gradient", "linear_gradient.fs.glsl" },
{ "blur", "blur.fs.glsl" },
{ "inset shadow", "inset_shadow.fs.glsl" },
{ "outset shadow", "outset_shadow.fs.glsl" },
{ "unblurred outset shadow", "unblurred_outset_shadow.fs.glsl" },
{ "border", "border.fs.glsl" },
{ "cross fade", "cross_fade.fs.glsl" },
{ "blend", "blend.fs.glsl" },
{ "repeat", "repeat.fs.glsl" },
{ "border", "border.fs.glsl" },
{ "cross fade", "cross_fade.fs.glsl" },
{ "blend", "blend.fs.glsl" },
};
builder = gsk_shader_builder_new ();
@@ -2549,7 +2423,6 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
prog->index = i;
prog->id = gsk_shader_builder_create_program (builder,
program_definitions[i].fs,
program_definitions[i].vs,
&shader_error);
if (shader_error != NULL)
@@ -2557,8 +2430,8 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
g_propagate_prefixed_error (error, shader_error,
"Unable to create '%s' program (from %s and %s):\n",
program_definitions[i].name,
program_definitions[i].fs,
program_definitions[i].vs);
"blit.vs.glsl",
program_definitions[i].fs);
g_object_unref (builder);
return FALSE;
@@ -2632,10 +2505,6 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
INIT_PROGRAM_UNIFORM_LOCATION (blend, source2);
INIT_PROGRAM_UNIFORM_LOCATION (blend, mode);
/* repeat */
INIT_PROGRAM_UNIFORM_LOCATION (repeat, child_bounds);
INIT_PROGRAM_UNIFORM_LOCATION (repeat, texture_rect);
g_object_unref (builder);
return TRUE;
}
@@ -2963,11 +2832,8 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
render_blend_node (self, node, builder);
break;
case GSK_REPEAT_NODE:
render_repeat_node (self, node, builder);
break;
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
case GSK_REPEAT_NODE:
case GSK_CAIRO_NODE:
default:
{
@@ -3254,10 +3120,6 @@ gsk_gl_renderer_render_ops (GskGLRenderer *self,
apply_unblurred_outset_shadow_op (program, op);
break;
case OP_CHANGE_REPEAT:
apply_repeat_op (program, op);
break;
case OP_DRAW:
OP_PRINT (" -> draw %ld, size %ld and program %d\n",
op->draw.vao_offset, op->draw.vao_size, program->index);
@@ -3298,7 +3160,7 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
int scale_factor)
{
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
graphene_matrix_t projection;
graphene_matrix_t modelview, projection;
gsize buffer_size;
#ifdef G_ENABLE_DEBUG
GskProfiler *profiler;
@@ -3318,6 +3180,7 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
g_assert (gsk_gl_driver_in_frame (self->gl_driver));
/* Set up the modelview and projection matrices to fit our viewport */
graphene_matrix_init_scale (&modelview, scale_factor, scale_factor, 1.0);
graphene_matrix_init_ortho (&projection,
viewport->origin.x,
viewport->origin.x + viewport->size.width,
+32 -68
View File
@@ -8,15 +8,6 @@ rect_equal (const graphene_rect_t *a,
return memcmp (a, b, sizeof (graphene_rect_t)) == 0;
}
static inline ProgramState *
get_current_program_state (RenderOpBuilder *builder)
{
if (!builder->current_program)
return NULL;
return &builder->program_state[builder->current_program->index];
}
void
ops_finish (RenderOpBuilder *builder)
{
@@ -36,6 +27,7 @@ ops_finish (RenderOpBuilder *builder)
builder->current_render_target = 0;
builder->current_texture = 0;
builder->current_program = NULL;
builder->current_program_state = NULL;
graphene_matrix_init_identity (&builder->current_projection);
builder->current_viewport = GRAPHENE_RECT_INIT (0, 0, 0, 0);
}
@@ -195,17 +187,6 @@ ops_init (RenderOpBuilder *builder)
}
}
void
ops_free (RenderOpBuilder *builder)
{
int i;
for (i = 0; i < GL_N_PROGRAMS; i ++)
{
gsk_transform_unref (builder->program_state[i].modelview);
}
}
void
ops_set_program (RenderOpBuilder *builder,
const Program *program)
@@ -244,7 +225,6 @@ ops_set_program (RenderOpBuilder *builder,
op.op = OP_CHANGE_MODELVIEW;
gsk_transform_to_matrix (builder->current_modelview, &op.modelview);
g_array_append_val (builder->render_ops, op);
gsk_transform_unref (program_state->modelview);
program_state->modelview = gsk_transform_ref (builder->current_modelview);
}
@@ -273,6 +253,8 @@ ops_set_program (RenderOpBuilder *builder,
g_array_append_val (builder->render_ops, op);
program_state->opacity = builder->current_opacity;
}
builder->current_program_state = &builder->program_state[program->index];
}
static void
@@ -280,10 +262,9 @@ ops_set_clip (RenderOpBuilder *builder,
const GskRoundedRect *clip)
{
RenderOp *last_op;
ProgramState *current_program_state = get_current_program_state (builder);
if (current_program_state &&
memcmp (&current_program_state->clip, clip,sizeof (GskRoundedRect)) == 0)
if (builder->current_program_state &&
memcmp (&builder->current_program_state->clip, clip,sizeof (GskRoundedRect)) == 0)
return;
if (builder->render_ops->len > 0)
@@ -305,7 +286,7 @@ ops_set_clip (RenderOpBuilder *builder,
}
if (builder->current_program != NULL)
current_program_state->clip = *clip;
builder->current_program_state->clip = *clip;
}
void
@@ -355,16 +336,12 @@ static void
ops_set_modelview_internal (RenderOpBuilder *builder,
GskTransform *transform)
{
ProgramState *current_program_state = get_current_program_state (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);
@@ -390,18 +367,10 @@ ops_set_modelview_internal (RenderOpBuilder *builder,
}
if (builder->current_program != NULL)
{
gsk_transform_unref (current_program_state->modelview);
current_program_state->modelview = gsk_transform_ref (transform);
}
builder->current_program_state->modelview = transform;
}
/**
* ops_set_modelview:
* @builder
* @transform: (transfer full): The new modelview transform
*
* This sets the modelview to the given one without looking at the
/* This sets the modelview to the given one without looking at the
* one that's currently set */
void
ops_set_modelview (RenderOpBuilder *builder,
@@ -417,11 +386,11 @@ ops_set_modelview (RenderOpBuilder *builder,
g_array_set_size (builder->mv_stack, builder->mv_stack->len + 1);
entry = &g_array_index (builder->mv_stack, MatrixStackEntry, builder->mv_stack->len - 1);
entry->transform = transform;
entry->transform = gsk_transform_ref (transform);
entry->metadata.dx_before = builder->dx;
entry->metadata.dy_before = builder->dy;
extract_matrix_metadata (entry->transform, &entry->metadata);
extract_matrix_metadata (transform, &entry->metadata);
builder->dx = 0;
builder->dy = 0;
@@ -435,6 +404,7 @@ void
ops_push_modelview (RenderOpBuilder *builder,
GskTransform *transform)
{
float scale = ops_get_scale (builder);
MatrixStackEntry *entry;
if (G_UNLIKELY (builder->mv_stack == NULL))
@@ -454,9 +424,10 @@ ops_push_modelview (RenderOpBuilder *builder,
/* Multiply given matrix with current modelview */
t = gsk_transform_translate (gsk_transform_ref (cur->transform),
&(graphene_point_t) { builder->dx, builder->dy});
&(graphene_point_t) { builder->dx * scale, builder->dy * scale});
t = gsk_transform_transform (t, transform);
entry->transform = t;
}
else
{
@@ -465,6 +436,7 @@ ops_push_modelview (RenderOpBuilder *builder,
entry->metadata.dx_before = builder->dx;
entry->metadata.dy_before = builder->dy;
extract_matrix_metadata (entry->transform, &entry->metadata);
builder->dx = 0;
@@ -504,7 +476,6 @@ graphene_matrix_t
ops_set_projection (RenderOpBuilder *builder,
const graphene_matrix_t *projection)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
graphene_matrix_t prev_mv;
@@ -530,7 +501,7 @@ ops_set_projection (RenderOpBuilder *builder,
}
if (builder->current_program != NULL)
current_program_state->projection = *projection;
builder->current_program_state->projection = *projection;
prev_mv = builder->current_projection;
builder->current_projection = *projection;
@@ -542,20 +513,19 @@ graphene_rect_t
ops_set_viewport (RenderOpBuilder *builder,
const graphene_rect_t *viewport)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
graphene_rect_t prev_viewport;
if (current_program_state != NULL &&
rect_equal (&current_program_state->viewport, viewport))
return current_program_state->viewport;
if (builder->current_program_state != NULL &&
rect_equal (&builder->current_program_state->viewport, viewport))
return builder->current_program_state->viewport;
op.op = OP_CHANGE_VIEWPORT;
op.viewport = *viewport;
g_array_append_val (builder->render_ops, op);
if (builder->current_program != NULL)
current_program_state->viewport = *viewport;
builder->current_program_state->viewport = *viewport;
prev_viewport = builder->current_viewport;
builder->current_viewport = *viewport;
@@ -620,7 +590,6 @@ float
ops_set_opacity (RenderOpBuilder *builder,
float opacity)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
float prev_opacity;
RenderOp *last_op;
@@ -654,7 +623,7 @@ ops_set_opacity (RenderOpBuilder *builder,
builder->current_opacity = opacity;
if (builder->current_program != NULL)
current_program_state->opacity = opacity;
builder->current_program_state->opacity = opacity;
return prev_opacity;
}
@@ -663,13 +632,12 @@ void
ops_set_color (RenderOpBuilder *builder,
const GdkRGBA *color)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
if (gdk_rgba_equal (color, &current_program_state->color))
if (gdk_rgba_equal (color, &builder->current_program_state->color))
return;
current_program_state->color = *color;
builder->current_program_state->color = *color;
op.op = OP_CHANGE_COLOR;
op.color = *color;
@@ -681,19 +649,18 @@ ops_set_color_matrix (RenderOpBuilder *builder,
const graphene_matrix_t *matrix,
const graphene_vec4_t *offset)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
if (memcmp (matrix,
&current_program_state->color_matrix.matrix,
&builder->current_program_state->color_matrix.matrix,
sizeof (graphene_matrix_t)) == 0 &&
memcmp (offset,
&current_program_state->color_matrix.offset,
&builder->current_program_state->color_matrix.offset,
sizeof (graphene_vec4_t)) == 0)
return;
current_program_state->color_matrix.matrix = *matrix;
current_program_state->color_matrix.offset = *offset;
builder->current_program_state->color_matrix.matrix = *matrix;
builder->current_program_state->color_matrix.offset = *offset;
op.op = OP_CHANGE_COLOR_MATRIX;
op.color_matrix.matrix = *matrix;
@@ -705,14 +672,13 @@ void
ops_set_border (RenderOpBuilder *builder,
const GskRoundedRect *outline)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
if (memcmp (&current_program_state->border.outline,
if (memcmp (&builder->current_program_state->border.outline,
outline, sizeof (GskRoundedRect)) == 0)
return;
current_program_state->border.outline = *outline;
builder->current_program_state->border.outline = *outline;
op.op = OP_CHANGE_BORDER;
op.border.outline = *outline;
@@ -723,14 +689,13 @@ void
ops_set_border_width (RenderOpBuilder *builder,
const float *widths)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
if (memcmp (current_program_state->border.widths,
if (memcmp (builder->current_program_state->border.widths,
widths, sizeof (float) * 4) == 0)
return;
memcpy (&current_program_state->border.widths,
memcpy (&builder->current_program_state->border.widths,
widths, sizeof (float) * 4);
op.op = OP_CHANGE_BORDER_WIDTH;
@@ -746,16 +711,15 @@ void
ops_set_border_color (RenderOpBuilder *builder,
const GdkRGBA *color)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
op.op = OP_CHANGE_BORDER_COLOR;
rgba_to_float (color, op.border.color);
if (memcmp (&op.border.color, &current_program_state->border.color,
if (memcmp (&op.border.color, &builder->current_program_state->border.color,
sizeof (float) * 4) == 0)
return;
rgba_to_float (color, current_program_state->border.color);
rgba_to_float (color, builder->current_program_state->border.color);
g_array_append_val (builder->render_ops, op);
}
+4 -12
View File
@@ -11,7 +11,7 @@
#include "gskrendernodeprivate.h"
#define GL_N_VERTICES 6
#define GL_N_PROGRAMS 13
#define GL_N_PROGRAMS 12
@@ -60,7 +60,6 @@ enum {
OP_PUSH_DEBUG_GROUP = 24,
OP_POP_DEBUG_GROUP = 25,
OP_CHANGE_BLEND = 26,
OP_CHANGE_REPEAT = 27,
};
typedef struct
@@ -140,10 +139,6 @@ typedef struct
int source2_location;
int mode_location;
} blend;
struct {
int child_bounds_location;
int texture_rect_location;
} repeat;
};
} Program;
@@ -154,7 +149,7 @@ typedef struct
union {
float opacity;
graphene_matrix_t modelview;
graphene_matrix_t modelview; /* TODO: Make both matrix members just "matrix" */
graphene_matrix_t projection;
const Program *program;
int texture_id;
@@ -226,10 +221,6 @@ typedef struct
int source2;
int mode;
} blend;
struct {
float child_bounds[4];
float texture_rect[4];
} repeat;
struct {
char *filename;
int width;
@@ -267,6 +258,8 @@ typedef struct
typedef struct
{
ProgramState program_state[GL_N_PROGRAMS];
/* Current global state */
ProgramState *current_program_state;
const Program *current_program;
int current_render_target;
int current_texture;
@@ -297,7 +290,6 @@ void ops_dump_framebuffer (RenderOpBuilder *builder,
int width,
int height);
void ops_init (RenderOpBuilder *builder);
void ops_free (RenderOpBuilder *builder);
void ops_push_debug_group (RenderOpBuilder *builder,
const char *text);
void ops_pop_debug_group (RenderOpBuilder *builder);
+1 -11
View File
@@ -257,7 +257,6 @@ gsk_shader_builder_set_common_vertex_shader (GskShaderBuilder *self,
int
gsk_shader_builder_create_program (GskShaderBuilder *builder,
const char *fragment_shader,
const char *vertex_shader,
GError **error)
{
int vertex_id;
@@ -269,16 +268,7 @@ gsk_shader_builder_create_program (GskShaderBuilder *builder,
g_return_val_if_fail (fragment_shader != NULL, -1);
g_return_val_if_fail (builder->common_vertex_shader_id != 0, -1);
if (vertex_shader == NULL)
vertex_id = builder->common_vertex_shader_id;
else
vertex_id = gsk_shader_builder_compile_shader (builder, GL_VERTEX_SHADER,
builder->vertex_preamble,
vertex_shader,
error);
if (vertex_id < 0)
return -1;
vertex_id = builder->common_vertex_shader_id;
fragment_id = gsk_shader_builder_compile_shader (builder, GL_FRAGMENT_SHADER,
builder->fragment_preamble,
fragment_shader,
-1
View File
@@ -31,7 +31,6 @@ void gsk_shader_builder_set_common_vertex_shader (GskShad
int gsk_shader_builder_create_program (GskShaderBuilder *builder,
const char *fragment_shader,
const char *vertex_shader,
GError **error);
G_END_DECLS
+3 -3
View File
@@ -1966,14 +1966,14 @@ gsk_transform_node_diff (GskRenderNode *node1,
cairo_region_t *tmp = cairo_region_copy (sub);
cairo_region_translate (tmp, 1, 0);
cairo_region_union (sub, tmp);
cairo_region_destroy (tmp);
cairo_region_destroy (sub);
}
if (floor (dy) != dy)
{
cairo_region_t *tmp = cairo_region_copy (sub);
cairo_region_translate (tmp, 0, 1);
cairo_region_union (sub, tmp);
cairo_region_destroy (tmp);
cairo_region_destroy (sub);
}
cairo_region_union (region, sub);
cairo_region_destroy (sub);
@@ -2284,7 +2284,7 @@ gsk_opacity_node_new (GskRenderNode *child,
/**
* gsk_opacity_node_get_child:
* @node: an opacity @GskRenderNode
* @node: a opacity @GskRenderNode
*
* Gets the child node that is getting opacityed by the given @node.
*
+1 -4
View File
@@ -94,7 +94,6 @@ parse_texture (GtkCssParser *parser,
if (bytes)
{
stream = g_memory_input_stream_new_from_bytes (bytes);
g_bytes_unref (bytes);
pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, &error);
g_object_unref (stream);
if (pixbuf != NULL)
@@ -749,8 +748,6 @@ parse_glyphs (GtkCssParser *parser,
pango_glyph_string_set_size (glyph_string, glyph_string->num_glyphs + 1);
glyph_string->glyphs[glyph_string->num_glyphs - 1] = gi;
}
g_free (s);
}
else
{
@@ -820,7 +817,7 @@ parse_container_node (GtkCssParser *parser)
token = gtk_css_parser_get_token (parser))
{
node = NULL;
/* We don't want a semicolon here, but the parse_node function will figure
/* We don't wand a semicolon here, but the parse_node function will figure
* that out itself and return an error if we encounter one.
*/
gtk_css_parser_start_semicolon_block (parser, GTK_CSS_TOKEN_OPEN_CURLY);
+18 -58
View File
@@ -106,7 +106,7 @@ gsk_transform_has_class (GskTransform *self,
* @transform_class: class structure for this self
* @category: The category of this transform. Will be used to initialize
* the result's category together with &next's category
* @next: (transfer full): Next matrix to multiply with or %NULL if none
* @next: (transfer full) Next matrix to multiply with or %NULL if none
*
* Returns: (transfer full): the newly created #GskTransform
*/
@@ -461,7 +461,7 @@ gsk_transform_matrix_with_category (GskTransform *next,
/**
* gsk_transform_matrix:
* @next: (allow-none) (transfer full): the next transform
* @next: (allow-none): the next transform
* @matrix: the matrix to multiply @next with
*
* Multiplies @next with the given @matrix.
@@ -612,7 +612,7 @@ static const GskTransformClass GSK_TRANSLATE_TRANSFORM_CLASS =
/**
* gsk_transform_translate:
* @next: (allow-none) (transfer full): the next transform
* @next: (allow-none): the next transform
* @point: the point to translate the matrix by
*
* Translates @next in 2dimensional space by @point.
@@ -632,7 +632,7 @@ gsk_transform_translate (GskTransform *next,
/**
* gsk_transform_translate_3d:
* @next: (allow-none) (transfer full): the next transform
* @next: (allow-none): the next transform
* @point: the point to translate the matrix by
*
* Translates @next by @point.
@@ -646,7 +646,7 @@ gsk_transform_translate_3d (GskTransform *next,
GskTranslateTransform *result;
if (graphene_point3d_equal (point, graphene_point3d_zero ()))
return next;
return gsk_transform_ref (next);
if (gsk_transform_has_class (next, &GSK_TRANSLATE_TRANSFORM_CLASS))
{
@@ -787,7 +787,7 @@ static const GskTransformClass GSK_ROTATE_TRANSFORM_CLASS =
/**
* gsk_transform_rotate:
* @next: (allow-none) (transfer full): the next transform
* @next: (allow-none): the next transform
* @angle: the rotation angle, in degrees (clockwise)
*
* Rotates @next @angle degrees in 2D - or in 3Dspeak, around the z axis.
@@ -801,7 +801,7 @@ gsk_transform_rotate (GskTransform *next,
GskRotateTransform *result;
if (angle == 0.0f)
return next;
return gsk_transform_ref (next);
if (gsk_transform_has_class (next, &GSK_ROTATE_TRANSFORM_CLASS))
{
@@ -911,7 +911,7 @@ static const GskTransformClass GSK_ROTATE3D_TRANSFORM_CLASS =
/**
* gsk_transform_rotate_3d:
* @next: (allow-none) (transfer full): the next transform
* @next: (allow-none): the next transform
* @angle: the rotation angle, in degrees (clockwise)
* @axis: The rotation axis
*
@@ -932,7 +932,7 @@ gsk_transform_rotate_3d (GskTransform *next,
return gsk_transform_rotate (next, angle);
if (angle == 0.0f)
return next;
return gsk_transform_ref (next);
result = gsk_transform_alloc (&GSK_ROTATE3D_TRANSFORM_CLASS,
GSK_TRANSFORM_CATEGORY_3D,
@@ -1084,7 +1084,7 @@ static const GskTransformClass GSK_SCALE_TRANSFORM_CLASS =
/**
* gsk_transform_scale:
* @next: (allow-none) (transfer full): the next transform
* @next: (allow-none): the next transform
* @factor_x: scaling factor on the X axis
* @factor_y: scaling factor on the Y axis
*
@@ -1103,7 +1103,7 @@ gsk_transform_scale (GskTransform *next,
/**
* gsk_transform_scale_3d:
* @next: (allow-none) (transfer full): the next transform
* @next: (allow-none): the next transform
* @factor_x: scaling factor on the X axis
* @factor_y: scaling factor on the Y axis
* @factor_z: scaling factor on the Z axis
@@ -1121,7 +1121,7 @@ gsk_transform_scale_3d (GskTransform *next,
GskScaleTransform *result;
if (factor_x == 1 && factor_y == 1 && factor_z == 1)
return next;
return gsk_transform_ref (next);
if (gsk_transform_has_class (next, &GSK_SCALE_TRANSFORM_CLASS))
{
@@ -1232,7 +1232,7 @@ static const GskTransformClass GSK_PERSPECTIVE_TRANSFORM_CLASS =
/**
* gsk_transform_perspective:
* @next: (allow-none) (transfer full): the next transform
* @next: (allow-none): the next transform
* @depth: distance of the z=0 plane. Lower values give a more
* flattened pyramid and therefore a more pronounced
* perspective effect.
@@ -1250,7 +1250,7 @@ gsk_transform_perspective (GskTransform *next,
float depth)
{
GskPerspectiveTransform *result;
if (gsk_transform_has_class (next, &GSK_PERSPECTIVE_TRANSFORM_CLASS))
{
GskTransform *r = gsk_transform_perspective (gsk_transform_ref (next->next),
@@ -1690,26 +1690,11 @@ 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;
@@ -1901,43 +1886,18 @@ 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;
-1
View File
@@ -12,7 +12,6 @@ gsk_private_gl_shaders = [
'resources/glsl/border.fs.glsl',
'resources/glsl/cross_fade.fs.glsl',
'resources/glsl/blend.fs.glsl',
'resources/glsl/repeat.fs.glsl',
'resources/glsl/es2_common.fs.glsl',
'resources/glsl/es2_common.vs.glsl',
'resources/glsl/gl3_common.fs.glsl',
+35 -84
View File
@@ -4,14 +4,14 @@ uniform sampler2D u_source2;
float
combine (float source, float backdrop)
{
return source + backdrop * (1.0 - source);
return source + backdrop * (1 - source);
}
vec4
composite (vec4 Cs, vec4 Cb, vec3 B)
{
float ao = Cs.a + Cb.a * (1.0 - Cs.a);
vec3 Co = (Cs.a*(1.0 - Cb.a)*Cs.rgb + Cs.a*Cb.a*B + (1.0 - Cs.a)*Cb.a*Cb.rgb) / ao;
float ao = Cs.a + Cb.a * (1 - Cs.a);
vec3 Co = (Cs.a*(1 - Cb.a)*Cs.rgb + Cs.a*Cb.a*B + (1 - Cs.a)*Cb.a*Cb.rgb) / ao;
return vec4(Co, ao);
}
@@ -43,9 +43,9 @@ float
hard_light (float source, float backdrop)
{
if (source <= 0.5)
return 2.0 * backdrop * source;
return 2 * backdrop * source;
else
return 2.0 * (backdrop + source - backdrop * source) - 1.0;
return 2 * (backdrop + source - backdrop * source) - 1;
}
vec4
@@ -63,14 +63,14 @@ soft_light (float source, float backdrop)
float db;
if (backdrop <= 0.25)
db = ((16.0 * backdrop - 12.0) * backdrop + 4.0) * backdrop;
db = ((16 * backdrop - 12) * backdrop + 4) * backdrop;
else
db = sqrt (backdrop);
if (source <= 0.5)
return backdrop - (1.0 - 2.0 * source) * backdrop * (1.0 - backdrop);
return backdrop - (1 - 2 * source) * backdrop * (1 - backdrop);
else
return backdrop + (2.0 * source - 1.0) * (db - backdrop);
return backdrop + (2 * source - 1) * (db - backdrop);
}
vec4
@@ -155,8 +155,8 @@ clip_color (vec3 c)
float l = lum (c);
float n = min (c.r, min (c.g, c.b));
float x = max (c.r, max (c.g, c.b));
if (n < 0.0) c = l + (((c - l) * l) / (l - n));
if (x > 1.0) c = l + (((c - l) * (1.0 - l)) / (x - l));
if (n < 0) c = l + (((c - l) * l) / (l - n));
if (x > 1) c = l + (((c - l) * (1 - l)) / (x - l));
return c;
}
@@ -189,12 +189,12 @@ set_sat (vec3 c, float s)
if (c.g == cmin)
{
res.b = ((c.b - cmin) * s) / (cmax - cmin);
res.g = 0.0;
res.g = 0;
}
else
{
res.g = ((c.g - cmin) * s) / (cmax - cmin);
res.b = 0.0;
res.b = 0;
}
res.r = s;
}
@@ -203,12 +203,12 @@ set_sat (vec3 c, float s)
if (c.r == cmin)
{
res.b = ((c.b - cmin) * s) / (cmax - cmin);
res.r = 0.0;
res.r = 0;
}
else
{
res.r = ((c.r - cmin) * s) / (cmax - cmin);
res.b = 0.0;
res.b = 0;
}
res.g = s;
}
@@ -217,12 +217,12 @@ set_sat (vec3 c, float s)
if (c.r == cmin)
{
res.g = ((c.g - cmin) * s) / (cmax - cmin);
res.r = 0.0;
res.r = 0;
}
else
{
res.r = ((c.r - cmin) * s) / (cmax - cmin);
res.g = 0.0;
res.g = 0;
}
res.b = s;
}
@@ -263,74 +263,25 @@ void main() {
vec4 top_color = Texture(u_source2, vUv);
vec4 result;
if (u_mode == 0)
{
result = normal(top_color, bottom_color);
}
else if (u_mode == 1)
{
result = multiply(top_color, bottom_color);
}
else if (u_mode == 2)
{
result = screen(top_color, bottom_color);
}
else if (u_mode == 3)
{
result = overlay(top_color, bottom_color);
}
else if (u_mode == 4)
{
result = darken(top_color, bottom_color);
}
else if (u_mode == 5)
{
result = lighten(top_color, bottom_color);
}
else if (u_mode == 6)
{
result = color_dodge(top_color, bottom_color);
}
else if (u_mode == 7)
{
result = color_burn(top_color, bottom_color);
}
else if (u_mode == 8)
{
result = hard_light(top_color, bottom_color);
}
else if (u_mode == 9)
{
result = soft_light(top_color, bottom_color);
}
else if (u_mode == 10)
{
result = difference(top_color, bottom_color);
}
else if (u_mode == 11)
{
result = exclusion(top_color, bottom_color);
}
else if (u_mode == 12)
{
result = color(top_color, bottom_color);
}
else if (u_mode == 13)
{
result = hue(top_color, bottom_color);
}
else if (u_mode == 14)
{
result = saturation(top_color, bottom_color);
}
else if (u_mode == 15)
{
result = luminosity(top_color, bottom_color);
}
else
{
discard;
}
switch(u_mode) {
case 0: result = normal(top_color, bottom_color); break;
case 1: result = multiply(top_color, bottom_color); break;
case 2: result = screen(top_color, bottom_color); break;
case 3: result = overlay(top_color, bottom_color); break;
case 4: result = darken(top_color, bottom_color); break;
case 5: result = lighten(top_color, bottom_color); break;
case 6: result = color_dodge(top_color, bottom_color); break;
case 7: result = color_burn(top_color, bottom_color); break;
case 8: result = hard_light(top_color, bottom_color); break;
case 9: result = soft_light(top_color, bottom_color); break;
case 10: result = difference(top_color, bottom_color); break;
case 11: result = exclusion(top_color, bottom_color); break;
case 12: result = color(top_color, bottom_color); break;
case 13: result = hue(top_color, bottom_color); break;
case 14: result = saturation(top_color, bottom_color); break;
case 15: result = luminosity(top_color, bottom_color); break;
default: discard;
}
setOutputColor(result * u_alpha);
}
-34
View File
@@ -1,34 +0,0 @@
uniform vec4 u_child_bounds;
uniform vec4 u_texture_rect;
float wrap(float f, float wrap_for) {
return mod(f, wrap_for);
}
/* We get the texture coordinates via vUv,
* but that might be on a texture atlas, so we need to do the
* wrapping ourselves.
*/
void main() {
/* We map the texture coordinate to [1;0], then wrap it and scale the result again */
float tw = u_texture_rect.z - u_texture_rect.x;
float th = u_texture_rect.w - u_texture_rect.y;
float mapped_x = (vUv.x - u_texture_rect.x) / tw;
float mapped_y = (vUv.y - u_texture_rect.y) / th;
float wrapped_x = wrap(mapped_x * u_child_bounds.z, 1.0);
float wrapped_y = wrap(mapped_y * u_child_bounds.w, 1.0);
vec2 tp;
tp.x = u_texture_rect.x + (wrapped_x * tw);
tp.y = u_texture_rect.y + (wrapped_y * th);
vec4 diffuse = Texture(u_source, tp);
setOutputColor(diffuse * u_alpha);
}
+3 -8
View File
@@ -119,17 +119,12 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline *
if (gi->glyph != PANGO_GLYPH_EMPTY)
{
double cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
double cy = gi->geometry.y_offset / PANGO_SCALE;
double cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
double cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
GskVulkanColorTextInstance *instance = &instances[count];
GskVulkanCachedGlyph *glyph;
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer,
font,
gi->glyph,
x_position + gi->geometry.x_offset,
gi->geometry.y_offset,
scale);
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer, font, gi->glyph, scale);
instance->tex_rect[0] = glyph->tx;
instance->tex_rect[1] = glyph->ty;
+4 -21
View File
@@ -115,8 +115,6 @@ gsk_vulkan_glyph_cache_class_init (GskVulkanGlyphCacheClass *klass)
typedef struct {
PangoFont *font;
PangoGlyph glyph;
guint xshift;
guint yshift;
guint scale; /* times 1024 */
} GlyphCacheKey;
@@ -128,8 +126,6 @@ glyph_cache_equal (gconstpointer v1, gconstpointer v2)
return key1->font == key2->font &&
key1->glyph == key2->glyph &&
key1->xshift == key2->xshift &&
key1->yshift == key2->yshift &&
key1->scale == key2->scale;
}
@@ -138,7 +134,7 @@ glyph_cache_hash (gconstpointer v)
{
const GlyphCacheKey *key = v;
return GPOINTER_TO_UINT (key->font) ^ key->glyph ^ (key->xshift << 24) ^ (key->yshift << 26) ^ key->scale;
return GPOINTER_TO_UINT (key->font) ^ key->glyph ^ key->scale;
}
static void
@@ -271,10 +267,10 @@ render_glyph (Atlas *atlas,
gi.glyph = key->glyph;
gi.geometry.width = value->draw_width * 1024;
if (key->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
gi.geometry.x_offset = key->xshift * 256;
gi.geometry.x_offset = 0;
else
gi.geometry.x_offset = key->xshift * 256 - value->draw_x * 1024;
gi.geometry.y_offset = key->yshift * 256 - value->draw_y * 1024;
gi.geometry.x_offset = - value->draw_x * 1024;
gi.geometry.y_offset = - value->draw_y * 1024;
glyphs.num_glyphs = 1;
glyphs.glyphs = &gi;
@@ -332,29 +328,18 @@ gsk_vulkan_glyph_cache_new (GskRenderer *renderer,
return cache;
}
#define PHASE(x) ((x % PANGO_SCALE) * 4 / PANGO_SCALE)
GskVulkanCachedGlyph *
gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache *cache,
gboolean create,
PangoFont *font,
PangoGlyph glyph,
int x,
int y,
float scale)
{
GlyphCacheKey lookup_key;
GskVulkanCachedGlyph *value;
guint xshift;
guint yshift;
xshift = PHASE (x);
yshift = PHASE (y);
lookup_key.font = font;
lookup_key.glyph = glyph;
lookup_key.xshift = xshift;
lookup_key.yshift = yshift;
lookup_key.scale = (guint)(scale * 1024);
value = g_hash_table_lookup (cache->hash_table, &lookup_key);
@@ -389,8 +374,6 @@ gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache *cache,
key->font = g_object_ref (font);
key->glyph = glyph;
key->xshift = xshift;
key->yshift = yshift;
key->scale = (guint)(scale * 1024);
if (ink_rect.width > 0 && ink_rect.height > 0)
-3
View File
@@ -22,9 +22,6 @@ GskVulkanCachedGlyph *gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache
gboolean create,
PangoFont *font,
PangoGlyph glyph,
int x,
int y,
float scale);
void gsk_vulkan_glyph_cache_begin_frame (GskVulkanGlyphCache *cache);
+10 -14
View File
@@ -362,6 +362,15 @@ gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
return image;
}
guint
gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *self,
PangoFont *font,
PangoGlyph glyph,
float scale)
{
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, TRUE, font, glyph, scale)->texture_index;
}
GskVulkanImage *
gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
GskVulkanUploader *uploader,
@@ -370,26 +379,13 @@ gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
return g_object_ref (gsk_vulkan_glyph_cache_get_glyph_image (self->glyph_cache, uploader, index));
}
guint
gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *self,
PangoFont *font,
PangoGlyph glyph,
int x,
int y,
float scale)
{
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, TRUE, font, glyph, x, y, scale)->texture_index;
}
GskVulkanCachedGlyph *
gsk_vulkan_renderer_get_cached_glyph (GskVulkanRenderer *self,
PangoFont *font,
PangoGlyph glyph,
int x,
int y,
float scale)
{
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, FALSE, font, glyph, x, y, scale);
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, FALSE, font, glyph, scale);
}
/**
-4
View File
@@ -30,8 +30,6 @@ typedef struct
guint gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *renderer,
PangoFont *font,
PangoGlyph glyph,
int x,
int y,
float scale);
GskVulkanImage * gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
@@ -41,8 +39,6 @@ GskVulkanImage * gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *
GskVulkanCachedGlyph * gsk_vulkan_renderer_get_cached_glyph (GskVulkanRenderer *self,
PangoFont *font,
PangoGlyph glyph,
int x,
int y,
float scale);
+1 -10
View File
@@ -370,7 +370,6 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
int i;
guint count;
guint texture_index;
gint x_position;
GskVulkanRenderer *renderer = GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render));
if (font_has_color_glyphs (font))
@@ -403,17 +402,11 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
op.text.texture_index = G_MAXUINT;
op.text.scale = self->scale_factor;
x_position = 0;
for (i = 0, count = 0; i < num_glyphs; i++)
{
const PangoGlyphInfo *gi = &glyphs[i];
texture_index = gsk_vulkan_renderer_cache_glyph (renderer,
(PangoFont *)font,
gi->glyph,
x_position + gi->geometry.x_offset,
gi->geometry.y_offset,
op.text.scale);
texture_index = gsk_vulkan_renderer_cache_glyph (renderer, (PangoFont *)font, gi->glyph, op.text.scale);
if (op.text.texture_index == G_MAXUINT)
op.text.texture_index = texture_index;
if (texture_index != op.text.texture_index)
@@ -428,8 +421,6 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
}
else
count++;
x_position += gi->geometry.width;
}
if (op.text.texture_index != G_MAXUINT && count != 0)
+3 -8
View File
@@ -127,17 +127,12 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline *pipeline,
if (gi->glyph != PANGO_GLYPH_EMPTY)
{
double cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
double cy = gi->geometry.y_offset / PANGO_SCALE;
double cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
double cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
GskVulkanTextInstance *instance = &instances[count];
GskVulkanCachedGlyph *glyph;
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer,
font,
gi->glyph,
x_position + gi->geometry.x_offset,
gi->geometry.y_offset,
scale);
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer, font, gi->glyph, scale);
instance->tex_rect[0] = glyph->tx;
instance->tex_rect[1] = glyph->ty;

Some files were not shown because too many files have changed in this diff Show More