mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
Merge branch 'wip/gtk4-port' into 'master'
Port sysprof to GTK 4 See merge request GNOME/sysprof!49
This commit is contained in:
@ -97,21 +97,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "libdazzle",
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"--buildtype=debugoptimized"
|
||||
],
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/libdazzle.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "sysprof",
|
||||
"config-opts" : [
|
||||
|
||||
@ -1,20 +1,5 @@
|
||||
<schemalist>
|
||||
<schema id="org.gnome.sysprof3" path="/org/gnome/sysprof/" gettext-domain="sysprof">
|
||||
<key name="window-size" type="(ii)">
|
||||
<default>(-1, -1)</default>
|
||||
<summary>Window size</summary>
|
||||
<description>Window size (width and height).</description>
|
||||
</key>
|
||||
<key name="window-position" type="(ii)">
|
||||
<default>(-1,-1)</default>
|
||||
<summary>Window position</summary>
|
||||
<description>Window position (x and y).</description>
|
||||
</key>
|
||||
<key name="window-maximized" type="b">
|
||||
<default>true</default>
|
||||
<summary>Window maximized</summary>
|
||||
<description>Window maximized state</description>
|
||||
</key>
|
||||
<key name="last-spawn-argv" type="s">
|
||||
<default>''</default>
|
||||
<summary>Last Spawn Program</summary>
|
||||
|
||||
10
meson.build
10
meson.build
@ -8,22 +8,23 @@ project('sysprof', 'c',
|
||||
]
|
||||
)
|
||||
|
||||
symbolic_version = '42.0'
|
||||
symbolic_version = '43.alpha0'
|
||||
|
||||
gnome = import('gnome')
|
||||
pkgconfig = import('pkgconfig')
|
||||
i18n = import('i18n')
|
||||
|
||||
libsysprof_api_version = 4
|
||||
libsysprof_ui_api_version = 5
|
||||
|
||||
version_split = meson.project_version().split('.')
|
||||
datadir = get_option('datadir')
|
||||
datadir_for_pc_file = join_paths('${prefix}', datadir)
|
||||
podir = join_paths(meson.current_source_dir(), 'po')
|
||||
|
||||
glib_req_version = '>= 2.67.4'
|
||||
gtk_req_version = '>= 3.22'
|
||||
glib_req_version = '>= 2.68.0'
|
||||
gtk_req_version = '>= 4.4'
|
||||
polkit_req_version = '>= 0.105'
|
||||
dazzle_req_version = '>= 3.30.0'
|
||||
|
||||
cc = meson.get_compiler('c')
|
||||
|
||||
@ -45,6 +46,7 @@ config_h.set('PACKAGE_TARNAME', 'PACKAGE_STRING')
|
||||
config_h.set('PACKAGE', 'PACKAGE_NAME')
|
||||
config_h.set('VERSION', 'PACKAGE_VERSION')
|
||||
|
||||
|
||||
# Detect and set symbol visibility
|
||||
if get_option('default_library') != 'static'
|
||||
if host_machine.system() == 'windows'
|
||||
|
||||
@ -1,7 +1,3 @@
|
||||
SysprofDisplay dzlmultipaned {
|
||||
-DzlMultiPaned-handle-size: 0;
|
||||
}
|
||||
|
||||
SysprofVisualizer {
|
||||
background: @content_view_bg;
|
||||
}
|
||||
@ -34,11 +30,11 @@ SysprofVisualizersFrame scrollbar.horizontal {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
SysprofVisualizersFrame scrollbar.horizontal contents trough {
|
||||
SysprofVisualizersFrame scrollbar.horizontal range trough {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
SysprofVisualizersFrame scrollbar.horizontal contents trough slider {
|
||||
SysprofVisualizersFrame scrollbar.horizontal range trough slider {
|
||||
margin-left: 1px;
|
||||
margin-right: 1px;
|
||||
padding: 6px;
|
||||
@ -81,10 +77,6 @@ SysprofVisualizersFrame .left-column .small-button.flat:hover {
|
||||
border-color: @borders;
|
||||
}
|
||||
|
||||
SysprofDisplay > dzlmultipaned > :nth-child(2) {
|
||||
border-top: 1px solid @borders;
|
||||
}
|
||||
|
||||
SysprofVisualizersFrame .selection {
|
||||
border-radius: 3px;
|
||||
background-color: alpha(@theme_selected_bg_color, 0.35);
|
||||
|
||||
35
src/libsysprof-ui/egg-handle-private.h
Normal file
35
src/libsysprof-ui/egg-handle-private.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* egg-handle.h
|
||||
*
|
||||
* Copyright 2021 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This file 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 3 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file 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 General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EGG_TYPE_HANDLE (egg_handle_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (EggHandle, egg_handle, EGG, HANDLE, GtkWidget)
|
||||
|
||||
GtkWidget *egg_handle_new (GtkPositionType position);
|
||||
void egg_handle_set_position (EggHandle *self,
|
||||
GtkPositionType position);
|
||||
|
||||
G_END_DECLS
|
||||
145
src/libsysprof-ui/egg-handle.c
Normal file
145
src/libsysprof-ui/egg-handle.c
Normal file
@ -0,0 +1,145 @@
|
||||
/* egg-handle.c
|
||||
*
|
||||
* Copyright 2021 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This file 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 3 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file 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 General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "egg-handle-private.h"
|
||||
|
||||
#define EXTRA_SIZE 8
|
||||
|
||||
struct _EggHandle
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
GtkWidget *separator;
|
||||
GtkPositionType position : 3;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (EggHandle, egg_handle, GTK_TYPE_WIDGET)
|
||||
|
||||
static gboolean
|
||||
egg_handle_contains (GtkWidget *widget,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
EggHandle *self = (EggHandle *)widget;
|
||||
graphene_rect_t area;
|
||||
|
||||
g_assert (EGG_IS_HANDLE (self));
|
||||
|
||||
if (!gtk_widget_compute_bounds (GTK_WIDGET (self->separator),
|
||||
GTK_WIDGET (self),
|
||||
&area))
|
||||
return FALSE;
|
||||
|
||||
switch (self->position)
|
||||
{
|
||||
case GTK_POS_LEFT:
|
||||
area.origin.x -= EXTRA_SIZE;
|
||||
area.size.width = EXTRA_SIZE;
|
||||
break;
|
||||
|
||||
case GTK_POS_RIGHT:
|
||||
area.size.width = EXTRA_SIZE;
|
||||
break;
|
||||
|
||||
case GTK_POS_TOP:
|
||||
area.origin.y -= EXTRA_SIZE;
|
||||
area.size.height = EXTRA_SIZE;
|
||||
break;
|
||||
|
||||
case GTK_POS_BOTTOM:
|
||||
area.size.height = EXTRA_SIZE;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
return graphene_rect_contains_point (&area, &GRAPHENE_POINT_INIT (x, y));
|
||||
}
|
||||
|
||||
static void
|
||||
egg_handle_dispose (GObject *object)
|
||||
{
|
||||
EggHandle *self = (EggHandle *)object;
|
||||
|
||||
g_clear_pointer (&self->separator, gtk_widget_unparent);
|
||||
|
||||
G_OBJECT_CLASS (egg_handle_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_handle_class_init (EggHandleClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = egg_handle_dispose;
|
||||
|
||||
widget_class->contains = egg_handle_contains;
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_handle_init (EggHandle *self)
|
||||
{
|
||||
self->separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_widget_set_parent (GTK_WIDGET (self->separator), GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
void
|
||||
egg_handle_set_position (EggHandle *self,
|
||||
GtkPositionType position)
|
||||
{
|
||||
g_return_if_fail (EGG_IS_HANDLE (self));
|
||||
|
||||
self->position = position;
|
||||
|
||||
switch (position)
|
||||
{
|
||||
case GTK_POS_LEFT:
|
||||
case GTK_POS_RIGHT:
|
||||
gtk_widget_set_cursor_from_name (GTK_WIDGET (self), "col-resize");
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (self->separator), GTK_ORIENTATION_VERTICAL);
|
||||
break;
|
||||
|
||||
case GTK_POS_TOP:
|
||||
case GTK_POS_BOTTOM:
|
||||
gtk_widget_set_cursor_from_name (GTK_WIDGET (self), "row-resize");
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (self->separator), GTK_ORIENTATION_HORIZONTAL);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
egg_handle_new (GtkPositionType position)
|
||||
{
|
||||
EggHandle *self;
|
||||
|
||||
self = g_object_new (EGG_TYPE_HANDLE, NULL);
|
||||
egg_handle_set_position (self, position);
|
||||
|
||||
return GTK_WIDGET (self);
|
||||
}
|
||||
48
src/libsysprof-ui/egg-paned-private.h
Normal file
48
src/libsysprof-ui/egg-paned-private.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* egg-paned.h
|
||||
*
|
||||
* Copyright 2021 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This file 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 3 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file 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 General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EGG_TYPE_PANED (egg_paned_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (EggPaned, egg_paned, EGG, PANED, GtkWidget)
|
||||
|
||||
GtkWidget *egg_paned_new (void);
|
||||
void egg_paned_append (EggPaned *self,
|
||||
GtkWidget *child);
|
||||
void egg_paned_prepend (EggPaned *self,
|
||||
GtkWidget *child);
|
||||
void egg_paned_insert (EggPaned *self,
|
||||
int position,
|
||||
GtkWidget *child);
|
||||
void egg_paned_insert_after (EggPaned *self,
|
||||
GtkWidget *child,
|
||||
GtkWidget *sibling);
|
||||
void egg_paned_remove (EggPaned *self,
|
||||
GtkWidget *child);
|
||||
guint egg_paned_get_n_children (EggPaned *self);
|
||||
GtkWidget *egg_paned_get_nth_child (EggPaned *self,
|
||||
guint nth);
|
||||
|
||||
G_END_DECLS
|
||||
593
src/libsysprof-ui/egg-paned.c
Normal file
593
src/libsysprof-ui/egg-paned.c
Normal file
@ -0,0 +1,593 @@
|
||||
/* egg-paned.c
|
||||
*
|
||||
* Copyright 2021 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This file 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 3 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file 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 General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "egg-paned-private.h"
|
||||
#include "egg-resizer-private.h"
|
||||
|
||||
struct _EggPaned
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
GtkOrientation orientation;
|
||||
};
|
||||
|
||||
static void buildable_iface_init (GtkBuildableIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (EggPaned, egg_paned, GTK_TYPE_WIDGET,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, buildable_iface_init)
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL))
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
N_PROPS,
|
||||
|
||||
PROP_ORIENTATION,
|
||||
};
|
||||
|
||||
static void
|
||||
update_orientation (GtkWidget *widget,
|
||||
GtkOrientation orientation)
|
||||
{
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
gtk_widget_remove_css_class (widget, "vertical");
|
||||
gtk_widget_add_css_class (widget, "horizontal");
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_remove_css_class (widget, "horizontal");
|
||||
gtk_widget_add_css_class (widget, "vertical");
|
||||
}
|
||||
|
||||
gtk_accessible_update_property (GTK_ACCESSIBLE (widget),
|
||||
GTK_ACCESSIBLE_PROPERTY_ORIENTATION, orientation,
|
||||
-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* egg_paned_new:
|
||||
*
|
||||
* Create a new #EggPaned.
|
||||
*
|
||||
* Returns: (transfer full): a newly created #EggPaned
|
||||
*/
|
||||
GtkWidget *
|
||||
egg_paned_new (void)
|
||||
{
|
||||
return g_object_new (EGG_TYPE_PANED, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_paned_set_orientation (EggPaned *self,
|
||||
GtkOrientation orientation)
|
||||
{
|
||||
GtkPositionType pos;
|
||||
|
||||
g_assert (EGG_IS_PANED (self));
|
||||
g_assert (orientation == GTK_ORIENTATION_HORIZONTAL ||
|
||||
orientation == GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
if (self->orientation == orientation)
|
||||
return;
|
||||
|
||||
self->orientation = orientation;
|
||||
|
||||
if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
pos = GTK_POS_LEFT;
|
||||
else
|
||||
pos = GTK_POS_TOP;
|
||||
|
||||
for (GtkWidget *child = gtk_widget_get_last_child (GTK_WIDGET (self));
|
||||
child != NULL;
|
||||
child = gtk_widget_get_prev_sibling (child))
|
||||
{
|
||||
g_assert (EGG_IS_RESIZER (child));
|
||||
|
||||
egg_resizer_set_position (EGG_RESIZER (child), pos);
|
||||
}
|
||||
|
||||
update_orientation (GTK_WIDGET (self), self->orientation);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
g_object_notify (G_OBJECT (self), "orientation");
|
||||
}
|
||||
|
||||
static void
|
||||
egg_paned_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
EggPaned *self = (EggPaned *)widget;
|
||||
|
||||
g_assert (EGG_IS_PANED (self));
|
||||
|
||||
*minimum = 0;
|
||||
*natural = 0;
|
||||
*minimum_baseline = -1;
|
||||
*natural_baseline = -1;
|
||||
|
||||
for (GtkWidget *child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
int child_min, child_nat;
|
||||
|
||||
gtk_widget_measure (child, orientation, for_size, &child_min, &child_nat, NULL, NULL);
|
||||
|
||||
if (orientation == self->orientation)
|
||||
{
|
||||
*minimum += child_min;
|
||||
*natural += child_nat;
|
||||
}
|
||||
else
|
||||
{
|
||||
*minimum = MAX (*minimum, child_min);
|
||||
*natural = MAX (*natural, child_nat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkRequisition min_request;
|
||||
GtkRequisition nat_request;
|
||||
GtkAllocation alloc;
|
||||
} ChildAllocation;
|
||||
|
||||
static void
|
||||
egg_paned_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
EggPaned *self = (EggPaned *)widget;
|
||||
ChildAllocation *allocs;
|
||||
ChildAllocation *last_alloc = NULL;
|
||||
GtkOrientation orientation;
|
||||
guint n_children = 0;
|
||||
guint n_expand = 0;
|
||||
guint i;
|
||||
int extra_width = width;
|
||||
int extra_height = height;
|
||||
int expand_width;
|
||||
int expand_height;
|
||||
int x, y;
|
||||
|
||||
g_assert (EGG_IS_PANED (self));
|
||||
|
||||
GTK_WIDGET_CLASS (egg_paned_parent_class)->size_allocate (widget, width, height, baseline);
|
||||
|
||||
n_children = egg_paned_get_n_children (self);
|
||||
|
||||
if (n_children == 1)
|
||||
{
|
||||
GtkWidget *child = gtk_widget_get_first_child (widget);
|
||||
GtkAllocation alloc = { 0, 0, width, height };
|
||||
|
||||
if (gtk_widget_get_visible (child))
|
||||
{
|
||||
gtk_widget_size_allocate (child, &alloc, -1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (self));
|
||||
allocs = g_newa (ChildAllocation, n_children);
|
||||
memset (allocs, 0, sizeof *allocs * n_children);
|
||||
|
||||
/* Give min size to each of the children */
|
||||
i = 0;
|
||||
for (GtkWidget *child = gtk_widget_get_first_child (GTK_WIDGET (self));
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child), i++)
|
||||
{
|
||||
ChildAllocation *child_alloc = &allocs[i];
|
||||
|
||||
if (!gtk_widget_get_visible (child))
|
||||
continue;
|
||||
|
||||
gtk_widget_measure (child, GTK_ORIENTATION_HORIZONTAL, height,
|
||||
&child_alloc->min_request.width,
|
||||
&child_alloc->nat_request.width,
|
||||
NULL, NULL);
|
||||
gtk_widget_measure (child, GTK_ORIENTATION_VERTICAL, width,
|
||||
&child_alloc->min_request.height,
|
||||
&child_alloc->nat_request.height,
|
||||
NULL, NULL);
|
||||
|
||||
child_alloc->alloc.width = child_alloc->min_request.width;
|
||||
child_alloc->alloc.height = child_alloc->min_request.height;
|
||||
|
||||
n_expand += gtk_widget_compute_expand (child, orientation);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
extra_width -= child_alloc->alloc.width;
|
||||
child_alloc->alloc.height = height;
|
||||
}
|
||||
else
|
||||
{
|
||||
extra_height -= child_alloc->alloc.height;
|
||||
child_alloc->alloc.width = width;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now try to distribute extra space for natural size */
|
||||
i = 0;
|
||||
for (GtkWidget *child = gtk_widget_get_first_child (GTK_WIDGET (self));
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child), i++)
|
||||
{
|
||||
ChildAllocation *child_alloc = &allocs[i];
|
||||
|
||||
if (!gtk_widget_get_visible (child))
|
||||
continue;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
int taken = MIN (extra_width, child_alloc->nat_request.width - child_alloc->alloc.width);
|
||||
|
||||
if (taken > 0)
|
||||
{
|
||||
child_alloc->alloc.width += taken;
|
||||
extra_width -= taken;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int taken = MIN (extra_height, child_alloc->nat_request.height - child_alloc->alloc.height);
|
||||
|
||||
if (taken > 0)
|
||||
{
|
||||
child_alloc->alloc.height += taken;
|
||||
extra_height -= taken;
|
||||
}
|
||||
}
|
||||
|
||||
last_alloc = child_alloc;
|
||||
}
|
||||
|
||||
/* Now give extra space for those that expand */
|
||||
expand_width = n_expand ? extra_width / n_expand : 0;
|
||||
expand_height = n_expand ? extra_height / n_expand : 0;
|
||||
i = n_children;
|
||||
for (GtkWidget *child = gtk_widget_get_last_child (GTK_WIDGET (self));
|
||||
child != NULL;
|
||||
child = gtk_widget_get_prev_sibling (child), i--)
|
||||
{
|
||||
ChildAllocation *child_alloc = &allocs[i-1];
|
||||
|
||||
if (!gtk_widget_get_visible (child))
|
||||
continue;
|
||||
|
||||
if (!gtk_widget_compute_expand (child, orientation))
|
||||
continue;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
child_alloc->alloc.width += expand_width;
|
||||
extra_width -= expand_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
child_alloc->alloc.height += expand_height;
|
||||
extra_height -= expand_height;
|
||||
}
|
||||
}
|
||||
|
||||
/* Give any leftover to the last visible child */
|
||||
if (last_alloc)
|
||||
{
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
last_alloc->alloc.width += extra_width;
|
||||
else
|
||||
last_alloc->alloc.height += extra_height;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
x = 0;
|
||||
y = 0;
|
||||
for (GtkWidget *child = gtk_widget_get_first_child (GTK_WIDGET (self));
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child), i++)
|
||||
{
|
||||
ChildAllocation *child_alloc = &allocs[i];
|
||||
|
||||
child_alloc->alloc.x = x;
|
||||
child_alloc->alloc.y = y;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
x += child_alloc->alloc.width;
|
||||
else
|
||||
y += child_alloc->alloc.height;
|
||||
|
||||
gtk_widget_size_allocate (child, &child_alloc->alloc, -1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
egg_paned_dispose (GObject *object)
|
||||
{
|
||||
EggPaned *self = (EggPaned *)object;
|
||||
GtkWidget *child;
|
||||
|
||||
child = gtk_widget_get_first_child (GTK_WIDGET (self));
|
||||
while (child)
|
||||
{
|
||||
GtkWidget *next = gtk_widget_get_next_sibling (child);
|
||||
gtk_widget_unparent (child);
|
||||
child = next;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (egg_paned_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_paned_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EggPaned *self = EGG_PANED (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ORIENTATION:
|
||||
g_value_set_enum (value, self->orientation);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
egg_paned_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EggPaned *self = EGG_PANED (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ORIENTATION:
|
||||
egg_paned_set_orientation (self, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
egg_paned_class_init (EggPanedClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = egg_paned_dispose;
|
||||
object_class->get_property = egg_paned_get_property;
|
||||
object_class->set_property = egg_paned_set_property;
|
||||
|
||||
widget_class->measure = egg_paned_measure;
|
||||
widget_class->size_allocate = egg_paned_size_allocate;
|
||||
|
||||
g_object_class_override_property (object_class, PROP_ORIENTATION, "orientation");
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "eggpaned");
|
||||
}
|
||||
|
||||
static void
|
||||
egg_paned_init (EggPaned *self)
|
||||
{
|
||||
self->orientation = GTK_ORIENTATION_HORIZONTAL;
|
||||
|
||||
update_orientation (GTK_WIDGET (self), self->orientation);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_paned_update_handles (EggPaned *self)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
g_assert (EGG_IS_PANED (self));
|
||||
|
||||
for (child = gtk_widget_get_first_child (GTK_WIDGET (self));
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
GtkWidget *handle;
|
||||
|
||||
g_assert (EGG_IS_RESIZER (child));
|
||||
|
||||
if ((handle = egg_resizer_get_handle (EGG_RESIZER (child))))
|
||||
gtk_widget_show (handle);
|
||||
}
|
||||
|
||||
if ((child = gtk_widget_get_last_child (GTK_WIDGET (self))))
|
||||
{
|
||||
GtkWidget *handle = egg_resizer_get_handle (EGG_RESIZER (child));
|
||||
gtk_widget_hide (handle);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
egg_paned_remove (EggPaned *self,
|
||||
GtkWidget *child)
|
||||
{
|
||||
GtkWidget *resizer;
|
||||
|
||||
g_return_if_fail (EGG_IS_PANED (self));
|
||||
g_return_if_fail (GTK_IS_WIDGET (child));
|
||||
|
||||
resizer = gtk_widget_get_ancestor (child, EGG_TYPE_RESIZER);
|
||||
g_return_if_fail (resizer != NULL &&
|
||||
gtk_widget_get_parent (resizer) == GTK_WIDGET (self));
|
||||
gtk_widget_unparent (resizer);
|
||||
egg_paned_update_handles (self);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
void
|
||||
egg_paned_insert (EggPaned *self,
|
||||
int position,
|
||||
GtkWidget *child)
|
||||
{
|
||||
GtkPositionType pos;
|
||||
GtkWidget *resizer;
|
||||
|
||||
g_return_if_fail (EGG_IS_PANED (self));
|
||||
g_return_if_fail (GTK_IS_WIDGET (child));
|
||||
g_return_if_fail (gtk_widget_get_parent (child) == NULL);
|
||||
|
||||
if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
pos = GTK_POS_LEFT;
|
||||
else
|
||||
pos = GTK_POS_TOP;
|
||||
|
||||
resizer = egg_resizer_new (pos);
|
||||
egg_resizer_set_child (EGG_RESIZER (resizer), child);
|
||||
|
||||
if (position < 0)
|
||||
gtk_widget_insert_before (GTK_WIDGET (resizer), GTK_WIDGET (self), NULL);
|
||||
else if (position == 0)
|
||||
gtk_widget_insert_after (GTK_WIDGET (resizer), GTK_WIDGET (self), NULL);
|
||||
else
|
||||
{
|
||||
GtkWidget *sibling = gtk_widget_get_first_child (GTK_WIDGET (self));
|
||||
|
||||
for (int i = position; i > 0 && sibling != NULL; i--)
|
||||
sibling = gtk_widget_get_next_sibling (sibling);
|
||||
|
||||
gtk_widget_insert_before (GTK_WIDGET (resizer), GTK_WIDGET (self), sibling);
|
||||
}
|
||||
|
||||
egg_paned_update_handles (self);
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
void
|
||||
egg_paned_append (EggPaned *self,
|
||||
GtkWidget *child)
|
||||
{
|
||||
egg_paned_insert (self, -1, child);
|
||||
}
|
||||
|
||||
void
|
||||
egg_paned_prepend (EggPaned *self,
|
||||
GtkWidget *child)
|
||||
{
|
||||
egg_paned_insert (self, 0, child);
|
||||
}
|
||||
|
||||
void
|
||||
egg_paned_insert_after (EggPaned *self,
|
||||
GtkWidget *child,
|
||||
GtkWidget *sibling)
|
||||
{
|
||||
int position = 0;
|
||||
|
||||
g_return_if_fail (EGG_IS_PANED (self));
|
||||
g_return_if_fail (GTK_IS_WIDGET (child));
|
||||
g_return_if_fail (!sibling || GTK_IS_WIDGET (sibling));
|
||||
|
||||
if (sibling == NULL)
|
||||
{
|
||||
egg_paned_prepend (self, child);
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: We should reverse insert() to call this */
|
||||
|
||||
for (GtkWidget *ancestor = gtk_widget_get_first_child (GTK_WIDGET (self));
|
||||
ancestor != NULL;
|
||||
ancestor = gtk_widget_get_next_sibling (ancestor))
|
||||
{
|
||||
position++;
|
||||
|
||||
if (sibling == ancestor || gtk_widget_is_ancestor (sibling, ancestor))
|
||||
break;
|
||||
}
|
||||
|
||||
egg_paned_insert (self, position, child);
|
||||
}
|
||||
|
||||
guint
|
||||
egg_paned_get_n_children (EggPaned *self)
|
||||
{
|
||||
guint count = 0;
|
||||
|
||||
for (GtkWidget *child = gtk_widget_get_first_child (GTK_WIDGET (self));
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
count++;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
egg_paned_get_nth_child (EggPaned *self,
|
||||
guint nth)
|
||||
{
|
||||
g_return_val_if_fail (EGG_IS_PANED (self), NULL);
|
||||
|
||||
for (GtkWidget *child = gtk_widget_get_first_child (GTK_WIDGET (self));
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
g_assert (EGG_IS_RESIZER (child));
|
||||
|
||||
if (nth == 0)
|
||||
return egg_resizer_get_child (EGG_RESIZER (child));
|
||||
|
||||
nth--;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
egg_paned_add_child (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const char *type)
|
||||
{
|
||||
if (GTK_IS_WIDGET (child))
|
||||
egg_paned_append (EGG_PANED (buildable), GTK_WIDGET (child));
|
||||
else
|
||||
g_warning ("Cannot add child of type %s to %s",
|
||||
G_OBJECT_TYPE_NAME (child),
|
||||
G_OBJECT_TYPE_NAME (buildable));
|
||||
}
|
||||
|
||||
static void
|
||||
buildable_iface_init (GtkBuildableIface *iface)
|
||||
{
|
||||
iface->add_child = egg_paned_add_child;
|
||||
}
|
||||
40
src/libsysprof-ui/egg-resizer-private.h
Normal file
40
src/libsysprof-ui/egg-resizer-private.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* egg-resizer.h
|
||||
*
|
||||
* Copyright 2021 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This file 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 3 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file 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 General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EGG_TYPE_RESIZER (egg_resizer_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (EggResizer, egg_resizer, EGG, RESIZER, GtkWidget)
|
||||
|
||||
GtkWidget *egg_resizer_new (GtkPositionType position);
|
||||
GtkPositionType egg_resizer_get_position (EggResizer *self);
|
||||
void egg_resizer_set_position (EggResizer *self,
|
||||
GtkPositionType position);
|
||||
GtkWidget *egg_resizer_get_child (EggResizer *self);
|
||||
void egg_resizer_set_child (EggResizer *self,
|
||||
GtkWidget *child);
|
||||
GtkWidget *egg_resizer_get_handle (EggResizer *self);
|
||||
|
||||
G_END_DECLS
|
||||
495
src/libsysprof-ui/egg-resizer.c
Normal file
495
src/libsysprof-ui/egg-resizer.c
Normal file
@ -0,0 +1,495 @@
|
||||
/* egg-resizer.c
|
||||
*
|
||||
* Copyright 2021 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This file 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 3 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file 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 General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "egg-handle-private.h"
|
||||
#include "egg-resizer-private.h"
|
||||
|
||||
#define HANDLE_SIZE 8
|
||||
|
||||
struct _EggResizer
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
EggHandle *handle;
|
||||
GtkWidget *child;
|
||||
|
||||
double drag_orig_size;
|
||||
double drag_position;
|
||||
|
||||
GtkPositionType position : 3;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (EggResizer, egg_resizer, GTK_TYPE_WIDGET)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_CHILD,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
static void
|
||||
egg_resizer_drag_begin_cb (EggResizer *self,
|
||||
double start_x,
|
||||
double start_y,
|
||||
GtkGestureDrag *drag)
|
||||
{
|
||||
GtkAllocation child_alloc;
|
||||
GtkAllocation handle_alloc;
|
||||
|
||||
g_assert (EGG_IS_RESIZER (self));
|
||||
g_assert (GTK_IS_GESTURE_DRAG (drag));
|
||||
|
||||
if (self->child == NULL)
|
||||
return;
|
||||
|
||||
switch (self->position)
|
||||
{
|
||||
case GTK_POS_LEFT:
|
||||
if (start_x > gtk_widget_get_width (GTK_WIDGET (self)) - HANDLE_SIZE)
|
||||
goto start_drag;
|
||||
break;
|
||||
|
||||
case GTK_POS_RIGHT:
|
||||
if (start_x <= HANDLE_SIZE)
|
||||
goto start_drag;
|
||||
break;
|
||||
|
||||
case GTK_POS_TOP:
|
||||
if (start_y > gtk_widget_get_height (GTK_WIDGET (self)) - HANDLE_SIZE)
|
||||
goto start_drag;
|
||||
break;
|
||||
|
||||
case GTK_POS_BOTTOM:
|
||||
if (start_y <= HANDLE_SIZE)
|
||||
goto start_drag;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_gesture_set_state (GTK_GESTURE (drag),
|
||||
GTK_EVENT_SEQUENCE_DENIED);
|
||||
|
||||
return;
|
||||
|
||||
start_drag:
|
||||
|
||||
gtk_widget_get_allocation (self->child, &child_alloc);
|
||||
gtk_widget_get_allocation (GTK_WIDGET (self->handle), &handle_alloc);
|
||||
|
||||
if (self->position == GTK_POS_LEFT ||
|
||||
self->position == GTK_POS_RIGHT)
|
||||
{
|
||||
self->drag_orig_size = child_alloc.width + handle_alloc.width;
|
||||
gtk_widget_set_hexpand (self->child, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->drag_orig_size = child_alloc.height + handle_alloc.height;
|
||||
gtk_widget_set_vexpand (self->child, FALSE);
|
||||
}
|
||||
|
||||
self->drag_position = self->drag_orig_size;
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
egg_resizer_drag_update_cb (EggResizer *self,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
GtkGestureDrag *drag)
|
||||
{
|
||||
g_assert (EGG_IS_RESIZER (self));
|
||||
g_assert (GTK_IS_GESTURE_DRAG (drag));
|
||||
|
||||
if (self->position == GTK_POS_LEFT)
|
||||
self->drag_position = self->drag_orig_size + offset_x;
|
||||
else if (self->position == GTK_POS_RIGHT)
|
||||
self->drag_position = gtk_widget_get_width (GTK_WIDGET (self)) - offset_x;
|
||||
else if (self->position == GTK_POS_TOP)
|
||||
self->drag_position = self->drag_orig_size + offset_y;
|
||||
else if (self->position == GTK_POS_BOTTOM)
|
||||
self->drag_position = gtk_widget_get_height (GTK_WIDGET (self)) - offset_y;
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
egg_resizer_drag_end_cb (EggResizer *self,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
GtkGestureDrag *drag)
|
||||
{
|
||||
g_assert (EGG_IS_RESIZER (self));
|
||||
g_assert (GTK_IS_GESTURE_DRAG (drag));
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
egg_resizer_new (GtkPositionType position)
|
||||
{
|
||||
EggResizer *self;
|
||||
|
||||
self = g_object_new (EGG_TYPE_RESIZER, NULL);
|
||||
self->position = position;
|
||||
self->handle = EGG_HANDLE (egg_handle_new (position));
|
||||
gtk_widget_set_parent (GTK_WIDGET (self->handle), GTK_WIDGET (self));
|
||||
|
||||
return GTK_WIDGET (self);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_resizer_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
EggResizer *self = (EggResizer *)widget;
|
||||
|
||||
g_assert (EGG_IS_RESIZER (self));
|
||||
|
||||
*minimum = 0;
|
||||
*natural = 0;
|
||||
*minimum_baseline = -1;
|
||||
*natural_baseline = -1;
|
||||
|
||||
if (self->child != NULL)
|
||||
gtk_widget_measure (self->child,
|
||||
orientation,
|
||||
for_size,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
|
||||
if ((orientation == GTK_ORIENTATION_HORIZONTAL &&
|
||||
(self->position == GTK_POS_LEFT ||
|
||||
self->position == GTK_POS_RIGHT)) ||
|
||||
(orientation == GTK_ORIENTATION_VERTICAL &&
|
||||
(self->position == GTK_POS_TOP ||
|
||||
self->position == GTK_POS_BOTTOM)))
|
||||
{
|
||||
int handle_min, handle_nat;
|
||||
|
||||
if (self->drag_position != 0)
|
||||
{
|
||||
if (self->drag_position > *minimum)
|
||||
*natural = self->drag_position;
|
||||
else if (self->drag_position < *minimum)
|
||||
*natural = *minimum;
|
||||
}
|
||||
|
||||
if (gtk_widget_get_visible (GTK_WIDGET (self->handle)))
|
||||
{
|
||||
gtk_widget_measure (GTK_WIDGET (self->handle),
|
||||
orientation, for_size,
|
||||
&handle_min, &handle_nat,
|
||||
NULL, NULL);
|
||||
|
||||
*minimum += handle_min;
|
||||
*natural += handle_nat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
egg_resizer_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
EggResizer *self = (EggResizer *)widget;
|
||||
GtkOrientation orientation;
|
||||
GtkAllocation child_alloc;
|
||||
GtkAllocation handle_alloc;
|
||||
int handle_min = 0, handle_nat = 0;
|
||||
|
||||
g_assert (EGG_IS_RESIZER (self));
|
||||
|
||||
if (self->position == GTK_POS_LEFT ||
|
||||
self->position == GTK_POS_RIGHT)
|
||||
orientation = GTK_ORIENTATION_HORIZONTAL;
|
||||
else
|
||||
orientation = GTK_ORIENTATION_VERTICAL;
|
||||
|
||||
if (gtk_widget_get_visible (GTK_WIDGET (self->handle)))
|
||||
gtk_widget_measure (GTK_WIDGET (self->handle),
|
||||
orientation,
|
||||
-1,
|
||||
&handle_min, &handle_nat,
|
||||
NULL, NULL);
|
||||
|
||||
switch (self->position)
|
||||
{
|
||||
case GTK_POS_LEFT:
|
||||
handle_alloc.x = width - handle_min;
|
||||
handle_alloc.width = handle_min;
|
||||
handle_alloc.y = 0;
|
||||
handle_alloc.height = height;
|
||||
child_alloc.x = 0;
|
||||
child_alloc.y = 0;
|
||||
child_alloc.width = width - handle_min;
|
||||
child_alloc.height = height;
|
||||
break;
|
||||
|
||||
case GTK_POS_RIGHT:
|
||||
handle_alloc.x = 0;
|
||||
handle_alloc.width = handle_min;
|
||||
handle_alloc.y = 0;
|
||||
handle_alloc.height = height;
|
||||
child_alloc.x = handle_min;
|
||||
child_alloc.y = 0;
|
||||
child_alloc.width = width - handle_min;
|
||||
child_alloc.height = height;
|
||||
break;
|
||||
|
||||
case GTK_POS_TOP:
|
||||
handle_alloc.x = 0;
|
||||
handle_alloc.width = width;
|
||||
handle_alloc.y = height - handle_min;
|
||||
handle_alloc.height = handle_min;
|
||||
child_alloc.x = 0;
|
||||
child_alloc.y = 0;
|
||||
child_alloc.width = width;
|
||||
child_alloc.height = height - handle_min;
|
||||
break;
|
||||
|
||||
case GTK_POS_BOTTOM:
|
||||
handle_alloc.x = 0;
|
||||
handle_alloc.width = width;
|
||||
handle_alloc.y = 0;
|
||||
handle_alloc.height = handle_min;
|
||||
child_alloc.x = 0;
|
||||
child_alloc.y = handle_min;
|
||||
child_alloc.width = width;
|
||||
child_alloc.height = height - handle_min;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (gtk_widget_get_mapped (GTK_WIDGET (self->handle)))
|
||||
gtk_widget_size_allocate (GTK_WIDGET (self->handle), &handle_alloc, -1);
|
||||
|
||||
if (self->child != NULL &&
|
||||
gtk_widget_get_mapped (self->child))
|
||||
gtk_widget_size_allocate (self->child, &child_alloc, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_resizer_compute_expand (GtkWidget *widget,
|
||||
gboolean *hexpand,
|
||||
gboolean *vexpand)
|
||||
{
|
||||
EggResizer *self = EGG_RESIZER (widget);
|
||||
|
||||
if (self->child != NULL)
|
||||
{
|
||||
*hexpand = gtk_widget_compute_expand (self->child, GTK_ORIENTATION_HORIZONTAL);
|
||||
*vexpand = gtk_widget_compute_expand (self->child, GTK_ORIENTATION_VERTICAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
*hexpand = FALSE;
|
||||
*vexpand = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
egg_resizer_dispose (GObject *object)
|
||||
{
|
||||
EggResizer *self = (EggResizer *)object;
|
||||
|
||||
if (self->handle)
|
||||
gtk_widget_unparent (GTK_WIDGET (self->handle));
|
||||
self->handle = NULL;
|
||||
|
||||
if (self->child)
|
||||
gtk_widget_unparent (self->child);
|
||||
self->child = NULL;
|
||||
|
||||
G_OBJECT_CLASS (egg_resizer_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_resizer_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EggResizer *self = EGG_RESIZER (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CHILD:
|
||||
g_value_set_object (value, egg_resizer_get_child (self));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
egg_resizer_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EggResizer *self = EGG_RESIZER (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CHILD:
|
||||
egg_resizer_set_child (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
egg_resizer_class_init (EggResizerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = egg_resizer_dispose;
|
||||
object_class->get_property = egg_resizer_get_property;
|
||||
object_class->set_property = egg_resizer_set_property;
|
||||
|
||||
widget_class->compute_expand = egg_resizer_compute_expand;
|
||||
widget_class->measure = egg_resizer_measure;
|
||||
widget_class->size_allocate = egg_resizer_size_allocate;
|
||||
|
||||
properties [PROP_CHILD] =
|
||||
g_param_spec_object ("child",
|
||||
"Child",
|
||||
"Child",
|
||||
GTK_TYPE_WIDGET,
|
||||
(G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "eggresizer");
|
||||
}
|
||||
|
||||
static void
|
||||
egg_resizer_init (EggResizer *self)
|
||||
{
|
||||
GtkGesture *gesture;
|
||||
|
||||
gesture = gtk_gesture_drag_new ();
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), GTK_PHASE_CAPTURE);
|
||||
g_signal_connect_object (gesture,
|
||||
"drag-begin",
|
||||
G_CALLBACK (egg_resizer_drag_begin_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (gesture,
|
||||
"drag-update",
|
||||
G_CALLBACK (egg_resizer_drag_update_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (gesture,
|
||||
"drag-end",
|
||||
G_CALLBACK (egg_resizer_drag_end_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (gesture));
|
||||
}
|
||||
|
||||
/**
|
||||
* egg_resizer_get_child:
|
||||
* @self: a #EggResizer
|
||||
*
|
||||
* Gets the child widget of the resizer.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): A #GtkWidget or %NULL
|
||||
*/
|
||||
GtkWidget *
|
||||
egg_resizer_get_child (EggResizer *self)
|
||||
{
|
||||
g_return_val_if_fail (EGG_IS_RESIZER (self), NULL);
|
||||
|
||||
return self->child;
|
||||
}
|
||||
|
||||
void
|
||||
egg_resizer_set_child (EggResizer *self,
|
||||
GtkWidget *child)
|
||||
{
|
||||
g_return_if_fail (EGG_IS_RESIZER (self));
|
||||
g_return_if_fail (!child || GTK_IS_WIDGET (child));
|
||||
|
||||
if (child == self->child)
|
||||
return;
|
||||
|
||||
g_clear_pointer (&self->child, gtk_widget_unparent);
|
||||
|
||||
self->child = child;
|
||||
|
||||
if (self->child != NULL)
|
||||
gtk_widget_insert_before (self->child,
|
||||
GTK_WIDGET (self),
|
||||
GTK_WIDGET (self->handle));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CHILD]);
|
||||
}
|
||||
|
||||
GtkPositionType
|
||||
egg_resizer_get_position (EggResizer *self)
|
||||
{
|
||||
g_return_val_if_fail (EGG_IS_RESIZER (self), 0);
|
||||
|
||||
return self->position;
|
||||
}
|
||||
|
||||
void
|
||||
egg_resizer_set_position (EggResizer *self,
|
||||
GtkPositionType position)
|
||||
{
|
||||
g_return_if_fail (EGG_IS_RESIZER (self));
|
||||
|
||||
if (position != self->position)
|
||||
{
|
||||
self->position = position;
|
||||
|
||||
egg_handle_set_position (self->handle, position);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
}
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
egg_resizer_get_handle (EggResizer *self)
|
||||
{
|
||||
g_return_val_if_fail (EGG_IS_RESIZER (self), NULL);
|
||||
|
||||
return GTK_WIDGET (self->handle);
|
||||
}
|
||||
781
src/libsysprof-ui/egg-three-grid.c
Normal file
781
src/libsysprof-ui/egg-three-grid.c
Normal file
@ -0,0 +1,781 @@
|
||||
/* egg-three-grid.c
|
||||
*
|
||||
* Copyright (C) 2016 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define G_LOG_DOMAIN "egg-three-grid"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
|
||||
#include "egg-three-grid.h"
|
||||
|
||||
struct _EggThreeGridChild
|
||||
{
|
||||
GtkLayoutChild parent_instance;
|
||||
EggThreeGridColumn column;
|
||||
int row;
|
||||
int min_height;
|
||||
int nat_height;
|
||||
int min_baseline;
|
||||
int nat_baseline;
|
||||
};
|
||||
|
||||
#define EGG_TYPE_THREE_GRID_CHILD (egg_three_grid_child_get_type())
|
||||
G_DECLARE_FINAL_TYPE (EggThreeGridChild, egg_three_grid_child, EGG, THREE_GRID_CHILD, GtkLayoutChild)
|
||||
G_DEFINE_FINAL_TYPE (EggThreeGridChild, egg_three_grid_child, GTK_TYPE_LAYOUT_CHILD)
|
||||
|
||||
enum {
|
||||
CHILD_PROP_0,
|
||||
CHILD_PROP_COLUMN,
|
||||
CHILD_PROP_ROW,
|
||||
LAST_CHILD_PROP
|
||||
};
|
||||
|
||||
static GParamSpec *child_properties [LAST_CHILD_PROP];
|
||||
|
||||
static void
|
||||
egg_three_grid_child_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EggThreeGridChild *self = EGG_THREE_GRID_CHILD (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case CHILD_PROP_ROW:
|
||||
g_value_set_uint (value, self->row);
|
||||
break;
|
||||
|
||||
case CHILD_PROP_COLUMN:
|
||||
g_value_set_enum (value, self->column);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
egg_three_grid_child_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EggThreeGridChild *self = EGG_THREE_GRID_CHILD (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case CHILD_PROP_ROW:
|
||||
self->row = g_value_get_uint (value);
|
||||
break;
|
||||
|
||||
case CHILD_PROP_COLUMN:
|
||||
self->column = g_value_get_enum (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
egg_three_grid_child_class_init (EggThreeGridChildClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->get_property = egg_three_grid_child_get_property;
|
||||
object_class->set_property = egg_three_grid_child_set_property;
|
||||
|
||||
child_properties [CHILD_PROP_COLUMN] =
|
||||
g_param_spec_enum ("column",
|
||||
"Column",
|
||||
"The column for the child",
|
||||
EGG_TYPE_THREE_GRID_COLUMN,
|
||||
EGG_THREE_GRID_COLUMN_LEFT,
|
||||
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
child_properties [CHILD_PROP_ROW] =
|
||||
g_param_spec_uint ("row",
|
||||
"Row",
|
||||
"The row for the child",
|
||||
0, G_MAXUINT, 0,
|
||||
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_CHILD_PROP, child_properties);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_three_grid_child_init (EggThreeGridChild *self)
|
||||
{
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int row;
|
||||
int min_above_baseline;
|
||||
int min_below_baseline;
|
||||
int nat_above_baseline;
|
||||
int nat_below_baseline;
|
||||
} EggThreeGridRowInfo;
|
||||
|
||||
struct _EggThreeGridLayout
|
||||
{
|
||||
GtkLayoutManager parent_instance;
|
||||
GHashTable *row_infos;
|
||||
int row_spacing;
|
||||
int column_spacing;
|
||||
};
|
||||
|
||||
#define EGG_TYPE_THREE_GRID_LAYOUT (egg_three_grid_layout_get_type())
|
||||
G_DECLARE_FINAL_TYPE (EggThreeGridLayout, egg_three_grid_layout, EGG, THREE_GRID_LAYOUT, GtkLayoutManager)
|
||||
G_DEFINE_FINAL_TYPE (EggThreeGridLayout, egg_three_grid_layout, GTK_TYPE_LAYOUT_MANAGER)
|
||||
|
||||
static GtkSizeRequestMode
|
||||
egg_three_grid_layout_get_request_mode (GtkLayoutManager *manager,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
|
||||
}
|
||||
|
||||
static void
|
||||
get_column_width (EggThreeGridLayout *self,
|
||||
GtkWidget *widget,
|
||||
EggThreeGridColumn column,
|
||||
int *min_width,
|
||||
int *nat_width)
|
||||
{
|
||||
int real_min_width = 0;
|
||||
int real_nat_width = 0;
|
||||
|
||||
g_assert (EGG_IS_THREE_GRID_LAYOUT (self));
|
||||
g_assert (column >= EGG_THREE_GRID_COLUMN_LEFT);
|
||||
g_assert (column <= EGG_THREE_GRID_COLUMN_RIGHT);
|
||||
g_assert (min_width != NULL);
|
||||
g_assert (nat_width != NULL);
|
||||
|
||||
for (GtkWidget *iter = gtk_widget_get_first_child (widget);
|
||||
iter;
|
||||
iter = gtk_widget_get_next_sibling (iter))
|
||||
{
|
||||
EggThreeGridChild *child = EGG_THREE_GRID_CHILD (gtk_layout_manager_get_layout_child (GTK_LAYOUT_MANAGER (self), iter));
|
||||
|
||||
if (child->column == column)
|
||||
{
|
||||
int child_min_width;
|
||||
int child_nat_width;
|
||||
|
||||
gtk_widget_measure (iter, GTK_ORIENTATION_HORIZONTAL, 0, &child_min_width, &child_nat_width, NULL, NULL);
|
||||
|
||||
real_min_width = MAX (real_min_width, child_min_width);
|
||||
real_nat_width = MAX (real_nat_width, child_nat_width);
|
||||
}
|
||||
}
|
||||
|
||||
*min_width = real_min_width;
|
||||
*nat_width = real_nat_width;
|
||||
}
|
||||
|
||||
static void
|
||||
get_preferred_width (EggThreeGridLayout *self,
|
||||
GtkWidget *widget,
|
||||
int *min_width,
|
||||
int *nat_width)
|
||||
{
|
||||
int min_widths[3];
|
||||
int nat_widths[3];
|
||||
|
||||
g_assert (EGG_IS_THREE_GRID_LAYOUT (self));
|
||||
g_assert (min_width != NULL);
|
||||
g_assert (nat_width != NULL);
|
||||
|
||||
for (guint i = 0; i < 3; i++)
|
||||
get_column_width (self, widget, i, &min_widths[i], &nat_widths[i]);
|
||||
|
||||
*min_width = MAX (min_widths[0], min_widths[2]) * 2 + min_widths[1] + (self->column_spacing * 2);
|
||||
*nat_width = MAX (nat_widths[0], nat_widths[2]) * 2 + nat_widths[1] + (self->column_spacing * 2);
|
||||
}
|
||||
|
||||
static void
|
||||
row_info_merge (EggThreeGridRowInfo *row_info,
|
||||
const EggThreeGridRowInfo *other)
|
||||
{
|
||||
g_assert (row_info);
|
||||
g_assert (other);
|
||||
|
||||
row_info->min_above_baseline = MAX (row_info->min_above_baseline, other->min_above_baseline);
|
||||
row_info->min_below_baseline = MAX (row_info->min_below_baseline, other->min_below_baseline);
|
||||
row_info->nat_above_baseline = MAX (row_info->nat_above_baseline, other->nat_above_baseline);
|
||||
row_info->nat_below_baseline = MAX (row_info->nat_below_baseline, other->nat_below_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
update_row_info (GHashTable *hashtable,
|
||||
EggThreeGridChild *child)
|
||||
{
|
||||
GtkBaselinePosition baseline_position = GTK_BASELINE_POSITION_CENTER;
|
||||
EggThreeGridRowInfo *row_info;
|
||||
EggThreeGridRowInfo current = { 0 };
|
||||
|
||||
g_assert (hashtable);
|
||||
g_assert (child);
|
||||
|
||||
row_info = g_hash_table_lookup (hashtable, GINT_TO_POINTER (child->row));
|
||||
|
||||
if (row_info == NULL)
|
||||
{
|
||||
row_info = g_new0 (EggThreeGridRowInfo, 1);
|
||||
row_info->row = child->row;
|
||||
g_hash_table_insert (hashtable, GINT_TO_POINTER (child->row), row_info);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*
|
||||
* Allow setting baseline position per row. Right now we only support center
|
||||
* because that is the easiest thing to start with.
|
||||
*/
|
||||
|
||||
if (child->min_baseline == -1)
|
||||
{
|
||||
if (baseline_position == GTK_BASELINE_POSITION_CENTER)
|
||||
{
|
||||
current.min_above_baseline = current.min_below_baseline = ceil (child->min_height / 2.0);
|
||||
current.nat_above_baseline = current.nat_below_baseline = ceil (child->min_height / 2.0);
|
||||
}
|
||||
else if (baseline_position == GTK_BASELINE_POSITION_TOP)
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
else if (baseline_position == GTK_BASELINE_POSITION_BOTTOM)
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
current.min_above_baseline = child->min_baseline;
|
||||
current.min_below_baseline = child->min_height - child->min_baseline;
|
||||
current.nat_above_baseline = child->nat_baseline;
|
||||
current.nat_below_baseline = child->nat_height - child->nat_baseline;
|
||||
}
|
||||
|
||||
row_info_merge (row_info, ¤t);
|
||||
}
|
||||
|
||||
static void
|
||||
get_preferred_height_for_width (EggThreeGridLayout *self,
|
||||
GtkWidget *widget,
|
||||
int width,
|
||||
int *min_height,
|
||||
int *nat_height)
|
||||
{
|
||||
g_autoptr(GHashTable) row_infos = NULL;
|
||||
EggThreeGridRowInfo *row_info;
|
||||
GHashTableIter hiter;
|
||||
int real_min_height = 0;
|
||||
int real_nat_height = 0;
|
||||
int column_min_widths[3];
|
||||
int column_nat_widths[3];
|
||||
int widths[3];
|
||||
int n_rows;
|
||||
|
||||
g_assert (EGG_IS_THREE_GRID_LAYOUT (self));
|
||||
g_assert (min_height != NULL);
|
||||
g_assert (nat_height != NULL);
|
||||
|
||||
width -= self->column_spacing * 2;
|
||||
|
||||
get_column_width (self, widget, EGG_THREE_GRID_COLUMN_LEFT, &column_min_widths[0], &column_nat_widths[0]);
|
||||
get_column_width (self, widget, EGG_THREE_GRID_COLUMN_CENTER, &column_min_widths[1], &column_nat_widths[1]);
|
||||
get_column_width (self, widget, EGG_THREE_GRID_COLUMN_RIGHT, &column_min_widths[2], &column_nat_widths[2]);
|
||||
|
||||
if ((MAX (column_min_widths[0], column_min_widths[2]) * 2 + column_nat_widths[1]) > width)
|
||||
{
|
||||
widths[0] = column_min_widths[0];
|
||||
widths[2] = column_min_widths[2];
|
||||
widths[1] = width - widths[0] - widths[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Handle #1 and #2 */
|
||||
widths[1] = column_nat_widths[1];
|
||||
widths[0] = (width - widths[1]) / 2;
|
||||
widths[2] = width - widths[1] - widths[0];
|
||||
}
|
||||
|
||||
row_infos = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||
|
||||
for (GtkWidget *iter = gtk_widget_get_first_child (widget);
|
||||
iter;
|
||||
iter = gtk_widget_get_next_sibling (iter))
|
||||
{
|
||||
EggThreeGridChild *child = EGG_THREE_GRID_CHILD (gtk_layout_manager_get_layout_child (GTK_LAYOUT_MANAGER (self), iter));
|
||||
|
||||
if (!gtk_widget_get_visible (iter) || !gtk_widget_get_child_visible (iter))
|
||||
continue;
|
||||
|
||||
gtk_widget_measure (iter, GTK_ORIENTATION_VERTICAL, MAX (0, widths[child->column]),
|
||||
&child->min_height, &child->nat_height,
|
||||
&child->min_baseline, &child->nat_baseline);
|
||||
|
||||
update_row_info (row_infos, child);
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&hiter, row_infos);
|
||||
while (g_hash_table_iter_next (&hiter, NULL, (gpointer *)&row_info))
|
||||
{
|
||||
real_min_height += row_info->min_above_baseline + row_info->min_below_baseline;
|
||||
real_nat_height += row_info->nat_above_baseline + row_info->nat_below_baseline;
|
||||
}
|
||||
|
||||
n_rows = g_hash_table_size (row_infos);
|
||||
|
||||
if (n_rows > 1)
|
||||
{
|
||||
real_min_height += (n_rows - 1) * self->row_spacing;
|
||||
real_nat_height += (n_rows - 1) * self->row_spacing;
|
||||
}
|
||||
|
||||
*min_height = real_min_height;
|
||||
*nat_height = real_nat_height;
|
||||
|
||||
g_clear_pointer (&self->row_infos, g_hash_table_unref);
|
||||
self->row_infos = g_steal_pointer (&row_infos);
|
||||
}
|
||||
|
||||
static int
|
||||
sort_by_row (gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
const EggThreeGridRowInfo *info_a = a;
|
||||
const EggThreeGridRowInfo *info_b = b;
|
||||
|
||||
return info_a->row - info_b->row;
|
||||
}
|
||||
|
||||
static void
|
||||
size_allocate_children (EggThreeGridLayout *self,
|
||||
GtkWidget *widget,
|
||||
EggThreeGridColumn column,
|
||||
int row,
|
||||
GtkAllocation *allocation,
|
||||
int baseline)
|
||||
{
|
||||
g_assert (EGG_IS_THREE_GRID_LAYOUT (self));
|
||||
g_assert (allocation != NULL);
|
||||
|
||||
for (GtkWidget *iter = gtk_widget_get_first_child (widget);
|
||||
iter;
|
||||
iter = gtk_widget_get_next_sibling (iter))
|
||||
{
|
||||
EggThreeGridChild *child = EGG_THREE_GRID_CHILD (gtk_layout_manager_get_layout_child (GTK_LAYOUT_MANAGER (self), iter));
|
||||
|
||||
if (child->row == row && child->column == column)
|
||||
{
|
||||
GtkAllocation copy = *allocation;
|
||||
gtk_widget_size_allocate (iter, ©, baseline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
egg_three_grid_layout_allocate (GtkLayoutManager *manager,
|
||||
GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
EggThreeGridLayout *self = (EggThreeGridLayout *)manager;
|
||||
g_autofree GtkRequestedSize *rows = NULL;
|
||||
const GList *iter;
|
||||
GtkAllocation area;
|
||||
GtkTextDirection dir;
|
||||
GList *values;
|
||||
guint i;
|
||||
guint n_rows;
|
||||
int min_height;
|
||||
int nat_height;
|
||||
int left_min_width;
|
||||
int left_nat_width;
|
||||
int center_min_width;
|
||||
int center_nat_width;
|
||||
int right_min_width;
|
||||
int right_nat_width;
|
||||
int left;
|
||||
int center;
|
||||
int right;
|
||||
|
||||
g_assert (EGG_IS_THREE_GRID_LAYOUT (self));
|
||||
|
||||
area.x = 0;
|
||||
area.y = 0;
|
||||
area.width = width;
|
||||
area.height = height;
|
||||
|
||||
dir = gtk_widget_get_direction (widget);
|
||||
|
||||
get_preferred_height_for_width (self, widget, width, &min_height, &nat_height);
|
||||
|
||||
if (min_height > height)
|
||||
g_warning ("%s requested a minimum height of %d and got %d",
|
||||
G_OBJECT_TYPE_NAME (widget), min_height, height);
|
||||
|
||||
if (self->row_infos == NULL)
|
||||
return;
|
||||
|
||||
values = g_hash_table_get_values (self->row_infos);
|
||||
values = g_list_sort (values, sort_by_row);
|
||||
|
||||
get_column_width (self, widget, EGG_THREE_GRID_COLUMN_LEFT, &left_min_width, &left_nat_width);
|
||||
get_column_width (self, widget, EGG_THREE_GRID_COLUMN_CENTER, ¢er_min_width, ¢er_nat_width);
|
||||
get_column_width (self, widget, EGG_THREE_GRID_COLUMN_RIGHT, &right_min_width, &right_nat_width);
|
||||
|
||||
/*
|
||||
* Determine how much to give to the center widget first. This is because we will
|
||||
* just give the rest of the space on the sides to left/right columns and they
|
||||
* can deal with alignment by using halign.
|
||||
*
|
||||
* We can be in one of a couple states:
|
||||
*
|
||||
* 1) There is enough room for all columns natural size.
|
||||
* (We allocate the same to the left and the right).
|
||||
* 2) There is enough for the natural size of the center
|
||||
* but for some amount between natural and min sizing
|
||||
* of the left/right columns.
|
||||
* 3) There is only minimum size for columns and some
|
||||
* amount between natural/minimum of the center.
|
||||
*
|
||||
* We can handle #1 and #2 with the same logic though.
|
||||
*/
|
||||
|
||||
if ((MAX (left_min_width, right_min_width) * 2 + center_nat_width + 2 * self->column_spacing) > area.width)
|
||||
{
|
||||
/* Handle #3 */
|
||||
left = right = MAX (left_min_width, right_min_width);
|
||||
center = area.width - left - right - 2 * self->column_spacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Handle #1 and #2 */
|
||||
center = center_nat_width;
|
||||
right = left = (area.width - center) / 2 - self->column_spacing;
|
||||
}
|
||||
|
||||
n_rows = g_list_length (values);
|
||||
rows = g_new0 (GtkRequestedSize, n_rows);
|
||||
|
||||
for (iter = values, i = 0; iter != NULL; iter = iter->next, i++)
|
||||
{
|
||||
EggThreeGridRowInfo *row_info = iter->data;
|
||||
|
||||
rows[i].data = row_info;
|
||||
rows[i].minimum_size = row_info->min_above_baseline + row_info->min_below_baseline;
|
||||
rows[i].natural_size = row_info->nat_above_baseline + row_info->nat_below_baseline;
|
||||
}
|
||||
|
||||
gtk_distribute_natural_allocation (area.height, n_rows, rows);
|
||||
|
||||
for (i = 0; i < n_rows; i++)
|
||||
{
|
||||
GtkRequestedSize *size = &rows[i];
|
||||
EggThreeGridRowInfo *row_info = size->data;
|
||||
GtkAllocation child_alloc;
|
||||
int child_baseline;
|
||||
|
||||
if (row_info->nat_above_baseline + row_info->nat_below_baseline < size->minimum_size)
|
||||
child_baseline = row_info->nat_above_baseline;
|
||||
else
|
||||
child_baseline = row_info->min_above_baseline;
|
||||
|
||||
child_alloc.x = area.x;
|
||||
child_alloc.width = left;
|
||||
child_alloc.y = area.y;
|
||||
child_alloc.height = size->minimum_size;
|
||||
|
||||
if (dir == GTK_TEXT_DIR_LTR)
|
||||
size_allocate_children (self, widget, EGG_THREE_GRID_COLUMN_LEFT, row_info->row, &child_alloc, child_baseline);
|
||||
else
|
||||
size_allocate_children (self, widget, EGG_THREE_GRID_COLUMN_RIGHT, row_info->row, &child_alloc, child_baseline);
|
||||
|
||||
child_alloc.x = area.x + left + self->column_spacing;
|
||||
child_alloc.width = center;
|
||||
child_alloc.y = area.y;
|
||||
child_alloc.height = size->minimum_size;
|
||||
|
||||
size_allocate_children (self, widget, EGG_THREE_GRID_COLUMN_CENTER, row_info->row, &child_alloc, child_baseline);
|
||||
|
||||
child_alloc.x = area.x + area.width - right;
|
||||
child_alloc.width = right;
|
||||
child_alloc.y = area.y;
|
||||
child_alloc.height = size->minimum_size;
|
||||
|
||||
if (dir == GTK_TEXT_DIR_LTR)
|
||||
size_allocate_children (self, widget, EGG_THREE_GRID_COLUMN_RIGHT, row_info->row, &child_alloc, child_baseline);
|
||||
else
|
||||
size_allocate_children (self, widget, EGG_THREE_GRID_COLUMN_LEFT, row_info->row, &child_alloc, child_baseline);
|
||||
|
||||
area.y += child_alloc.height + self->row_spacing;
|
||||
area.height -= child_alloc.height + self->row_spacing;
|
||||
}
|
||||
|
||||
g_list_free (values);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_three_grid_layout_measure (GtkLayoutManager *manager,
|
||||
GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
EggThreeGridLayout *self = (EggThreeGridLayout *)manager;
|
||||
|
||||
g_assert (EGG_IS_THREE_GRID_LAYOUT (self));
|
||||
|
||||
*minimum_baseline = -1;
|
||||
*natural_baseline = -1;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
get_preferred_width (self, widget, minimum, natural);
|
||||
else
|
||||
get_preferred_height_for_width (self, widget, for_size, minimum, natural);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_three_grid_layout_dispose (GObject *object)
|
||||
{
|
||||
EggThreeGridLayout *self = (EggThreeGridLayout *)object;
|
||||
|
||||
g_clear_pointer (&self->row_infos, g_hash_table_unref);
|
||||
|
||||
G_OBJECT_CLASS (egg_three_grid_layout_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_three_grid_layout_class_init (EggThreeGridLayoutClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkLayoutManagerClass *layout_class = GTK_LAYOUT_MANAGER_CLASS (klass);
|
||||
|
||||
object_class->dispose = egg_three_grid_layout_dispose;
|
||||
|
||||
layout_class->get_request_mode = egg_three_grid_layout_get_request_mode;
|
||||
layout_class->measure = egg_three_grid_layout_measure;
|
||||
layout_class->allocate = egg_three_grid_layout_allocate;
|
||||
layout_class->layout_child_type = EGG_TYPE_THREE_GRID_CHILD;
|
||||
}
|
||||
|
||||
static void
|
||||
egg_three_grid_layout_init (EggThreeGridLayout *self)
|
||||
{
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
guint column_spacing;
|
||||
guint row_spacing;
|
||||
} EggThreeGridPrivate;
|
||||
|
||||
static void buildable_iface_init (GtkBuildableIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (EggThreeGrid, egg_three_grid, GTK_TYPE_WIDGET,
|
||||
G_ADD_PRIVATE (EggThreeGrid)
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, buildable_iface_init))
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_COLUMN_SPACING,
|
||||
PROP_ROW_SPACING,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
void
|
||||
egg_three_grid_add (EggThreeGrid *self,
|
||||
GtkWidget *widget,
|
||||
guint row,
|
||||
EggThreeGridColumn column)
|
||||
{
|
||||
g_assert (EGG_IS_THREE_GRID (self));
|
||||
g_assert (GTK_IS_WIDGET (widget));
|
||||
|
||||
gtk_widget_set_parent (widget, GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
void
|
||||
egg_three_grid_remove (EggThreeGrid *self,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
g_assert (EGG_IS_THREE_GRID (self));
|
||||
g_assert (GTK_IS_WIDGET (widget));
|
||||
|
||||
gtk_widget_unparent (widget);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
egg_three_grid_dispose (GObject *object)
|
||||
{
|
||||
EggThreeGrid *self = (EggThreeGrid *)object;
|
||||
GtkWidget *child;
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self))))
|
||||
egg_three_grid_remove (self, child);
|
||||
|
||||
G_OBJECT_CLASS (egg_three_grid_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_three_grid_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EggThreeGrid *self = EGG_THREE_GRID (object);
|
||||
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_COLUMN_SPACING:
|
||||
g_value_set_uint (value, EGG_THREE_GRID_LAYOUT (manager)->column_spacing);
|
||||
break;
|
||||
|
||||
case PROP_ROW_SPACING:
|
||||
g_value_set_uint (value, EGG_THREE_GRID_LAYOUT (manager)->row_spacing);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
egg_three_grid_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EggThreeGrid *self = EGG_THREE_GRID (object);
|
||||
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_COLUMN_SPACING:
|
||||
EGG_THREE_GRID_LAYOUT (manager)->column_spacing = g_value_get_uint (value);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
break;
|
||||
|
||||
case PROP_ROW_SPACING:
|
||||
EGG_THREE_GRID_LAYOUT (manager)->row_spacing = g_value_get_uint (value);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
egg_three_grid_class_init (EggThreeGridClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = egg_three_grid_dispose;
|
||||
object_class->get_property = egg_three_grid_get_property;
|
||||
object_class->set_property = egg_three_grid_set_property;
|
||||
|
||||
properties [PROP_COLUMN_SPACING] =
|
||||
g_param_spec_uint ("column-spacing",
|
||||
"Column Spacing",
|
||||
"The amount of spacing to add between columns",
|
||||
0,
|
||||
G_MAXUINT,
|
||||
0,
|
||||
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
properties [PROP_ROW_SPACING] =
|
||||
g_param_spec_uint ("row-spacing",
|
||||
"Row Spacing",
|
||||
"The amount of spacing to add between rows",
|
||||
0,
|
||||
G_MAXUINT,
|
||||
0,
|
||||
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "threegrid");
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, EGG_TYPE_THREE_GRID_LAYOUT);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_three_grid_init (EggThreeGrid *self)
|
||||
{
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
egg_three_grid_new (void)
|
||||
{
|
||||
return g_object_new (EGG_TYPE_THREE_GRID, NULL);
|
||||
}
|
||||
|
||||
GType
|
||||
egg_three_grid_column_get_type (void)
|
||||
{
|
||||
static GType type_id;
|
||||
|
||||
if (g_once_init_enter (&type_id))
|
||||
{
|
||||
GType _type_id;
|
||||
static const GEnumValue values[] = {
|
||||
{ EGG_THREE_GRID_COLUMN_LEFT, "EGG_THREE_GRID_COLUMN_LEFT", "left" },
|
||||
{ EGG_THREE_GRID_COLUMN_CENTER, "EGG_THREE_GRID_COLUMN_CENTER", "center" },
|
||||
{ EGG_THREE_GRID_COLUMN_RIGHT, "EGG_THREE_GRID_COLUMN_RIGHT", "right" },
|
||||
{ 0 }
|
||||
};
|
||||
_type_id = g_enum_register_static ("EggThreeGridColumn", values);
|
||||
g_once_init_leave (&type_id, _type_id);
|
||||
}
|
||||
|
||||
return type_id;
|
||||
}
|
||||
|
||||
static void
|
||||
egg_three_grid_add_child (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const char *type)
|
||||
{
|
||||
if (GTK_IS_WIDGET (child))
|
||||
egg_three_grid_add (EGG_THREE_GRID (buildable), GTK_WIDGET (child), 0, EGG_THREE_GRID_COLUMN_LEFT);
|
||||
else
|
||||
g_warning ("%s cannot be added to %s", G_OBJECT_TYPE_NAME (child), G_OBJECT_TYPE_NAME (buildable));
|
||||
}
|
||||
|
||||
static void
|
||||
buildable_iface_init (GtkBuildableIface *iface)
|
||||
{
|
||||
iface->add_child = egg_three_grid_add_child;
|
||||
}
|
||||
51
src/libsysprof-ui/egg-three-grid.h
Normal file
51
src/libsysprof-ui/egg-three-grid.h
Normal file
@ -0,0 +1,51 @@
|
||||
/* egg-three-grid.h
|
||||
*
|
||||
* Copyright (C) 2016 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EGG_TYPE_THREE_GRID (egg_three_grid_get_type())
|
||||
#define EGG_TYPE_THREE_GRID_COLUMN (egg_three_grid_column_get_type())
|
||||
|
||||
G_DECLARE_DERIVABLE_TYPE (EggThreeGrid, egg_three_grid, EGG, THREE_GRID, GtkWidget)
|
||||
|
||||
struct _EggThreeGridClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EGG_THREE_GRID_COLUMN_LEFT,
|
||||
EGG_THREE_GRID_COLUMN_CENTER,
|
||||
EGG_THREE_GRID_COLUMN_RIGHT
|
||||
} EggThreeGridColumn;
|
||||
|
||||
GType egg_three_grid_column_get_type (void);
|
||||
GtkWidget *egg_three_grid_new (void);
|
||||
void egg_three_grid_add (EggThreeGrid *self,
|
||||
GtkWidget *child,
|
||||
guint row,
|
||||
EggThreeGridColumn column);
|
||||
void egg_three_grid_remove (EggThreeGrid *self,
|
||||
GtkWidget *child);
|
||||
|
||||
G_END_DECLS
|
||||
@ -24,7 +24,6 @@
|
||||
<file preprocess="xml-stripblanks">sysprof-profiler-assistant.ui</file>
|
||||
<file preprocess="xml-stripblanks">sysprof-recording-state-view.ui</file>
|
||||
<file preprocess="xml-stripblanks">sysprof-tab.ui</file>
|
||||
<file preprocess="xml-stripblanks">sysprof-time-label.ui</file>
|
||||
<file preprocess="xml-stripblanks">sysprof-visualizers-frame.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
@ -13,6 +13,11 @@ libsysprof_ui_public_sources = [
|
||||
]
|
||||
|
||||
libsysprof_ui_private_sources = [
|
||||
'egg-handle.c',
|
||||
'egg-paned.c',
|
||||
'egg-resizer.c',
|
||||
'egg-three-grid.c',
|
||||
|
||||
'pointcache.c',
|
||||
'rectangles.c',
|
||||
'sysprof-aid.c',
|
||||
@ -23,6 +28,7 @@ libsysprof_ui_private_sources = [
|
||||
'sysprof-callgraph-page.c',
|
||||
'sysprof-cell-renderer-duration.c',
|
||||
'sysprof-cell-renderer-percent.c',
|
||||
'sysprof-cell-renderer-progress.c',
|
||||
'sysprof-color-cycle.c',
|
||||
'sysprof-counters-aid.c',
|
||||
'sysprof-cpu-aid.c',
|
||||
@ -87,7 +93,8 @@ libsysprof_ui_resources = gnome.compile_resources(
|
||||
# Subset of dependencies used in generating the pkg-config file
|
||||
libsysprof_ui_pkg_deps = [
|
||||
dependency('gio-2.0', version: glib_req_version),
|
||||
dependency('gtk+-3.0', version: gtk_req_version),
|
||||
dependency('gtk4', version: gtk_req_version),
|
||||
dependency('libadwaita-1'),
|
||||
]
|
||||
|
||||
libsysprof_ui_deps = libsysprof_ui_pkg_deps + [
|
||||
@ -98,15 +105,8 @@ libsysprof_ui_deps = libsysprof_ui_pkg_deps + [
|
||||
# dependency object
|
||||
libsysprof_ui_pkg_deps += libsysprof
|
||||
|
||||
dazzle_dep = dependency('libdazzle-1.0', version: dazzle_req_version, fallback: ['libdazzle', 'libdazzle_dep'])
|
||||
libsysprof_ui_deps += dazzle_dep
|
||||
|
||||
if dazzle_dep.type_name() == 'pkgconfig'
|
||||
libsysprof_ui_pkg_deps += dazzle_dep
|
||||
endif
|
||||
|
||||
libsysprof_ui = shared_library(
|
||||
'sysprof-ui-@0@'.format(libsysprof_api_version),
|
||||
'sysprof-ui-@0@'.format(libsysprof_ui_api_version),
|
||||
libsysprof_ui_public_sources + libsysprof_ui_private_sources + libsysprof_ui_resources,
|
||||
|
||||
dependencies: libsysprof_ui_deps + [librax_dep],
|
||||
@ -124,16 +124,16 @@ libsysprof_ui_dep = declare_dependency(
|
||||
|
||||
pkgconfig.generate(
|
||||
libsysprof_ui,
|
||||
subdirs: [ sysprof_header_subdir ],
|
||||
subdirs: [ sysprof_ui_header_subdir ],
|
||||
description: 'The UI library for GTK applications embedding sysprof',
|
||||
install_dir: join_paths(get_option('libdir'), 'pkgconfig'),
|
||||
requires: [ 'gio-2.0', 'gtk+-3.0' ],
|
||||
requires: [ 'gio-2.0', 'gtk4' ],
|
||||
libraries_private: libsysprof_ui_pkg_deps,
|
||||
variables: [
|
||||
'datadir=' + datadir_for_pc_file,
|
||||
],
|
||||
)
|
||||
|
||||
install_headers(libsysprof_ui_public_headers, subdir: sysprof_header_subdir)
|
||||
install_headers(libsysprof_ui_public_headers, subdir: sysprof_ui_header_subdir)
|
||||
|
||||
endif
|
||||
|
||||
@ -1,32 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.12"/>
|
||||
<requires lib="gtk" version="4.0"/>
|
||||
<template class="SysprofAidIcon" parent="GtkFlowBoxChild">
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkOverlay">
|
||||
<property name="halign">center</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<property name="child">
|
||||
<object class="GtkImage" id="image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="pixel_size">64</property>
|
||||
<property name="width-request">92</property>
|
||||
<property name="icon_name">org.gnome.Sysprof-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</property>
|
||||
<child type="overlay">
|
||||
<object class="GtkImage" id="check">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="pixel_size">16</property>
|
||||
<property name="icon_name">object-select-symbolic</property>
|
||||
<property name="halign">end</property>
|
||||
@ -34,29 +25,17 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_underline">1</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="wrap">1</property>
|
||||
<property name="mnemonic_widget">SysprofAidIcon</property>
|
||||
<property name="max_width_chars">12</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
|
||||
@ -218,7 +218,7 @@ sysprof_battery_aid_present_finish (SysprofAid *aid,
|
||||
if (found > 0)
|
||||
sysprof_display_add_group (present->display, group);
|
||||
else
|
||||
gtk_widget_destroy (GTK_WIDGET (group));
|
||||
g_object_unref (g_object_ref_sink (group));
|
||||
}
|
||||
|
||||
return counters != NULL;
|
||||
|
||||
@ -39,11 +39,12 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <dazzle.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "../stackstash.h"
|
||||
|
||||
#include "egg-paned-private.h"
|
||||
|
||||
#include "sysprof-callgraph-page.h"
|
||||
#include "sysprof-cell-renderer-percent.h"
|
||||
|
||||
@ -56,6 +57,9 @@ typedef struct
|
||||
GtkTreeView *descendants_view;
|
||||
GtkTreeViewColumn *descendants_name_column;
|
||||
GtkStack *stack;
|
||||
GtkWidget *empty_state;
|
||||
GtkWidget *loading_state;
|
||||
GtkWidget *callgraph;
|
||||
|
||||
GQueue *history;
|
||||
|
||||
@ -208,7 +212,7 @@ sysprof_callgraph_page_load (SysprofCallgraphPage *self,
|
||||
gtk_tree_selection_select_iter (selection, &iter);
|
||||
}
|
||||
|
||||
gtk_stack_set_visible_child_name (priv->stack, "callgraph");
|
||||
gtk_stack_set_visible_child (priv->stack, priv->callgraph);
|
||||
|
||||
g_clear_object (&functions);
|
||||
}
|
||||
@ -220,7 +224,7 @@ _sysprof_callgraph_page_set_failed (SysprofCallgraphPage *self)
|
||||
|
||||
g_return_if_fail (SYSPROF_IS_CALLGRAPH_PAGE (self));
|
||||
|
||||
gtk_stack_set_visible_child_name (priv->stack, "empty-state");
|
||||
gtk_stack_set_visible_child (priv->stack, priv->empty_state);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -239,7 +243,7 @@ sysprof_callgraph_page_unload (SysprofCallgraphPage *self)
|
||||
gtk_tree_view_set_model (priv->functions_view, NULL);
|
||||
gtk_tree_view_set_model (priv->descendants_view, NULL);
|
||||
|
||||
gtk_stack_set_visible_child_name (priv->stack, "empty-state");
|
||||
gtk_stack_set_visible_child (priv->stack, priv->empty_state);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -664,10 +668,12 @@ sysprof_callgraph_page_real_go_previous (SysprofCallgraphPage *self)
|
||||
sysprof_callgraph_page_set_node (self, node);
|
||||
}
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
descendants_view_move_cursor_cb (GtkTreeView *descendants_view,
|
||||
GtkMovementStep step,
|
||||
int direction,
|
||||
gboolean extend,
|
||||
gboolean modify,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (step == GTK_MOVEMENT_VISUAL_POSITIONS)
|
||||
@ -680,15 +686,19 @@ descendants_view_move_cursor_cb (GtkTreeView *descendants_view,
|
||||
{
|
||||
gtk_tree_view_expand_row (descendants_view, path, FALSE);
|
||||
g_signal_stop_emission_by_name (descendants_view, "move-cursor");
|
||||
return FALSE;
|
||||
}
|
||||
else if (direction == -1)
|
||||
{
|
||||
gtk_tree_view_collapse_row (descendants_view, path);
|
||||
g_signal_stop_emission_by_name (descendants_view, "move-cursor");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -732,7 +742,7 @@ static void
|
||||
copy_tree_view_selection (GtkTreeView *tree_view)
|
||||
{
|
||||
g_autoptr(GString) str = NULL;
|
||||
GtkClipboard *clipboard;
|
||||
GdkClipboard *clipboard;
|
||||
|
||||
g_assert (GTK_IS_TREE_VIEW (tree_view));
|
||||
|
||||
@ -741,24 +751,26 @@ copy_tree_view_selection (GtkTreeView *tree_view)
|
||||
copy_tree_view_selection_cb,
|
||||
str);
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (tree_view), GDK_SELECTION_CLIPBOARD);
|
||||
gtk_clipboard_set_text (clipboard, str->str, str->len);
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (tree_view));
|
||||
gdk_clipboard_set_text (clipboard, str->str);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_callgraph_page_copy_cb (GtkWidget *widget,
|
||||
SysprofCallgraphPage *self)
|
||||
sysprof_callgraph_page_copy_cb (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *param)
|
||||
{
|
||||
SysprofCallgraphPage *self = (SysprofCallgraphPage *)widget;
|
||||
SysprofCallgraphPagePrivate *priv = sysprof_callgraph_page_get_instance_private (self);
|
||||
GtkWidget *toplevel;
|
||||
GtkRoot *toplevel;
|
||||
GtkWidget *focus;
|
||||
|
||||
g_assert (GTK_IS_WIDGET (widget));
|
||||
g_assert (SYSPROF_IS_CALLGRAPH_PAGE (self));
|
||||
|
||||
if (!(toplevel = gtk_widget_get_toplevel (widget)) ||
|
||||
!GTK_IS_WINDOW (toplevel) ||
|
||||
!(focus = gtk_window_get_focus (GTK_WINDOW (toplevel))))
|
||||
if (!(toplevel = gtk_widget_get_root (widget)) ||
|
||||
!GTK_IS_ROOT (toplevel) ||
|
||||
!(focus = gtk_root_get_focus (toplevel)))
|
||||
return;
|
||||
|
||||
if (focus == GTK_WIDGET (priv->descendants_view))
|
||||
@ -891,7 +903,6 @@ sysprof_callgraph_page_class_init (SysprofCallgraphPageClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
SysprofPageClass *page_class = SYSPROF_PAGE_CLASS (klass);
|
||||
GtkBindingSet *bindings;
|
||||
|
||||
object_class->finalize = sysprof_callgraph_page_finalize;
|
||||
object_class->get_property = sysprof_callgraph_page_get_property;
|
||||
@ -926,10 +937,16 @@ sysprof_callgraph_page_class_init (SysprofCallgraphPageClass *klass)
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofCallgraphPage, descendants_view);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofCallgraphPage, descendants_name_column);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofCallgraphPage, stack);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofCallgraphPage, callgraph);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofCallgraphPage, empty_state);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofCallgraphPage, loading_state);
|
||||
|
||||
bindings = gtk_binding_set_by_class (klass);
|
||||
gtk_binding_entry_add_signal (bindings, GDK_KEY_Left, GDK_MOD1_MASK, "go-previous", 0);
|
||||
gtk_widget_class_install_action (widget_class, "page.copy", NULL, sysprof_callgraph_page_copy_cb);
|
||||
|
||||
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_c, GDK_CONTROL_MASK, "page.copy", NULL);
|
||||
gtk_widget_class_add_binding_signal (widget_class, GDK_KEY_Left, GDK_ALT_MASK, "go-previous", NULL);
|
||||
|
||||
g_type_ensure (EGG_TYPE_PANED);
|
||||
g_type_ensure (SYSPROF_TYPE_CELL_RENDERER_PERCENT);
|
||||
}
|
||||
|
||||
@ -937,7 +954,6 @@ static void
|
||||
sysprof_callgraph_page_init (SysprofCallgraphPage *self)
|
||||
{
|
||||
SysprofCallgraphPagePrivate *priv = sysprof_callgraph_page_get_instance_private (self);
|
||||
DzlShortcutController *controller;
|
||||
GtkTreeSelection *selection;
|
||||
GtkCellRenderer *cell;
|
||||
|
||||
@ -945,7 +961,7 @@ sysprof_callgraph_page_init (SysprofCallgraphPage *self)
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
gtk_stack_set_visible_child_name (priv->stack, "empty-state");
|
||||
gtk_stack_set_visible_child (priv->stack, priv->loading_state);
|
||||
|
||||
selection = gtk_tree_view_get_selection (priv->functions_view);
|
||||
|
||||
@ -991,16 +1007,6 @@ sysprof_callgraph_page_init (SysprofCallgraphPage *self)
|
||||
|
||||
gtk_tree_selection_set_mode (gtk_tree_view_get_selection (priv->descendants_view),
|
||||
GTK_SELECTION_MULTIPLE);
|
||||
|
||||
controller = dzl_shortcut_controller_find (GTK_WIDGET (self));
|
||||
|
||||
dzl_shortcut_controller_add_command_callback (controller,
|
||||
"org.gnome.sysprof3.capture.copy",
|
||||
"<Control>c",
|
||||
DZL_SHORTCUT_PHASE_BUBBLE,
|
||||
(GtkCallback) sysprof_callgraph_page_copy_cb,
|
||||
self,
|
||||
NULL);
|
||||
}
|
||||
|
||||
typedef struct _Descendant Descendant;
|
||||
@ -1287,7 +1293,7 @@ _sysprof_callgraph_page_set_loading (SysprofCallgraphPage *self,
|
||||
priv->loading--;
|
||||
|
||||
if (priv->loading)
|
||||
gtk_stack_set_visible_child_name (priv->stack, "loading");
|
||||
gtk_stack_set_visible_child (priv->stack, priv->loading_state);
|
||||
else
|
||||
gtk_stack_set_visible_child_name (priv->stack, "callgraph");
|
||||
gtk_stack_set_visible_child (priv->stack, priv->callgraph);
|
||||
}
|
||||
|
||||
@ -2,23 +2,19 @@
|
||||
<template class="SysprofCallgraphPage" parent="SysprofPage">
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkPaned">
|
||||
<object class="EggPaned" id="callgraph">
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="position">450</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkPaned">
|
||||
<object class="EggPaned">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="width-request">400</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">true</property>
|
||||
<property name="vexpand">true</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="functions_view">
|
||||
<property name="fixed-height-mode">true</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="function_name_column">
|
||||
<property name="expand">true</property>
|
||||
@ -70,16 +66,12 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">true</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">true</property>
|
||||
<property name="vexpand">true</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="callers_view">
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="callers_name_column">
|
||||
<property name="expand">true</property>
|
||||
@ -131,18 +123,14 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">true</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">true</property>
|
||||
<property name="hexpand">true</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="descendants_view">
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="descendants_name_column">
|
||||
<property name="expand">true</property>
|
||||
@ -203,31 +191,20 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">callgraph</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="DzlEmptyState">
|
||||
<object class="AdwStatusPage" id="loading_state">
|
||||
<property name="icon-name">content-loading-symbolic</property>
|
||||
<property name="title" translatable="yes">Generating Callgraph</property>
|
||||
<property name="subtitle" translatable="yes">Sysprof is busy creating the selected callgraph.</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="description" translatable="yes">Sysprof is busy creating the selected callgraph.</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">loading</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="DzlEmptyState">
|
||||
<object class="AdwStatusPage" id="empty_state">
|
||||
<property name="icon-name">computer-fail-symbolic</property>
|
||||
<property name="title" translatable="yes">Not Enough Samples</property>
|
||||
<property name="subtitle" translatable="yes">More samples are necessary to display a callgraph.</property>
|
||||
<property name="visible">false</property>
|
||||
<property name="description" translatable="yes">More samples are necessary to display a callgraph.</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">empty-state</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@ -55,38 +55,87 @@ G_DEFINE_TYPE_WITH_PRIVATE (SysprofCellRendererDuration, sysprof_cell_renderer_d
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
static inline void
|
||||
rounded_rectangle (cairo_t *cr,
|
||||
const GdkRectangle *rect,
|
||||
int x_radius,
|
||||
int y_radius)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
int x1, x2;
|
||||
int y1, y2;
|
||||
int xr1, xr2;
|
||||
int yr1, yr2;
|
||||
|
||||
g_assert (cr);
|
||||
g_assert (rect);
|
||||
|
||||
x = rect->x;
|
||||
y = rect->y;
|
||||
width = rect->width;
|
||||
height = rect->height;
|
||||
|
||||
x1 = x;
|
||||
x2 = x1 + width;
|
||||
y1 = y;
|
||||
y2 = y1 + height;
|
||||
|
||||
x_radius = MIN (x_radius, width / 2.0);
|
||||
y_radius = MIN (y_radius, width / 2.0);
|
||||
|
||||
xr1 = x_radius;
|
||||
xr2 = x_radius / 2.0;
|
||||
yr1 = y_radius;
|
||||
yr2 = y_radius / 2.0;
|
||||
|
||||
cairo_move_to (cr, x1 + xr1, y1);
|
||||
cairo_line_to (cr, x2 - xr1, y1);
|
||||
cairo_curve_to (cr, x2 - xr2, y1, x2, y1 + yr2, x2, y1 + yr1);
|
||||
cairo_line_to (cr, x2, y2 - yr1);
|
||||
cairo_curve_to (cr, x2, y2 - yr2, x2 - xr2, y2, x2 - xr1, y2);
|
||||
cairo_line_to (cr, x1 + xr1, y2);
|
||||
cairo_curve_to (cr, x1 + xr2, y2, x1, y2 - yr2, x1, y2 - yr1);
|
||||
cairo_line_to (cr, x1, y1 + yr1);
|
||||
cairo_curve_to (cr, x1, y1 + yr2, x1 + xr2, y1, x1 + xr1, y1);
|
||||
cairo_close_path (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_cell_renderer_duration_render (GtkCellRenderer *renderer,
|
||||
cairo_t *cr,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *bg_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState state)
|
||||
sysprof_cell_renderer_duration_snapshot (GtkCellRenderer *renderer,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *bg_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState state)
|
||||
{
|
||||
SysprofCellRendererDuration *self = (SysprofCellRendererDuration *)renderer;
|
||||
SysprofCellRendererDurationPrivate *priv = sysprof_cell_renderer_duration_get_instance_private (self);
|
||||
g_autoptr(GString) str = NULL;
|
||||
GtkStyleContext *style_context;
|
||||
cairo_t *cr;
|
||||
gdouble x1, x2;
|
||||
GdkRGBA rgba;
|
||||
GdkRectangle r;
|
||||
gint64 duration;
|
||||
|
||||
g_assert (SYSPROF_IS_CELL_RENDERER_DURATION (self));
|
||||
g_assert (cr != NULL);
|
||||
g_assert (snapshot != NULL);
|
||||
g_assert (GTK_IS_WIDGET (widget));
|
||||
|
||||
if (priv->zoom_manager == NULL)
|
||||
return;
|
||||
|
||||
cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT (cell_area->x, cell_area->y, cell_area->width, cell_area->height));
|
||||
|
||||
style_context = gtk_widget_get_style_context (widget);
|
||||
|
||||
if (priv->color_set)
|
||||
rgba = priv->color;
|
||||
else
|
||||
gtk_style_context_get_color (style_context,
|
||||
gtk_style_context_get_state (style_context),
|
||||
&rgba);
|
||||
gtk_style_context_get_color (style_context, &rgba);
|
||||
|
||||
duration = sysprof_zoom_manager_get_duration_for_width (priv->zoom_manager, bg_area->width);
|
||||
|
||||
@ -108,7 +157,7 @@ sysprof_cell_renderer_duration_render (GtkCellRenderer *renderer,
|
||||
|
||||
if (r.width > 3)
|
||||
{
|
||||
dzl_cairo_rounded_rectangle (cr, &r, 2, 2);
|
||||
rounded_rectangle (cr, &r, 2, 2);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
else if (r.width > 1)
|
||||
@ -166,6 +215,8 @@ sysprof_cell_renderer_duration_render (GtkCellRenderer *renderer,
|
||||
|
||||
g_object_unref (layout);
|
||||
}
|
||||
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static GtkSizeRequestMode
|
||||
@ -342,7 +393,7 @@ sysprof_cell_renderer_duration_class_init (SysprofCellRendererDurationClass *kla
|
||||
cell_class->get_preferred_height_for_width = sysprof_cell_renderer_duration_get_preferred_height_for_width;
|
||||
cell_class->get_preferred_width = sysprof_cell_renderer_duration_get_preferred_width;
|
||||
cell_class->get_request_mode = sysprof_cell_renderer_duration_get_request_mode;
|
||||
cell_class->render = sysprof_cell_renderer_duration_render;
|
||||
cell_class->snapshot = sysprof_cell_renderer_duration_snapshot;
|
||||
|
||||
/* Note we do not emit ::notify() for these properties */
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ enum {
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (SysprofCellRendererPercent, sysprof_cell_renderer_percent, GTK_TYPE_CELL_RENDERER_PROGRESS)
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (SysprofCellRendererPercent, sysprof_cell_renderer_percent, SYSPROF_TYPE_CELL_RENDERER_PROGRESS)
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "sysprof-cell-renderer-progress.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -37,12 +37,12 @@ typedef struct _SysprofCellRendererPercentClass SysprofCellRendererPercentClass;
|
||||
|
||||
struct _SysprofCellRendererPercent
|
||||
{
|
||||
GtkCellRendererProgress parent;
|
||||
SysprofCellRendererProgress parent;
|
||||
};
|
||||
|
||||
struct _SysprofCellRendererPercentClass
|
||||
{
|
||||
GtkCellRendererProgressClass parent_class;
|
||||
SysprofCellRendererProgressClass parent_class;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _reserved[4];
|
||||
|
||||
712
src/libsysprof-ui/sysprof-cell-renderer-progress.c
Normal file
712
src/libsysprof-ui/sysprof-cell-renderer-progress.c
Normal file
@ -0,0 +1,712 @@
|
||||
/* gtkcellrendererprogress.c
|
||||
* Copyright (C) 2002 Naba Kumar <kh_naba@users.sourceforge.net>
|
||||
* heavily modified by Jörgen Scheibengruber <mfcn@gmx.de>
|
||||
* heavily modified by Marco Pesenti Gritti <marco@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2007. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "sysprof-cell-renderer-progress.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_VALUE,
|
||||
PROP_TEXT,
|
||||
PROP_PULSE,
|
||||
PROP_TEXT_XALIGN,
|
||||
PROP_TEXT_YALIGN,
|
||||
PROP_ORIENTATION,
|
||||
PROP_INVERTED
|
||||
};
|
||||
|
||||
struct _SysprofCellRendererProgressPrivate
|
||||
{
|
||||
int value;
|
||||
char *text;
|
||||
char *label;
|
||||
int min_h;
|
||||
int min_w;
|
||||
int pulse;
|
||||
int offset;
|
||||
float text_xalign;
|
||||
float text_yalign;
|
||||
GtkOrientation orientation;
|
||||
gboolean inverted;
|
||||
};
|
||||
|
||||
static void sysprof_cell_renderer_progress_finalize (GObject *object);
|
||||
static void sysprof_cell_renderer_progress_get_property (GObject *object,
|
||||
guint param_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void sysprof_cell_renderer_progress_set_property (GObject *object,
|
||||
guint param_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void sysprof_cell_renderer_progress_set_value (SysprofCellRendererProgress *cellprogress,
|
||||
int value);
|
||||
static void sysprof_cell_renderer_progress_set_text (SysprofCellRendererProgress *cellprogress,
|
||||
const char *text);
|
||||
static void sysprof_cell_renderer_progress_set_pulse (SysprofCellRendererProgress *cellprogress,
|
||||
int pulse);
|
||||
static void compute_dimensions (GtkCellRenderer *cell,
|
||||
GtkWidget *widget,
|
||||
const char *text,
|
||||
int *width,
|
||||
int *height);
|
||||
static void sysprof_cell_renderer_progress_snapshot (GtkCellRenderer *cell,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags);
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (SysprofCellRendererProgress, sysprof_cell_renderer_progress, GTK_TYPE_CELL_RENDERER,
|
||||
G_ADD_PRIVATE (SysprofCellRendererProgress)
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL))
|
||||
|
||||
static void
|
||||
recompute_label (SysprofCellRendererProgress *cellprogress)
|
||||
{
|
||||
SysprofCellRendererProgressPrivate *priv = sysprof_cell_renderer_progress_get_instance_private (cellprogress);
|
||||
char *label;
|
||||
|
||||
if (priv->text)
|
||||
label = g_strdup (priv->text);
|
||||
else if (priv->pulse < 0)
|
||||
label = g_strdup_printf (C_("progress bar label", "%d %%"), priv->value);
|
||||
else
|
||||
label = NULL;
|
||||
|
||||
g_free (priv->label);
|
||||
priv->label = label;
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_cell_renderer_progress_set_value (SysprofCellRendererProgress *cellprogress,
|
||||
int value)
|
||||
{
|
||||
SysprofCellRendererProgressPrivate *priv = sysprof_cell_renderer_progress_get_instance_private (cellprogress);
|
||||
|
||||
if (priv->value != value)
|
||||
{
|
||||
priv->value = value;
|
||||
recompute_label (cellprogress);
|
||||
g_object_notify (G_OBJECT (cellprogress), "value");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_cell_renderer_progress_set_text (SysprofCellRendererProgress *cellprogress,
|
||||
const char *text)
|
||||
{
|
||||
SysprofCellRendererProgressPrivate *priv = sysprof_cell_renderer_progress_get_instance_private (cellprogress);
|
||||
char *new_text;
|
||||
|
||||
new_text = g_strdup (text);
|
||||
g_free (priv->text);
|
||||
priv->text = new_text;
|
||||
recompute_label (cellprogress);
|
||||
g_object_notify (G_OBJECT (cellprogress), "text");
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_cell_renderer_progress_set_pulse (SysprofCellRendererProgress *cellprogress,
|
||||
int pulse)
|
||||
{
|
||||
SysprofCellRendererProgressPrivate *priv = sysprof_cell_renderer_progress_get_instance_private (cellprogress);
|
||||
|
||||
if (pulse != priv->pulse)
|
||||
{
|
||||
if (pulse <= 0)
|
||||
priv->offset = 0;
|
||||
else
|
||||
priv->offset = pulse;
|
||||
g_object_notify (G_OBJECT (cellprogress), "pulse");
|
||||
}
|
||||
|
||||
priv->pulse = pulse;
|
||||
recompute_label (cellprogress);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_cell_renderer_progress_finalize (GObject *object)
|
||||
{
|
||||
SysprofCellRendererProgress *cellprogress = SYSPROF_CELL_RENDERER_PROGRESS (object);
|
||||
SysprofCellRendererProgressPrivate *priv = sysprof_cell_renderer_progress_get_instance_private (cellprogress);
|
||||
|
||||
g_free (priv->text);
|
||||
g_free (priv->label);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_cell_renderer_progress_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_cell_renderer_progress_get_property (GObject *object,
|
||||
guint param_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
SysprofCellRendererProgress *cellprogress = SYSPROF_CELL_RENDERER_PROGRESS (object);
|
||||
SysprofCellRendererProgressPrivate *priv = sysprof_cell_renderer_progress_get_instance_private (cellprogress);
|
||||
|
||||
switch (param_id)
|
||||
{
|
||||
case PROP_VALUE:
|
||||
g_value_set_int (value, priv->value);
|
||||
break;
|
||||
case PROP_TEXT:
|
||||
g_value_set_string (value, priv->text);
|
||||
break;
|
||||
case PROP_PULSE:
|
||||
g_value_set_int (value, priv->pulse);
|
||||
break;
|
||||
case PROP_TEXT_XALIGN:
|
||||
g_value_set_float (value, priv->text_xalign);
|
||||
break;
|
||||
case PROP_TEXT_YALIGN:
|
||||
g_value_set_float (value, priv->text_yalign);
|
||||
break;
|
||||
case PROP_ORIENTATION:
|
||||
g_value_set_enum (value, priv->orientation);
|
||||
break;
|
||||
case PROP_INVERTED:
|
||||
g_value_set_boolean (value, priv->inverted);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_cell_renderer_progress_set_property (GObject *object,
|
||||
guint param_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
SysprofCellRendererProgress *cellprogress = SYSPROF_CELL_RENDERER_PROGRESS (object);
|
||||
SysprofCellRendererProgressPrivate *priv = sysprof_cell_renderer_progress_get_instance_private (cellprogress);
|
||||
|
||||
switch (param_id)
|
||||
{
|
||||
case PROP_VALUE:
|
||||
sysprof_cell_renderer_progress_set_value (cellprogress,
|
||||
g_value_get_int (value));
|
||||
break;
|
||||
case PROP_TEXT:
|
||||
sysprof_cell_renderer_progress_set_text (cellprogress,
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_PULSE:
|
||||
sysprof_cell_renderer_progress_set_pulse (cellprogress,
|
||||
g_value_get_int (value));
|
||||
break;
|
||||
case PROP_TEXT_XALIGN:
|
||||
priv->text_xalign = g_value_get_float (value);
|
||||
break;
|
||||
case PROP_TEXT_YALIGN:
|
||||
priv->text_yalign = g_value_get_float (value);
|
||||
break;
|
||||
case PROP_ORIENTATION:
|
||||
if (priv->orientation != g_value_get_enum (value))
|
||||
{
|
||||
priv->orientation = g_value_get_enum (value);
|
||||
g_object_notify_by_pspec (object, pspec);
|
||||
}
|
||||
break;
|
||||
case PROP_INVERTED:
|
||||
if (priv->inverted != g_value_get_boolean (value))
|
||||
{
|
||||
priv->inverted = g_value_get_boolean (value);
|
||||
g_object_notify_by_pspec (object, pspec);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
compute_dimensions (GtkCellRenderer *cell,
|
||||
GtkWidget *widget,
|
||||
const char *text,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
PangoRectangle logical_rect;
|
||||
PangoLayout *layout;
|
||||
int xpad, ypad;
|
||||
|
||||
layout = gtk_widget_create_pango_layout (widget, text);
|
||||
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
||||
|
||||
gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
|
||||
|
||||
if (width)
|
||||
*width = logical_rect.width + xpad * 2;
|
||||
|
||||
if (height)
|
||||
*height = logical_rect.height + ypad * 2;
|
||||
|
||||
g_object_unref (layout);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_cell_renderer_progress_get_preferred_width (GtkCellRenderer *cell,
|
||||
GtkWidget *widget,
|
||||
int *minimum,
|
||||
int *natural)
|
||||
{
|
||||
SysprofCellRendererProgress *self = SYSPROF_CELL_RENDERER_PROGRESS (cell);
|
||||
SysprofCellRendererProgressPrivate *priv = sysprof_cell_renderer_progress_get_instance_private (self);
|
||||
int w, h;
|
||||
int size;
|
||||
|
||||
if (priv->min_w < 0)
|
||||
{
|
||||
char *text = g_strdup_printf (C_("progress bar label", "%d %%"), 100);
|
||||
compute_dimensions (cell, widget, text,
|
||||
&priv->min_w,
|
||||
&priv->min_h);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
compute_dimensions (cell, widget, priv->label, &w, &h);
|
||||
|
||||
size = MAX (priv->min_w, w);
|
||||
|
||||
if (minimum != NULL)
|
||||
*minimum = size;
|
||||
if (natural != NULL)
|
||||
*natural = size;
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_cell_renderer_progress_get_preferred_height (GtkCellRenderer *cell,
|
||||
GtkWidget *widget,
|
||||
int *minimum,
|
||||
int *natural)
|
||||
{
|
||||
SysprofCellRendererProgress *self = SYSPROF_CELL_RENDERER_PROGRESS (cell);
|
||||
SysprofCellRendererProgressPrivate *priv = sysprof_cell_renderer_progress_get_instance_private (self);
|
||||
int w, h;
|
||||
int size;
|
||||
|
||||
if (priv->min_w < 0)
|
||||
{
|
||||
char *text = g_strdup_printf (C_("progress bar label", "%d %%"), 100);
|
||||
compute_dimensions (cell, widget, text,
|
||||
&priv->min_w,
|
||||
&priv->min_h);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
compute_dimensions (cell, widget, priv->label, &w, &h);
|
||||
|
||||
size = MIN (priv->min_h, h);
|
||||
|
||||
if (minimum != NULL)
|
||||
*minimum = size;
|
||||
if (natural != NULL)
|
||||
*natural = size;
|
||||
}
|
||||
|
||||
static inline int
|
||||
get_bar_size (int pulse,
|
||||
int value,
|
||||
int full_size)
|
||||
{
|
||||
int bar_size;
|
||||
|
||||
if (pulse < 0)
|
||||
bar_size = full_size * MAX (0, value) / 100;
|
||||
else if (pulse == 0)
|
||||
bar_size = 0;
|
||||
else if (pulse == G_MAXINT)
|
||||
bar_size = full_size;
|
||||
else
|
||||
bar_size = MAX (2, full_size / 5);
|
||||
|
||||
return bar_size;
|
||||
}
|
||||
|
||||
static inline int
|
||||
get_bar_position (int start,
|
||||
int full_size,
|
||||
int bar_size,
|
||||
int pulse,
|
||||
int offset,
|
||||
gboolean is_rtl)
|
||||
{
|
||||
int position;
|
||||
|
||||
if (pulse < 0 || pulse == 0 || pulse == G_MAXINT)
|
||||
{
|
||||
position = is_rtl ? (start + full_size - bar_size) : start;
|
||||
}
|
||||
else
|
||||
{
|
||||
position = (is_rtl ? offset + 12 : offset) % 24;
|
||||
if (position > 12)
|
||||
position = 24 - position;
|
||||
position = start + full_size * position / 15;
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_cell_renderer_progress_snapshot (GtkCellRenderer *cell,
|
||||
GtkSnapshot *snapshot,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
{
|
||||
SysprofCellRendererProgress *cellprogress = SYSPROF_CELL_RENDERER_PROGRESS (cell);
|
||||
SysprofCellRendererProgressPrivate *priv = sysprof_cell_renderer_progress_get_instance_private (cellprogress);
|
||||
GtkStyleContext *context;
|
||||
GtkBorder padding;
|
||||
PangoLayout *layout;
|
||||
PangoRectangle logical_rect;
|
||||
int x, y, w, h, x_pos, y_pos, bar_position, bar_size, start, full_size;
|
||||
int xpad, ypad;
|
||||
GdkRectangle clip;
|
||||
gboolean is_rtl;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
|
||||
|
||||
gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
|
||||
x = cell_area->x + xpad;
|
||||
y = cell_area->y + ypad;
|
||||
w = cell_area->width - xpad * 2;
|
||||
h = cell_area->height - ypad * 2;
|
||||
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_class (context, "trough");
|
||||
|
||||
gtk_snapshot_render_background (snapshot, context, x, y, w, h);
|
||||
gtk_snapshot_render_frame (snapshot, context, x, y, w, h);
|
||||
|
||||
gtk_style_context_get_padding (context, &padding);
|
||||
|
||||
x += padding.left;
|
||||
y += padding.top;
|
||||
w -= padding.left + padding.right;
|
||||
h -= padding.top + padding.bottom;
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
clip.y = y;
|
||||
clip.height = h;
|
||||
|
||||
start = x;
|
||||
full_size = w;
|
||||
|
||||
bar_size = get_bar_size (priv->pulse, priv->value, full_size);
|
||||
|
||||
if (!priv->inverted)
|
||||
bar_position = get_bar_position (start, full_size, bar_size,
|
||||
priv->pulse, priv->offset, is_rtl);
|
||||
else
|
||||
bar_position = get_bar_position (start, full_size, bar_size,
|
||||
priv->pulse, priv->offset, !is_rtl);
|
||||
|
||||
clip.width = bar_size;
|
||||
clip.x = bar_position;
|
||||
}
|
||||
else
|
||||
{
|
||||
clip.x = x;
|
||||
clip.width = w;
|
||||
|
||||
start = y;
|
||||
full_size = h;
|
||||
|
||||
bar_size = get_bar_size (priv->pulse, priv->value, full_size);
|
||||
|
||||
if (priv->inverted)
|
||||
bar_position = get_bar_position (start, full_size, bar_size,
|
||||
priv->pulse, priv->offset, TRUE);
|
||||
else
|
||||
bar_position = get_bar_position (start, full_size, bar_size,
|
||||
priv->pulse, priv->offset, FALSE);
|
||||
|
||||
clip.height = bar_size;
|
||||
clip.y = bar_position;
|
||||
}
|
||||
|
||||
if (bar_size > 0)
|
||||
{
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_class (context, "progressbar");
|
||||
|
||||
gtk_snapshot_render_background (snapshot, context, clip.x, clip.y, clip.width, clip.height);
|
||||
gtk_snapshot_render_frame (snapshot, context, clip.x, clip.y, clip.width, clip.height);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
|
||||
if (priv->label)
|
||||
{
|
||||
float text_xalign;
|
||||
|
||||
layout = gtk_widget_create_pango_layout (widget, priv->label);
|
||||
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
||||
|
||||
if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_LTR)
|
||||
text_xalign = 1.0 - priv->text_xalign;
|
||||
else
|
||||
text_xalign = priv->text_xalign;
|
||||
|
||||
x_pos = x + padding.left + text_xalign *
|
||||
(w - padding.left - padding.right - logical_rect.width);
|
||||
|
||||
y_pos = y + padding.top + priv->text_yalign *
|
||||
(h - padding.top - padding.bottom - logical_rect.height);
|
||||
|
||||
gtk_snapshot_push_clip (snapshot,
|
||||
&GRAPHENE_RECT_INIT(
|
||||
clip.x, clip.y,
|
||||
clip.width, clip.height
|
||||
));
|
||||
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_class (context, "progressbar");
|
||||
|
||||
gtk_snapshot_render_layout (snapshot, context,
|
||||
x_pos, y_pos,
|
||||
layout);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_class (context, "trough");
|
||||
|
||||
if (bar_position > start)
|
||||
{
|
||||
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
clip.x = x;
|
||||
clip.width = bar_position - x;
|
||||
}
|
||||
else
|
||||
{
|
||||
clip.y = y;
|
||||
clip.height = bar_position - y;
|
||||
}
|
||||
|
||||
gtk_snapshot_push_clip (snapshot,
|
||||
&GRAPHENE_RECT_INIT(
|
||||
clip.x, clip.y,
|
||||
clip.width, clip.height
|
||||
));
|
||||
|
||||
gtk_snapshot_render_layout (snapshot, context,
|
||||
x_pos, y_pos,
|
||||
layout);
|
||||
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
|
||||
if (bar_position + bar_size < start + full_size)
|
||||
{
|
||||
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
clip.x = bar_position + bar_size;
|
||||
clip.width = x + w - (bar_position + bar_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
clip.y = bar_position + bar_size;
|
||||
clip.height = y + h - (bar_position + bar_size);
|
||||
}
|
||||
|
||||
gtk_snapshot_push_clip (snapshot,
|
||||
&GRAPHENE_RECT_INIT(
|
||||
clip.x, clip.y,
|
||||
clip.width, clip.height
|
||||
));
|
||||
|
||||
gtk_snapshot_render_layout (snapshot, context,
|
||||
x_pos, y_pos,
|
||||
layout);
|
||||
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
g_object_unref (layout);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_cell_renderer_progress_class_init (SysprofCellRendererProgressClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass);
|
||||
|
||||
object_class->finalize = sysprof_cell_renderer_progress_finalize;
|
||||
object_class->get_property = sysprof_cell_renderer_progress_get_property;
|
||||
object_class->set_property = sysprof_cell_renderer_progress_set_property;
|
||||
|
||||
cell_class->get_preferred_width = sysprof_cell_renderer_progress_get_preferred_width;
|
||||
cell_class->get_preferred_height = sysprof_cell_renderer_progress_get_preferred_height;
|
||||
cell_class->snapshot = sysprof_cell_renderer_progress_snapshot;
|
||||
|
||||
/**
|
||||
* SysprofCellRendererProgress:value:
|
||||
*
|
||||
* The "value" property determines the percentage to which the
|
||||
* progress bar will be "filled in".
|
||||
**/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_VALUE,
|
||||
g_param_spec_int ("value",
|
||||
"Value",
|
||||
"Value of the progress bar",
|
||||
0, 100, 0,
|
||||
G_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
|
||||
/**
|
||||
* SysprofCellRendererProgress:text:
|
||||
*
|
||||
* The "text" property determines the label which will be drawn
|
||||
* over the progress bar. Setting this property to %NULL causes the default
|
||||
* label to be displayed. Setting this property to an empty string causes
|
||||
* no label to be displayed.
|
||||
**/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_TEXT,
|
||||
g_param_spec_string ("text",
|
||||
"Text",
|
||||
"Text on the progress bar",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* SysprofCellRendererProgress:pulse:
|
||||
*
|
||||
* Setting this to a non-negative value causes the cell renderer to
|
||||
* enter "activity mode", where a block bounces back and forth to
|
||||
* indicate that some progress is made, without specifying exactly how
|
||||
* much.
|
||||
*
|
||||
* Each increment of the property causes the block to move by a little
|
||||
* bit.
|
||||
*
|
||||
* To indicate that the activity has not started yet, set the property
|
||||
* to zero. To indicate completion, set the property to %G_MAXINT.
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PULSE,
|
||||
g_param_spec_int ("pulse",
|
||||
"Pulse",
|
||||
"Set this to positive values to indicate that some progress is made, but you don’t know how much.",
|
||||
-1, G_MAXINT, -1,
|
||||
G_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
|
||||
/**
|
||||
* SysprofCellRendererProgress:text-xalign:
|
||||
*
|
||||
* The "text-xalign" property controls the horizontal alignment of the
|
||||
* text in the progress bar. Valid values range from 0 (left) to 1
|
||||
* (right). Reserved for RTL layouts.
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_TEXT_XALIGN,
|
||||
g_param_spec_float ("text-xalign",
|
||||
"Text x alignment",
|
||||
"The horizontal text alignment, from 0 (left) to 1 (right). Reversed for RTL layouts.",
|
||||
0.0, 1.0, 0.5,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* SysprofCellRendererProgress:text-yalign:
|
||||
*
|
||||
* The "text-yalign" property controls the vertical alignment of the
|
||||
* text in the progress bar. Valid values range from 0 (top) to 1
|
||||
* (bottom).
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_TEXT_YALIGN,
|
||||
g_param_spec_float ("text-yalign",
|
||||
"Text y alignment",
|
||||
"The vertical text alignment, from 0 (top) to 1 (bottom).",
|
||||
0.0, 1.0, 0.5,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_override_property (object_class,
|
||||
PROP_ORIENTATION,
|
||||
"orientation");
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_INVERTED,
|
||||
g_param_spec_boolean ("inverted",
|
||||
"Inverted",
|
||||
"Invert the direction in which the progress bar grows",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_cell_renderer_progress_init (SysprofCellRendererProgress *cellprogress)
|
||||
{
|
||||
SysprofCellRendererProgressPrivate *priv = sysprof_cell_renderer_progress_get_instance_private (cellprogress);
|
||||
|
||||
priv->value = 0;
|
||||
priv->text = NULL;
|
||||
priv->label = NULL;
|
||||
priv->min_w = -1;
|
||||
priv->min_h = -1;
|
||||
priv->pulse = -1;
|
||||
priv->offset = 0;
|
||||
|
||||
priv->text_xalign = 0.5;
|
||||
priv->text_yalign = 0.5;
|
||||
|
||||
priv->orientation = GTK_ORIENTATION_HORIZONTAL,
|
||||
priv->inverted = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* sysprof_cell_renderer_progress_new:
|
||||
*
|
||||
* Creates a new `SysprofCellRendererProgress`.
|
||||
*
|
||||
* Returns: the new cell renderer
|
||||
**/
|
||||
GtkCellRenderer*
|
||||
sysprof_cell_renderer_progress_new (void)
|
||||
{
|
||||
return g_object_new (SYSPROF_TYPE_CELL_RENDERER_PROGRESS, NULL);
|
||||
}
|
||||
53
src/libsysprof-ui/sysprof-cell-renderer-progress.h
Normal file
53
src/libsysprof-ui/sysprof-cell-renderer-progress.h
Normal file
@ -0,0 +1,53 @@
|
||||
/* gtkcellrendererprogress.h
|
||||
* Copyright (C) 2002 Naba Kumar <kh_naba@users.sourceforge.net>
|
||||
* modified by Jörgen Scheibengruber <mfcn@gmx.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2004. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define SYSPROF_TYPE_CELL_RENDERER_PROGRESS (sysprof_cell_renderer_progress_get_type ())
|
||||
#define SYSPROF_CELL_RENDERER_PROGRESS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SYSPROF_TYPE_CELL_RENDERER_PROGRESS, SysprofCellRendererProgress))
|
||||
#define SYSPROF_IS_CELL_RENDERER_PROGRESS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SYSPROF_TYPE_CELL_RENDERER_PROGRESS))
|
||||
|
||||
typedef struct _SysprofCellRendererProgress SysprofCellRendererProgress;
|
||||
typedef struct _SysprofCellRendererProgressClass SysprofCellRendererProgressClass;
|
||||
typedef struct _SysprofCellRendererProgressPrivate SysprofCellRendererProgressPrivate;
|
||||
|
||||
struct _SysprofCellRendererProgress
|
||||
{
|
||||
GtkCellRenderer parent_instance;
|
||||
};
|
||||
|
||||
struct _SysprofCellRendererProgressClass
|
||||
{
|
||||
GtkCellRendererClass parent_class;
|
||||
};
|
||||
|
||||
GType sysprof_cell_renderer_progress_get_type (void) G_GNUC_CONST;
|
||||
GtkCellRenderer *sysprof_cell_renderer_progress_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
@ -221,7 +221,7 @@ sysprof_cpu_aid_present_finish (SysprofAid *aid,
|
||||
"y-lower", 0.0,
|
||||
"y-upper", 100.0,
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (freq), GTK_WIDGET (freq_row));
|
||||
sysprof_visualizer_group_insert (freq, freq_row, -1, FALSE);
|
||||
|
||||
over_row = g_object_new (SYSPROF_TYPE_LINE_VISUALIZER,
|
||||
"title", _("CPU Usage (All)"),
|
||||
@ -323,17 +323,17 @@ sysprof_cpu_aid_present_finish (SysprofAid *aid,
|
||||
if (has_usage && !found_combined)
|
||||
sysprof_visualizer_group_insert (usage, over_row, 0, FALSE);
|
||||
else
|
||||
gtk_widget_destroy (GTK_WIDGET (over_row));
|
||||
g_object_unref (g_object_ref_sink (over_row));
|
||||
|
||||
if (has_usage)
|
||||
sysprof_display_add_group (present->display, usage);
|
||||
else
|
||||
gtk_widget_destroy (GTK_WIDGET (usage));
|
||||
g_object_unref (g_object_ref_sink (usage));
|
||||
|
||||
if (has_freq)
|
||||
sysprof_display_add_group (present->display, freq);
|
||||
else
|
||||
gtk_widget_destroy (GTK_WIDGET (freq));
|
||||
g_object_unref (g_object_ref_sink (freq));
|
||||
}
|
||||
|
||||
return counters != NULL;
|
||||
|
||||
@ -34,7 +34,8 @@ struct _SysprofDepthVisualizer
|
||||
PointCache *points;
|
||||
guint reload_source;
|
||||
guint mode;
|
||||
GtkAllocation last_alloc;
|
||||
int last_width;
|
||||
int last_height;
|
||||
guint reloading : 1;
|
||||
guint needs_reload : 1;
|
||||
};
|
||||
@ -238,34 +239,46 @@ sysprof_depth_visualizer_set_reader (SysprofVisualizer *row,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sysprof_depth_visualizer_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
static void
|
||||
sysprof_depth_visualizer_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
SysprofDepthVisualizer *self = (SysprofDepthVisualizer *)widget;
|
||||
GtkAllocation alloc;
|
||||
GdkRectangle clip;
|
||||
const Point *points;
|
||||
gboolean ret;
|
||||
cairo_t *cr;
|
||||
guint n_points = 0;
|
||||
GdkRGBA user;
|
||||
GdkRGBA system;
|
||||
|
||||
g_assert (SYSPROF_IS_DEPTH_VISUALIZER (self));
|
||||
g_assert (cr != NULL);
|
||||
g_assert (snapshot != NULL);
|
||||
|
||||
ret = GTK_WIDGET_CLASS (sysprof_depth_visualizer_parent_class)->draw (widget, cr);
|
||||
GTK_WIDGET_CLASS (sysprof_depth_visualizer_parent_class)->snapshot (widget, snapshot);
|
||||
|
||||
if (self->points == NULL)
|
||||
return ret;
|
||||
return;
|
||||
|
||||
gdk_rgba_parse (&user, "#1a5fb4");
|
||||
gdk_rgba_parse (&system, "#3584e4");
|
||||
|
||||
gtk_widget_get_allocation (widget, &alloc);
|
||||
|
||||
cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT (0, 0, alloc.width, alloc.height));
|
||||
|
||||
/* FIXME: we should abstract visualizer drawing into regions so that we
|
||||
* can still know the region we're drawing.
|
||||
*/
|
||||
#if 0
|
||||
if (!gdk_cairo_get_clip_rectangle (cr, &clip))
|
||||
return ret;
|
||||
return;
|
||||
#else
|
||||
clip.x = alloc.x = 0;
|
||||
clip.y = alloc.y = 0;
|
||||
clip.width = alloc.width;
|
||||
clip.height = alloc.height;
|
||||
#endif
|
||||
|
||||
/* Draw user-space stacks */
|
||||
if (self->mode != SYSPROF_DEPTH_VISUALIZER_KERNEL_ONLY &&
|
||||
@ -355,7 +368,7 @@ sysprof_depth_visualizer_draw (GtkWidget *widget,
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -372,25 +385,23 @@ sysprof_depth_visualizer_queue_reload (SysprofDepthVisualizer *self)
|
||||
{
|
||||
g_assert (SYSPROF_IS_DEPTH_VISUALIZER (self));
|
||||
|
||||
if (self->reload_source)
|
||||
g_source_remove (self->reload_source);
|
||||
|
||||
self->reload_source = gdk_threads_add_idle (sysprof_depth_visualizer_do_reload, self);
|
||||
g_clear_handle_id (&self->reload_source, g_source_remove);
|
||||
self->reload_source = g_idle_add (sysprof_depth_visualizer_do_reload, self);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_depth_visualizer_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *alloc)
|
||||
sysprof_depth_visualizer_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
SysprofDepthVisualizer *self = (SysprofDepthVisualizer *)widget;
|
||||
|
||||
GTK_WIDGET_CLASS (sysprof_depth_visualizer_parent_class)->size_allocate (widget, alloc);
|
||||
|
||||
if (alloc->width != self->last_alloc.x ||
|
||||
alloc->height != self->last_alloc.height)
|
||||
if (width != self->last_width || height != self->last_height)
|
||||
{
|
||||
sysprof_depth_visualizer_queue_reload (SYSPROF_DEPTH_VISUALIZER (widget));
|
||||
self->last_alloc = *alloc;
|
||||
self->last_width = width;
|
||||
self->last_height = height;
|
||||
}
|
||||
}
|
||||
|
||||
@ -400,12 +411,7 @@ sysprof_depth_visualizer_finalize (GObject *object)
|
||||
SysprofDepthVisualizer *self = (SysprofDepthVisualizer *)object;
|
||||
|
||||
g_clear_pointer (&self->reader, sysprof_capture_reader_unref);
|
||||
|
||||
if (self->reload_source)
|
||||
{
|
||||
g_source_remove (self->reload_source);
|
||||
self->reload_source = 0;
|
||||
}
|
||||
g_clear_handle_id (&self->reload_source, g_source_remove);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_depth_visualizer_parent_class)->finalize (object);
|
||||
}
|
||||
@ -419,7 +425,7 @@ sysprof_depth_visualizer_class_init (SysprofDepthVisualizerClass *klass)
|
||||
|
||||
object_class->finalize = sysprof_depth_visualizer_finalize;
|
||||
|
||||
widget_class->draw = sysprof_depth_visualizer_draw;
|
||||
widget_class->snapshot = sysprof_depth_visualizer_snapshot;
|
||||
widget_class->size_allocate = sysprof_depth_visualizer_size_allocate;
|
||||
|
||||
row_class->set_reader = sysprof_depth_visualizer_set_reader;
|
||||
|
||||
@ -22,19 +22,20 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <dazzle.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sysprof-details-page.h"
|
||||
#include "sysprof-ui-private.h"
|
||||
|
||||
#include "egg-three-grid.h"
|
||||
|
||||
struct _SysprofDetailsPage
|
||||
{
|
||||
SysprofPage parent_instance;
|
||||
GtkWidget parent_instance;
|
||||
|
||||
/* Template Objects */
|
||||
DzlThreeGrid *three_grid;
|
||||
EggThreeGrid *three_grid;
|
||||
GtkListStore *marks_store;
|
||||
GtkTreeView *marks_view;
|
||||
GtkLabel *counters;
|
||||
@ -51,7 +52,7 @@ struct _SysprofDetailsPage
|
||||
guint next_row;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (SysprofDetailsPage, sysprof_details_page, GTK_TYPE_BIN)
|
||||
G_DEFINE_TYPE (SysprofDetailsPage, sysprof_details_page, GTK_TYPE_WIDGET)
|
||||
|
||||
#if GLIB_CHECK_VERSION(2, 56, 0)
|
||||
# define _g_date_time_new_from_iso8601 g_date_time_new_from_iso8601
|
||||
@ -76,12 +77,28 @@ _g_date_time_new_from_iso8601 (const gchar *str,
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
sysprof_details_page_dispose (GObject *object)
|
||||
{
|
||||
SysprofDetailsPage *self = (SysprofDetailsPage *)object;
|
||||
GtkWidget *child;
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self))))
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_details_page_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_details_page_class_init (SysprofDetailsPageClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = sysprof_details_page_dispose;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/sysprof/ui/sysprof-details-page.ui");
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofDetailsPage, allocations);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofDetailsPage, counters);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofDetailsPage, cpu_label);
|
||||
@ -96,7 +113,7 @@ sysprof_details_page_class_init (SysprofDetailsPageClass *klass)
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofDetailsPage, start_time);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofDetailsPage, three_grid);
|
||||
|
||||
g_type_ensure (DZL_TYPE_THREE_GRID);
|
||||
g_type_ensure (EGG_TYPE_THREE_GRID);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -264,16 +281,10 @@ sysprof_details_page_add_item (SysprofDetailsPage *self,
|
||||
g_return_if_fail (!center || GTK_IS_WIDGET (center));
|
||||
|
||||
if (left)
|
||||
gtk_container_add_with_properties (GTK_CONTAINER (self->three_grid), left,
|
||||
"row", self->next_row,
|
||||
"column", DZL_THREE_GRID_COLUMN_LEFT,
|
||||
NULL);
|
||||
egg_three_grid_add (self->three_grid, left, self->next_row, EGG_THREE_GRID_COLUMN_LEFT);
|
||||
|
||||
if (center)
|
||||
gtk_container_add_with_properties (GTK_CONTAINER (self->three_grid), center,
|
||||
"row", self->next_row,
|
||||
"column", DZL_THREE_GRID_COLUMN_CENTER,
|
||||
NULL);
|
||||
egg_three_grid_add (self->three_grid, center, self->next_row, EGG_THREE_GRID_COLUMN_CENTER);
|
||||
|
||||
self->next_row++;
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ SYSPROF_ALIGNED_END (8);
|
||||
|
||||
#define SYSPROF_TYPE_DETAILS_PAGE (sysprof_details_page_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (SysprofDetailsPage, sysprof_details_page, SYSPROF, DETAILS_PAGE, GtkBin)
|
||||
G_DECLARE_FINAL_TYPE (SysprofDetailsPage, sysprof_details_page, SYSPROF, DETAILS_PAGE, GtkWidget)
|
||||
|
||||
GtkWidget *sysprof_details_page_new (void);
|
||||
void sysprof_details_page_set_reader (SysprofDetailsPage *self,
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.22"/>
|
||||
<template class="SysprofDetailsPage" parent="GtkBin">
|
||||
<property name="can_focus">False</property>
|
||||
<template class="SysprofDetailsPage" parent="GtkWidget">
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="propagate-natural-height">true</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="DzlThreeGrid" id="three_grid">
|
||||
<property name="margin">36</property>
|
||||
<object class="EggThreeGrid" id="three_grid">
|
||||
<property name="margin-start">36</property>
|
||||
<property name="margin-end">36</property>
|
||||
<property name="margin-top">36</property>
|
||||
<property name="margin-bottom">36</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="visible">true</property>
|
||||
@ -23,11 +23,11 @@
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">left</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
@ -37,41 +37,39 @@
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">left</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Duration</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">left</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">CPU Model</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">left</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
@ -82,11 +80,11 @@
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">left</property>
|
||||
<property name="row">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
@ -96,11 +94,11 @@
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">left</property>
|
||||
<property name="row">5</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
@ -110,11 +108,11 @@
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">left</property>
|
||||
<property name="row">6</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
@ -124,11 +122,11 @@
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">left</property>
|
||||
<property name="row">7</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">7</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
@ -138,11 +136,11 @@
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">left</property>
|
||||
<property name="row">8</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">8</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
@ -153,148 +151,137 @@
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">left</property>
|
||||
<property name="row">9</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">9</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="filename">
|
||||
<property name="width-chars">35</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="ellipsize">start</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">True</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">1</property>
|
||||
<property name="row">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="start_time">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="ellipsize">start</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">True</property>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="duration">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">True</property>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="cpu_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="ellipsize">end</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">True</property>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="samples">
|
||||
<property name="margin-top">12</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="ellipsize">start</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">True</property>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="marks">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="ellipsize">start</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">True</property>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">5</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="processes">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="ellipsize">start</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">True</property>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">6</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="forks">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="ellipsize">start</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">True</property>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">7</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">7</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="counters">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="ellipsize">start</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">True</property>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">8</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">8</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="allocations">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="ellipsize">start</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">True</property>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">9</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">9</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<property name="visible">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="marks_view">
|
||||
@ -371,11 +358,11 @@
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">10</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">10</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@ -245,7 +245,7 @@ sysprof_diskstat_aid_present_finish (SysprofAid *aid,
|
||||
if (counters->len > 0)
|
||||
sysprof_display_add_group (present->display, group);
|
||||
else
|
||||
gtk_widget_destroy (GTK_WIDGET (group));
|
||||
g_object_unref (g_object_ref_sink (group));
|
||||
}
|
||||
|
||||
return counters != NULL;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* sysprof-window-settings.h
|
||||
/* sysprof-display-private.h
|
||||
*
|
||||
* Copyright 2016 Christian Hergert <chergert@redhat.com>
|
||||
* Copyright 2021 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -14,17 +14,16 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef SYSPROF_WINDOW_SETTINGS_H
|
||||
#define SYSPROF_WINDOW_SETTINGS_H
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "sysprof-display.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void sysprof_window_settings_register (GtkWindow *window);
|
||||
void _sysprof_display_destroy (SysprofDisplay *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* SYSPROF_WINDOW_SETTINGS_H */
|
||||
@ -22,11 +22,12 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <dazzle.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "egg-paned-private.h"
|
||||
|
||||
#include "sysprof-details-page.h"
|
||||
#include "sysprof-display.h"
|
||||
#include "sysprof-display-private.h"
|
||||
#include "sysprof-profiler-assistant.h"
|
||||
#include "sysprof-failed-state-view.h"
|
||||
#include "sysprof-recording-state-view.h"
|
||||
@ -72,7 +73,7 @@ typedef struct
|
||||
SysprofCaptureFlags flags;
|
||||
} SysprofDisplayPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (SysprofDisplay, sysprof_display, GTK_TYPE_BIN)
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (SysprofDisplay, sysprof_display, GTK_TYPE_WIDGET)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@ -96,10 +97,7 @@ update_title_child_property (SysprofDisplay *self)
|
||||
if ((parent = gtk_widget_get_parent (GTK_WIDGET (self))) && GTK_IS_NOTEBOOK (parent))
|
||||
{
|
||||
g_autofree gchar *title = sysprof_display_dup_title (self);
|
||||
|
||||
gtk_container_child_set (GTK_CONTAINER (parent), GTK_WIDGET (self),
|
||||
"menu-label", title,
|
||||
NULL);
|
||||
gtk_notebook_set_menu_label_text (GTK_NOTEBOOK (parent), GTK_WIDGET (self), title);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_TITLE]);
|
||||
@ -319,19 +317,17 @@ sysprof_display_notify_selection_cb (SysprofDisplay *self,
|
||||
/* Opportunistically load pages */
|
||||
if (priv->reader != NULL)
|
||||
{
|
||||
GList *pages = gtk_container_get_children (GTK_CONTAINER (priv->pages));
|
||||
|
||||
for (const GList *iter = pages; iter; iter = iter->next)
|
||||
for (GtkWidget *child = gtk_widget_get_first_child (GTK_WIDGET (priv->pages));
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
if (SYSPROF_IS_PAGE (iter->data))
|
||||
sysprof_page_load_async (iter->data,
|
||||
if (SYSPROF_IS_PAGE (child))
|
||||
sysprof_page_load_async (SYSPROF_PAGE (child),
|
||||
priv->reader,
|
||||
selection,
|
||||
priv->filter,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
g_list_free (pages);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -372,15 +368,21 @@ stop_recording_cb (GSimpleAction *action,
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_display_finalize (GObject *object)
|
||||
sysprof_display_dispose (GObject *object)
|
||||
{
|
||||
SysprofDisplay *self = (SysprofDisplay *)object;
|
||||
SysprofDisplayPrivate *priv = sysprof_display_get_instance_private (self);
|
||||
|
||||
if (priv->stack)
|
||||
{
|
||||
gtk_widget_unparent (GTK_WIDGET (priv->stack));
|
||||
priv->stack = NULL;
|
||||
}
|
||||
|
||||
g_clear_pointer (&priv->reader, sysprof_capture_reader_unref);
|
||||
g_clear_pointer (&priv->filter, sysprof_capture_condition_unref);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_display_parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (sysprof_display_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -443,7 +445,7 @@ sysprof_display_class_init (SysprofDisplayClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->finalize = sysprof_display_finalize;
|
||||
object_class->dispose = sysprof_display_dispose;
|
||||
object_class->get_property = sysprof_display_get_property;
|
||||
object_class->set_property = sysprof_display_set_property;
|
||||
|
||||
@ -453,6 +455,7 @@ sysprof_display_class_init (SysprofDisplayClass *klass)
|
||||
"/org/gnome/sysprof/css/SysprofDisplay-shared.css");
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/sysprof/ui/sysprof-display.ui");
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
gtk_widget_class_set_css_name (widget_class, "SysprofDisplay");
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofDisplay, assistant);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofDisplay, details);
|
||||
@ -499,7 +502,7 @@ sysprof_display_class_init (SysprofDisplayClass *klass)
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
g_type_ensure (DZL_TYPE_MULTI_PANED);
|
||||
g_type_ensure (EGG_TYPE_PANED);
|
||||
g_type_ensure (SYSPROF_TYPE_DETAILS_PAGE);
|
||||
g_type_ensure (SYSPROF_TYPE_FAILED_STATE_VIEW);
|
||||
g_type_ensure (SYSPROF_TYPE_PROFILER_ASSISTANT);
|
||||
@ -552,7 +555,7 @@ sysprof_display_add_group (SysprofDisplay *self,
|
||||
if (priv->reader != NULL)
|
||||
_sysprof_visualizer_group_set_reader (group, priv->reader);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (priv->visualizers), GTK_WIDGET (group));
|
||||
sysprof_visualizers_frame_add_group (priv->visualizers, group);
|
||||
}
|
||||
|
||||
void
|
||||
@ -567,10 +570,7 @@ sysprof_display_add_page (SysprofDisplay *self,
|
||||
g_return_if_fail (SYSPROF_IS_PAGE (page));
|
||||
|
||||
title = sysprof_page_get_title (page);
|
||||
|
||||
gtk_container_add_with_properties (GTK_CONTAINER (priv->pages), GTK_WIDGET (page),
|
||||
"title", title,
|
||||
NULL);
|
||||
gtk_stack_add_titled (priv->pages, GTK_WIDGET (page), NULL, title);
|
||||
|
||||
selection = sysprof_visualizers_frame_get_selection (priv->visualizers);
|
||||
|
||||
@ -933,7 +933,6 @@ sysprof_display_load_scan_cb (GObject *object,
|
||||
SysprofCaptureReader *reader;
|
||||
SysprofSelection *selection;
|
||||
GCancellable *cancellable;
|
||||
GList *pages;
|
||||
|
||||
g_assert (SYSPROF_IS_DISPLAY (self));
|
||||
g_assert (G_IS_ASYNC_RESULT (result));
|
||||
@ -956,17 +955,17 @@ sysprof_display_load_scan_cb (GObject *object,
|
||||
sysprof_details_page_set_reader (priv->details, reader);
|
||||
|
||||
/* Opportunistically load pages */
|
||||
pages = gtk_container_get_children (GTK_CONTAINER (priv->pages));
|
||||
for (const GList *iter = pages; iter; iter = iter->next)
|
||||
for (GtkWidget *child = gtk_widget_get_first_child (GTK_WIDGET (priv->pages));
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
if (SYSPROF_IS_PAGE (iter->data))
|
||||
sysprof_page_load_async (iter->data,
|
||||
if (SYSPROF_IS_PAGE (child))
|
||||
sysprof_page_load_async (SYSPROF_PAGE (child),
|
||||
reader,
|
||||
selection,
|
||||
priv->filter,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
g_list_free (pages);
|
||||
|
||||
gtk_stack_set_visible_child_name (priv->stack, "view");
|
||||
}
|
||||
@ -1097,12 +1096,13 @@ sysprof_display_open (SysprofDisplay *self,
|
||||
error->message);
|
||||
g_signal_connect (dialog,
|
||||
"response",
|
||||
G_CALLBACK (gtk_widget_destroy),
|
||||
G_CALLBACK (gtk_window_destroy),
|
||||
NULL);
|
||||
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window));
|
||||
gtk_window_present (GTK_WINDOW (dialog));
|
||||
gtk_widget_destroy (GTK_WIDGET (self));
|
||||
|
||||
_sysprof_display_destroy (self);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1200,36 +1200,21 @@ sysprof_display_new_for_profiler (SysprofProfiler *profiler)
|
||||
return GTK_WIDGET (g_steal_pointer (&self));
|
||||
}
|
||||
|
||||
void
|
||||
sysprof_display_save (SysprofDisplay *self)
|
||||
static void
|
||||
on_save_response_cb (SysprofDisplay *self,
|
||||
int res,
|
||||
GtkFileChooserNative *chooser)
|
||||
{
|
||||
SysprofDisplayPrivate *priv = sysprof_display_get_instance_private (self);
|
||||
g_autoptr(GFile) file = NULL;
|
||||
GtkFileChooserNative *native;
|
||||
GtkWindow *parent;
|
||||
gint res;
|
||||
|
||||
g_return_if_fail (SYSPROF_IS_DISPLAY (self));
|
||||
g_return_if_fail (priv->reader != NULL);
|
||||
|
||||
parent = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self)));
|
||||
|
||||
native = gtk_file_chooser_native_new (_("Save Recording"),
|
||||
parent,
|
||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
_("Save"),
|
||||
_("Cancel"));
|
||||
gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (native), TRUE);
|
||||
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (native), TRUE);
|
||||
gtk_file_chooser_set_create_folders (GTK_FILE_CHOOSER (native), TRUE);
|
||||
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (native), "capture.syscap");
|
||||
|
||||
res = gtk_native_dialog_run (GTK_NATIVE_DIALOG (native));
|
||||
g_assert (SYSPROF_IS_DISPLAY (self));
|
||||
g_assert (GTK_IS_FILE_CHOOSER_NATIVE (chooser));
|
||||
|
||||
switch (res)
|
||||
{
|
||||
case GTK_RESPONSE_ACCEPT:
|
||||
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (native));
|
||||
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (chooser));
|
||||
|
||||
if (g_file_is_native (file))
|
||||
{
|
||||
@ -1239,17 +1224,24 @@ sysprof_display_save (SysprofDisplay *self)
|
||||
if (!sysprof_capture_reader_save_as_with_error (priv->reader, path, &error))
|
||||
{
|
||||
GtkWidget *msg;
|
||||
GtkNative *root;
|
||||
|
||||
msg = gtk_message_dialog_new (parent,
|
||||
root = gtk_widget_get_native (GTK_WIDGET (self));
|
||||
msg = gtk_message_dialog_new (GTK_WINDOW (root),
|
||||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_USE_HEADER_BAR,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
_("Failed to save recording: %s"),
|
||||
error->message);
|
||||
gtk_window_present (GTK_WINDOW (msg));
|
||||
g_signal_connect (msg, "response", G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
g_signal_connect (msg, "response", G_CALLBACK (gtk_window_destroy), NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_autofree char *uri = g_file_get_uri (file);
|
||||
g_warning ("%s is not native, cannot open", uri);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@ -1258,7 +1250,35 @@ sysprof_display_save (SysprofDisplay *self)
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_TITLE]);
|
||||
gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (native));
|
||||
gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (chooser));
|
||||
}
|
||||
|
||||
void
|
||||
sysprof_display_save (SysprofDisplay *self)
|
||||
{
|
||||
SysprofDisplayPrivate *priv = sysprof_display_get_instance_private (self);
|
||||
GtkFileChooserNative *native;
|
||||
GtkNative *root;
|
||||
|
||||
g_return_if_fail (SYSPROF_IS_DISPLAY (self));
|
||||
g_return_if_fail (priv->reader != NULL);
|
||||
|
||||
root = gtk_widget_get_native (GTK_WIDGET (self));
|
||||
native = gtk_file_chooser_native_new (_("Save Recording"),
|
||||
GTK_WINDOW (root),
|
||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
_("Save"),
|
||||
_("Cancel"));
|
||||
gtk_file_chooser_set_create_folders (GTK_FILE_CHOOSER (native), TRUE);
|
||||
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (native), "capture.syscap");
|
||||
|
||||
g_signal_connect_object (native,
|
||||
"response",
|
||||
G_CALLBACK (on_save_response_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
gtk_native_dialog_show (GTK_NATIVE_DIALOG (native));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1294,3 +1314,15 @@ sysprof_display_add_to_selection (SysprofDisplay *self,
|
||||
selection = sysprof_visualizers_frame_get_selection (priv->visualizers);
|
||||
sysprof_selection_select_range (selection, begin_time, end_time);
|
||||
}
|
||||
|
||||
void
|
||||
_sysprof_display_destroy (SysprofDisplay *self)
|
||||
{
|
||||
GtkWidget *parent;
|
||||
|
||||
g_return_if_fail (SYSPROF_IS_DISPLAY (self));
|
||||
|
||||
if ((parent = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_NOTEBOOK)))
|
||||
gtk_notebook_remove_page (GTK_NOTEBOOK (parent),
|
||||
gtk_notebook_page_num (GTK_NOTEBOOK (parent), GTK_WIDGET (self)));
|
||||
}
|
||||
|
||||
@ -32,11 +32,11 @@ G_BEGIN_DECLS
|
||||
#define SYSPROF_TYPE_DISPLAY (sysprof_display_get_type())
|
||||
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
G_DECLARE_DERIVABLE_TYPE (SysprofDisplay, sysprof_display, SYSPROF, DISPLAY, GtkBin)
|
||||
G_DECLARE_DERIVABLE_TYPE (SysprofDisplay, sysprof_display, SYSPROF, DISPLAY, GtkWidget)
|
||||
|
||||
struct _SysprofDisplayClass
|
||||
{
|
||||
GtkBinClass parent_class;
|
||||
GtkWidgetClass parent_class;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _reserved[16];
|
||||
|
||||
@ -1,77 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="SysprofDisplay" parent="GtkBin">
|
||||
<requires lib="gtk" version="4.0"/>
|
||||
<template class="SysprofDisplay" parent="GtkWidget">
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="homogeneous">false</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="hhomogeneous">0</property>
|
||||
<property name="vhomogeneous">0</property>
|
||||
<child>
|
||||
<object class="SysprofProfilerAssistant" id="assistant">
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
<packing>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">assistant</property>
|
||||
</packing>
|
||||
<property name="child">
|
||||
<object class="SysprofProfilerAssistant" id="assistant">
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="DzlMultiPaned">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="vexpand">false</property>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">view</property>
|
||||
<property name="child">
|
||||
<object class="EggPaned">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="SysprofVisualizersFrame" id="visualizers">
|
||||
<property name="vexpand">false</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="pages">
|
||||
<property name="hhomogeneous">0</property>
|
||||
<property name="vhomogeneous">0</property>
|
||||
<property name="vexpand">true</property>
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="title" translatable="yes">Details</property>
|
||||
<property name="name">details</property>
|
||||
<property name="child">
|
||||
<object class="SysprofDetailsPage" id="details">
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="pages">
|
||||
<property name="homogeneous">false</property>
|
||||
<property name="vexpand">true</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="SysprofDetailsPage" id="details">
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="title" translatable="yes">Details</property>
|
||||
<property name="name">details</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">view</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="SysprofRecordingStateView" id="recording_view">
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
<packing>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">record</property>
|
||||
</packing>
|
||||
<property name="child">
|
||||
<object class="SysprofRecordingStateView" id="recording_view">
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="SysprofFailedStateView" id="failed_view">
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
<packing>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">failed</property>
|
||||
</packing>
|
||||
<property name="child">
|
||||
<object class="SysprofFailedStateView" id="failed_view">
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@ -296,35 +296,37 @@ sysprof_duplex_visualizer_set_reader (SysprofVisualizer *visualizer,
|
||||
g_task_run_in_thread (task, sysprof_duplex_visualizer_worker);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sysprof_duplex_visualizer_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
static void
|
||||
sysprof_duplex_visualizer_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
static const gdouble dashes[] = { 1.0, 2.0 };
|
||||
SysprofDuplexVisualizer *self = (SysprofDuplexVisualizer *)widget;
|
||||
PangoFontDescription *font_desc;
|
||||
GtkStyleContext *style_context;
|
||||
PangoLayout *layout;
|
||||
cairo_t *cr;
|
||||
GtkAllocation alloc;
|
||||
GdkRectangle clip;
|
||||
gboolean ret;
|
||||
GdkRGBA fg;
|
||||
guint mid;
|
||||
|
||||
g_assert (SYSPROF_IS_DUPLEX_VISUALIZER (self));
|
||||
g_assert (cr != NULL);
|
||||
g_assert (snapshot != NULL);
|
||||
|
||||
/* FIXME: This should all be drawn offscreen and then drawn to the snapshot
|
||||
* using GdkMemoryTexture so that we can avoid extra GPU uploads.
|
||||
*/
|
||||
|
||||
gtk_widget_get_allocation (widget, &alloc);
|
||||
gdk_cairo_get_clip_rectangle (cr, &clip);
|
||||
|
||||
mid = alloc.height / 2;
|
||||
|
||||
ret = GTK_WIDGET_CLASS (sysprof_duplex_visualizer_parent_class)->draw (widget, cr);
|
||||
GTK_WIDGET_CLASS (sysprof_duplex_visualizer_parent_class)->snapshot (widget, snapshot);
|
||||
|
||||
cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT (0, 0, alloc.width, alloc.height));
|
||||
|
||||
style_context = gtk_widget_get_style_context (widget);
|
||||
gtk_style_context_get_color (style_context,
|
||||
gtk_style_context_get_state (style_context),
|
||||
&fg);
|
||||
gtk_style_context_get_color (style_context, &fg);
|
||||
fg.alpha *= 0.4;
|
||||
|
||||
/* Draw our center line */
|
||||
@ -366,6 +368,7 @@ sysprof_duplex_visualizer_draw (GtkWidget *widget,
|
||||
n_fpoints);
|
||||
|
||||
/* Skip past data that we won't see anyway */
|
||||
#if 0
|
||||
for (p = 0; p < n_fpoints; p++)
|
||||
{
|
||||
if (points[p].x >= clip.x)
|
||||
@ -373,7 +376,8 @@ sysprof_duplex_visualizer_draw (GtkWidget *widget,
|
||||
}
|
||||
|
||||
if (p >= n_fpoints)
|
||||
return ret;
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* But get at least one data point to anchor out of view */
|
||||
if (p > 0)
|
||||
@ -398,8 +402,10 @@ sysprof_duplex_visualizer_draw (GtkWidget *widget,
|
||||
last_x = points[i].x;
|
||||
last_y = points[i].y;
|
||||
|
||||
#if 0
|
||||
if (points[i].x > clip.x + clip.width)
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
cairo_line_to (cr, last_x, mid);
|
||||
@ -436,6 +442,7 @@ sysprof_duplex_visualizer_draw (GtkWidget *widget,
|
||||
points,
|
||||
n_fpoints);
|
||||
|
||||
#if 0
|
||||
/* Skip past data that we won't see anyway */
|
||||
for (p = 0; p < n_fpoints; p++)
|
||||
{
|
||||
@ -445,6 +452,7 @@ sysprof_duplex_visualizer_draw (GtkWidget *widget,
|
||||
|
||||
if (p >= n_fpoints)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
/* But get at least one data point to anchor out of view */
|
||||
if (p > 0)
|
||||
@ -469,8 +477,10 @@ sysprof_duplex_visualizer_draw (GtkWidget *widget,
|
||||
last_x = points[i].x;
|
||||
last_y = points[i].y;
|
||||
|
||||
#if 0
|
||||
if (points[i].x > clip.x + clip.width)
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
cairo_line_to (cr, last_x, mid);
|
||||
@ -510,7 +520,7 @@ sysprof_duplex_visualizer_draw (GtkWidget *widget,
|
||||
pango_font_description_free (font_desc);
|
||||
g_object_unref (layout);
|
||||
|
||||
return ret;
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -534,7 +544,7 @@ sysprof_duplex_visualizer_class_init (SysprofDuplexVisualizerClass *klass)
|
||||
|
||||
object_class->finalize = sysprof_duplex_visualizer_finalize;
|
||||
|
||||
widget_class->draw = sysprof_duplex_visualizer_draw;
|
||||
widget_class->snapshot = sysprof_duplex_visualizer_snapshot;
|
||||
|
||||
visualizer_class->set_reader = sysprof_duplex_visualizer_set_reader;
|
||||
}
|
||||
|
||||
@ -127,9 +127,9 @@ value_entry_activate (GtkWidget *entry,
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_environ_editor_row_destroy (GtkWidget *widget)
|
||||
sysprof_environ_editor_row_dispose (GObject *object)
|
||||
{
|
||||
SysprofEnvironEditorRow *self = (SysprofEnvironEditorRow *)widget;
|
||||
SysprofEnvironEditorRow *self = (SysprofEnvironEditorRow *)object;
|
||||
|
||||
if (self->variable != NULL)
|
||||
{
|
||||
@ -137,7 +137,7 @@ sysprof_environ_editor_row_destroy (GtkWidget *widget)
|
||||
g_clear_object (&self->variable);
|
||||
}
|
||||
|
||||
GTK_WIDGET_CLASS (sysprof_environ_editor_row_parent_class)->destroy (widget);
|
||||
G_OBJECT_CLASS (sysprof_environ_editor_row_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -184,11 +184,10 @@ sysprof_environ_editor_row_class_init (SysprofEnvironEditorRowClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = sysprof_environ_editor_row_dispose;
|
||||
object_class->get_property = sysprof_environ_editor_row_get_property;
|
||||
object_class->set_property = sysprof_environ_editor_row_set_property;
|
||||
|
||||
widget_class->destroy = sysprof_environ_editor_row_destroy;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/sysprof/ui/sysprof-environ-editor-row.ui");
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofEnvironEditorRow, delete_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofEnvironEditorRow, key_entry);
|
||||
|
||||
@ -1,78 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.10"/>
|
||||
<template class="SysprofEnvironEditorRow" parent="GtkListBoxRow">
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="key_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="margin_start">3</property>
|
||||
<property name="has_frame">False</property>
|
||||
<property name="margin-start">3</property>
|
||||
<property name="has-frame">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="eq_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label">=</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="value_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="has_frame">False</property>
|
||||
<property name="has-frame">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="delete_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Remove environment variable</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">list-remove-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
<property name="tooltip-text" translatable="yes">Remove environment variable</property>
|
||||
<property name="icon-name">list-remove-symbolic</property>
|
||||
<style>
|
||||
<class name="image-button"/>
|
||||
<class name="flat"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@ -30,13 +30,14 @@
|
||||
|
||||
struct _SysprofEnvironEditor
|
||||
{
|
||||
GtkListBox parent_instance;
|
||||
GtkWidget parent_instance;
|
||||
GtkListBox *list_box;
|
||||
SysprofEnviron *environ;
|
||||
GtkWidget *dummy_row;
|
||||
SysprofEnvironVariable *dummy;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (SysprofEnvironEditor, sysprof_environ_editor, GTK_TYPE_LIST_BOX)
|
||||
G_DEFINE_TYPE (SysprofEnvironEditor, sysprof_environ_editor, GTK_TYPE_WIDGET)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@ -69,7 +70,10 @@ sysprof_environ_editor_create_dummy_row (SysprofEnvironEditor *self)
|
||||
|
||||
label = g_object_new (GTK_TYPE_LABEL,
|
||||
"label", _("New variable…"),
|
||||
"margin", 6,
|
||||
"margin-start", 6,
|
||||
"margin-end", 6,
|
||||
"margin-top", 6,
|
||||
"margin-bottom", 6,
|
||||
"visible", TRUE,
|
||||
"xalign", 0.0f,
|
||||
NULL);
|
||||
@ -114,8 +118,7 @@ sysprof_environ_editor_disconnect (SysprofEnvironEditor *self)
|
||||
g_assert (SYSPROF_IS_ENVIRON_EDITOR (self));
|
||||
g_assert (SYSPROF_IS_ENVIRON (self->environ));
|
||||
|
||||
gtk_list_box_bind_model (GTK_LIST_BOX (self), NULL, NULL, NULL, NULL);
|
||||
|
||||
gtk_list_box_bind_model (self->list_box, NULL, NULL, NULL, NULL);
|
||||
g_clear_object (&self->dummy);
|
||||
}
|
||||
|
||||
@ -125,12 +128,12 @@ sysprof_environ_editor_connect (SysprofEnvironEditor *self)
|
||||
g_assert (SYSPROF_IS_ENVIRON_EDITOR (self));
|
||||
g_assert (SYSPROF_IS_ENVIRON (self->environ));
|
||||
|
||||
gtk_list_box_bind_model (GTK_LIST_BOX (self),
|
||||
gtk_list_box_bind_model (self->list_box,
|
||||
G_LIST_MODEL (self->environ),
|
||||
sysprof_environ_editor_create_row, self, NULL);
|
||||
|
||||
self->dummy_row = sysprof_environ_editor_create_dummy_row (self);
|
||||
gtk_container_add (GTK_CONTAINER (self), self->dummy_row);
|
||||
gtk_list_box_append (self->list_box, self->dummy_row);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -168,17 +171,19 @@ find_row (SysprofEnvironEditor *self,
|
||||
g_assert (SYSPROF_IS_ENVIRON_EDITOR (self));
|
||||
g_assert (SYSPROF_IS_ENVIRON_VARIABLE (variable));
|
||||
|
||||
gtk_container_foreach (GTK_CONTAINER (self), find_row_cb, &lookup);
|
||||
for (GtkWidget *child = gtk_widget_get_first_child (GTK_WIDGET (self->list_box));
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
find_row_cb (child, &lookup);
|
||||
|
||||
return lookup.row;
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_environ_editor_row_activated (GtkListBox *list_box,
|
||||
GtkListBoxRow *row)
|
||||
sysprof_environ_editor_row_activated (SysprofEnvironEditor *self,
|
||||
GtkListBoxRow *row,
|
||||
GtkListBox *list_box)
|
||||
{
|
||||
SysprofEnvironEditor *self = (SysprofEnvironEditor *)list_box;
|
||||
|
||||
g_assert (GTK_IS_LIST_BOX (list_box));
|
||||
g_assert (GTK_IS_LIST_BOX_ROW (row));
|
||||
|
||||
@ -196,13 +201,19 @@ sysprof_environ_editor_row_activated (GtkListBox *list_box,
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_environ_editor_destroy (GtkWidget *widget)
|
||||
sysprof_environ_editor_dispose (GObject *object)
|
||||
{
|
||||
SysprofEnvironEditor *self = (SysprofEnvironEditor *)widget;
|
||||
SysprofEnvironEditor *self = (SysprofEnvironEditor *)object;
|
||||
|
||||
GTK_WIDGET_CLASS (sysprof_environ_editor_parent_class)->destroy (widget);
|
||||
if (self->list_box)
|
||||
{
|
||||
gtk_widget_unparent (GTK_WIDGET (self->list_box));
|
||||
self->list_box = NULL;
|
||||
}
|
||||
|
||||
g_clear_object (&self->environ);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_environ_editor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -248,16 +259,12 @@ sysprof_environ_editor_class_init (SysprofEnvironEditorClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GtkListBoxClass *list_box_class = GTK_LIST_BOX_CLASS (klass);
|
||||
SysprofThemeManager *theme_manager = sysprof_theme_manager_get_default ();
|
||||
|
||||
object_class->dispose = sysprof_environ_editor_dispose;
|
||||
object_class->get_property = sysprof_environ_editor_get_property;
|
||||
object_class->set_property = sysprof_environ_editor_set_property;
|
||||
|
||||
widget_class->destroy = sysprof_environ_editor_destroy;
|
||||
|
||||
list_box_class->row_activated = sysprof_environ_editor_row_activated;
|
||||
|
||||
properties [PROP_ENVIRON] =
|
||||
g_param_spec_object ("environ",
|
||||
"Environment",
|
||||
@ -267,16 +274,26 @@ sysprof_environ_editor_class_init (SysprofEnvironEditorClass *klass)
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
|
||||
sysprof_theme_manager_register_resource (theme_manager, NULL, NULL, "/org/gnome/sysprof/css/SysprofEnvironEditor-shared.css");
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_environ_editor_init (SysprofEnvironEditor *self)
|
||||
{
|
||||
gtk_list_box_set_selection_mode (GTK_LIST_BOX (self), GTK_SELECTION_NONE);
|
||||
self->list_box = GTK_LIST_BOX (gtk_list_box_new ());
|
||||
gtk_widget_set_parent (GTK_WIDGET (self->list_box), GTK_WIDGET (self));
|
||||
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (self)),
|
||||
"environ-editor");
|
||||
gtk_list_box_set_selection_mode (self->list_box, GTK_SELECTION_NONE);
|
||||
|
||||
gtk_widget_add_css_class (GTK_WIDGET (self), "environ-editor");
|
||||
|
||||
g_signal_connect_object (self->list_box,
|
||||
"row-activated",
|
||||
G_CALLBACK (sysprof_environ_editor_row_activated),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
|
||||
@ -28,11 +28,11 @@ G_BEGIN_DECLS
|
||||
|
||||
#define SYSPROF_TYPE_ENVIRON_EDITOR (sysprof_environ_editor_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (SysprofEnvironEditor, sysprof_environ_editor, SYSPROF, ENVIRON_EDITOR, GtkListBox)
|
||||
G_DECLARE_FINAL_TYPE (SysprofEnvironEditor, sysprof_environ_editor, SYSPROF, ENVIRON_EDITOR, GtkWidget)
|
||||
|
||||
GtkWidget *sysprof_environ_editor_new (void);
|
||||
SysprofEnviron *sysprof_environ_editor_get_environ (SysprofEnvironEditor *self);
|
||||
void sysprof_environ_editor_set_environ (SysprofEnvironEditor *self,
|
||||
SysprofEnviron *environ);
|
||||
SysprofEnviron *environ);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
|
||||
#include "sysprof-failed-state-view.h"
|
||||
|
||||
G_DEFINE_TYPE (SysprofFailedStateView, sysprof_failed_state_view, GTK_TYPE_BIN)
|
||||
G_DEFINE_TYPE (SysprofFailedStateView, sysprof_failed_state_view, GTK_TYPE_WIDGET)
|
||||
|
||||
GtkWidget *
|
||||
sysprof_failed_state_view_new (void)
|
||||
@ -30,11 +30,27 @@ sysprof_failed_state_view_new (void)
|
||||
return g_object_new (SYSPROF_TYPE_FAILED_STATE_VIEW, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_failed_state_view_dispose (GObject *object)
|
||||
{
|
||||
SysprofFailedStateView *self = (SysprofFailedStateView *)object;
|
||||
GtkWidget *child;
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self))))
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_failed_state_view_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_failed_state_view_class_init (SysprofFailedStateViewClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = sysprof_failed_state_view_dispose;
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
"/org/gnome/sysprof/ui/sysprof-failed-state-view.ui");
|
||||
}
|
||||
|
||||
@ -27,13 +27,11 @@ G_BEGIN_DECLS
|
||||
|
||||
#define SYSPROF_TYPE_FAILED_STATE_VIEW (sysprof_failed_state_view_get_type())
|
||||
|
||||
G_DECLARE_DERIVABLE_TYPE (SysprofFailedStateView, sysprof_failed_state_view, SYSPROF, FAILED_STATE_VIEW, GtkBin)
|
||||
G_DECLARE_DERIVABLE_TYPE (SysprofFailedStateView, sysprof_failed_state_view, SYSPROF, FAILED_STATE_VIEW, GtkWidget)
|
||||
|
||||
struct _SysprofFailedStateViewClass
|
||||
{
|
||||
GtkBinClass parent;
|
||||
|
||||
gpointer padding[4];
|
||||
GtkWidgetClass parent;
|
||||
};
|
||||
|
||||
GtkWidget *sysprof_failed_state_view_new (void);
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
<?xml version="1.0"?>
|
||||
<interface>
|
||||
<template class="SysprofFailedStateView" parent="GtkBin">
|
||||
<template class="SysprofFailedStateView" parent="GtkWidget">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="border-width">36</property>
|
||||
<property name="margin-top">36</property>
|
||||
<property name="margin-bottom">36</property>
|
||||
<property name="margin-start">36</property>
|
||||
<property name="margin-end">36</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">12</property>
|
||||
<property name="visible">true</property>
|
||||
@ -17,7 +20,23 @@
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<child type="end">
|
||||
<object class="GtkLabel">
|
||||
<property name="vexpand">true</property>
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Something unexpectedly went wrong while trying to profile your system.</property>
|
||||
<property name="use-markup">true</property>
|
||||
<property name="visible">true</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Ouch, that hurt!</property>
|
||||
<property name="visible">true</property>
|
||||
@ -29,34 +48,6 @@
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Something unexpectedly went wrong while trying to profile your system.</property>
|
||||
<property name="use-markup">true</property>
|
||||
<property name="visible">true</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="vexpand">true</property>
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
<property name="pack-type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@ -141,9 +141,9 @@ copy_array (GArray *ar)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sysprof_line_visualizer_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
static void
|
||||
sysprof_line_visualizer_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
static PangoAttrList *attrs = NULL;
|
||||
SysprofLineVisualizer *self = (SysprofLineVisualizer *)widget;
|
||||
@ -151,28 +151,35 @@ sysprof_line_visualizer_draw (GtkWidget *widget,
|
||||
g_autofree gchar *upper = NULL;
|
||||
GtkStyleContext *style_context;
|
||||
PangoLayout *layout;
|
||||
GtkStateFlags flags;
|
||||
cairo_t *cr;
|
||||
GtkAllocation alloc;
|
||||
GdkRectangle clip;
|
||||
GdkRGBA foreground;
|
||||
gboolean ret;
|
||||
|
||||
g_assert (SYSPROF_IS_LINE_VISUALIZER (widget));
|
||||
g_assert (cr != NULL);
|
||||
g_assert (snapshot != NULL);
|
||||
|
||||
gtk_widget_get_allocation (widget, &alloc);
|
||||
|
||||
ret = GTK_WIDGET_CLASS (sysprof_line_visualizer_parent_class)->draw (widget, cr);
|
||||
GTK_WIDGET_CLASS (sysprof_line_visualizer_parent_class)->snapshot (widget, snapshot);
|
||||
|
||||
if (priv->cache == NULL)
|
||||
return ret;
|
||||
return;
|
||||
|
||||
#if 0
|
||||
if (!gdk_cairo_get_clip_rectangle (cr, &clip))
|
||||
return ret;
|
||||
#else
|
||||
clip.x = 0;
|
||||
clip.y = 0;
|
||||
clip.width = alloc.width;
|
||||
clip.height = alloc.height;
|
||||
#endif
|
||||
|
||||
cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT (0, 0, alloc.width, alloc.height));
|
||||
|
||||
style_context = gtk_widget_get_style_context (widget);
|
||||
flags = gtk_widget_get_state_flags (widget);
|
||||
gtk_style_context_get_color (style_context, flags, &foreground);
|
||||
gtk_style_context_get_color (style_context, &foreground);
|
||||
|
||||
for (guint line = 0; line < priv->lines->len; line++)
|
||||
{
|
||||
@ -205,7 +212,7 @@ sysprof_line_visualizer_draw (GtkWidget *widget,
|
||||
}
|
||||
|
||||
if (p >= n_fpoints)
|
||||
return ret;
|
||||
goto cleanup;
|
||||
|
||||
if (p > 0)
|
||||
p--;
|
||||
@ -289,7 +296,8 @@ sysprof_line_visualizer_draw (GtkWidget *widget,
|
||||
g_clear_object (&layout);
|
||||
}
|
||||
|
||||
return ret;
|
||||
cleanup:
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -347,12 +355,10 @@ sysprof_line_visualizer_queue_reload (SysprofLineVisualizer *self)
|
||||
g_assert (SYSPROF_IS_LINE_VISUALIZER (self));
|
||||
|
||||
if (priv->queued_load == 0)
|
||||
{
|
||||
priv->queued_load = gdk_threads_add_idle_full (G_PRIORITY_LOW,
|
||||
sysprof_line_visualizer_do_reload,
|
||||
self,
|
||||
NULL);
|
||||
}
|
||||
priv->queued_load = g_idle_add_full (G_PRIORITY_LOW,
|
||||
sysprof_line_visualizer_do_reload,
|
||||
self,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -390,11 +396,7 @@ sysprof_line_visualizer_finalize (GObject *object)
|
||||
g_clear_pointer (&priv->cache, point_cache_unref);
|
||||
g_clear_pointer (&priv->reader, sysprof_capture_reader_unref);
|
||||
|
||||
if (priv->queued_load != 0)
|
||||
{
|
||||
g_source_remove (priv->queued_load);
|
||||
priv->queued_load = 0;
|
||||
}
|
||||
g_clear_handle_id (&priv->queued_load, g_source_remove);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_line_visualizer_parent_class)->finalize (object);
|
||||
}
|
||||
@ -472,7 +474,7 @@ sysprof_line_visualizer_class_init (SysprofLineVisualizerClass *klass)
|
||||
object_class->get_property = sysprof_line_visualizer_get_property;
|
||||
object_class->set_property = sysprof_line_visualizer_set_property;
|
||||
|
||||
widget_class->draw = sysprof_line_visualizer_draw;
|
||||
widget_class->snapshot = sysprof_line_visualizer_snapshot;
|
||||
|
||||
visualizer_class->set_reader = sysprof_line_visualizer_set_reader;
|
||||
|
||||
|
||||
@ -70,25 +70,27 @@ sysprof_mark_visualizer_new (GHashTable *groups)
|
||||
return SYSPROF_VISUALIZER (g_steal_pointer (&self));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sysprof_mark_visualizer_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
static void
|
||||
sysprof_mark_visualizer_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
SysprofMarkVisualizer *self = (SysprofMarkVisualizer *)widget;
|
||||
SysprofVisualizer *vis = (SysprofVisualizer *)widget;
|
||||
static const GdkRGBA black = {0,0,0,1};
|
||||
const GdkRGBA *rgba = &black;
|
||||
GHashTableIter iter;
|
||||
GtkAllocation alloc;
|
||||
gpointer k, v;
|
||||
gboolean ret;
|
||||
gint n_groups = 0;
|
||||
gint y = 0;
|
||||
int n_groups = 0;
|
||||
int y = 0;
|
||||
|
||||
g_assert (SYSPROF_IS_MARK_VISUALIZER (self));
|
||||
g_assert (cr != NULL);
|
||||
g_assert (snapshot != NULL);
|
||||
|
||||
GTK_WIDGET_CLASS (sysprof_mark_visualizer_parent_class)->snapshot (widget, snapshot);
|
||||
|
||||
ret = GTK_WIDGET_CLASS (sysprof_mark_visualizer_parent_class)->draw (widget, cr);
|
||||
if (self->spans_by_group == NULL)
|
||||
return ret;
|
||||
return;
|
||||
|
||||
gtk_widget_get_allocation (widget, &alloc);
|
||||
|
||||
@ -117,19 +119,14 @@ sysprof_mark_visualizer_draw (GtkWidget *widget,
|
||||
g_hash_table_iter_init (&iter, self->spans_by_group);
|
||||
while (g_hash_table_iter_next (&iter, &k, &v))
|
||||
{
|
||||
static const GdkRGBA black = {0, 0, 0, 1};
|
||||
SysprofMarkTimeSpan *span;
|
||||
const gchar *group = k;
|
||||
const GArray *spans = v;
|
||||
const GdkRGBA *rgba;
|
||||
const GdkRGBA *kindrgba;
|
||||
const GdkRGBA *grouprgba;
|
||||
|
||||
if ((grouprgba = g_hash_table_lookup (self->rgba_by_group, group)))
|
||||
{
|
||||
rgba = grouprgba;
|
||||
gdk_cairo_set_source_rgba (cr, rgba);
|
||||
}
|
||||
rgba = grouprgba;
|
||||
|
||||
for (guint i = 0; i < spans->len; i++)
|
||||
{
|
||||
@ -144,7 +141,6 @@ sysprof_mark_visualizer_draw (GtkWidget *widget,
|
||||
rgba = kindrgba;
|
||||
else if ((grouprgba = g_hash_table_lookup (self->rgba_by_group, group)))
|
||||
rgba = grouprgba;
|
||||
gdk_cairo_set_source_rgba (cr, rgba);
|
||||
}
|
||||
|
||||
x1 = span->x;
|
||||
@ -180,31 +176,24 @@ sysprof_mark_visualizer_draw (GtkWidget *widget,
|
||||
break;
|
||||
}
|
||||
|
||||
cairo_rectangle (cr, x1, y, x2 - x1, RECT_HEIGHT);
|
||||
|
||||
if (n_groups == 1)
|
||||
cairo_fill (cr);
|
||||
gtk_snapshot_append_color (snapshot, rgba, &GRAPHENE_RECT_INIT (x1, y, x2 - x1, RECT_HEIGHT));
|
||||
}
|
||||
|
||||
if (n_groups > 1)
|
||||
cairo_fill (cr);
|
||||
|
||||
y += RECT_HEIGHT + RECT_OVERLAP;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_mark_visualizer_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *alloc)
|
||||
sysprof_mark_visualizer_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
SysprofMarkVisualizer *self = (SysprofMarkVisualizer *)widget;
|
||||
|
||||
g_assert (SYSPROF_IS_MARK_VISUALIZER (self));
|
||||
g_assert (alloc != NULL);
|
||||
|
||||
GTK_WIDGET_CLASS (sysprof_mark_visualizer_parent_class)->size_allocate (widget, alloc);
|
||||
GTK_WIDGET_CLASS (sysprof_mark_visualizer_parent_class)->size_allocate (widget, width, height, baseline);
|
||||
|
||||
reset_positions (self);
|
||||
}
|
||||
@ -230,7 +219,7 @@ sysprof_mark_visualizer_class_init (SysprofMarkVisualizerClass *klass)
|
||||
|
||||
object_class->finalize = sysprof_mark_visualizer_finalize;
|
||||
|
||||
widget_class->draw = sysprof_mark_visualizer_draw;
|
||||
widget_class->snapshot = sysprof_mark_visualizer_snapshot;
|
||||
widget_class->size_allocate = sysprof_mark_visualizer_size_allocate;
|
||||
}
|
||||
|
||||
|
||||
@ -46,6 +46,177 @@ typedef struct
|
||||
|
||||
G_DEFINE_TYPE (SysprofMarksAid, sysprof_marks_aid, SYSPROF_TYPE_AID)
|
||||
|
||||
static void
|
||||
rgb_to_hls (gdouble *r,
|
||||
gdouble *g,
|
||||
gdouble *b)
|
||||
{
|
||||
gdouble min;
|
||||
gdouble max;
|
||||
gdouble red;
|
||||
gdouble green;
|
||||
gdouble blue;
|
||||
gdouble h, l, s;
|
||||
gdouble delta;
|
||||
|
||||
red = *r;
|
||||
green = *g;
|
||||
blue = *b;
|
||||
if (red > green)
|
||||
{
|
||||
if (red > blue)
|
||||
max = red;
|
||||
else
|
||||
max = blue;
|
||||
if (green < blue)
|
||||
min = green;
|
||||
else
|
||||
min = blue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (green > blue)
|
||||
max = green;
|
||||
else
|
||||
max = blue;
|
||||
if (red < blue)
|
||||
min = red;
|
||||
else
|
||||
min = blue;
|
||||
}
|
||||
l = (max + min) / 2;
|
||||
s = 0;
|
||||
h = 0;
|
||||
if (max != min)
|
||||
{
|
||||
if (l <= 0.5)
|
||||
s = (max - min) / (max + min);
|
||||
else
|
||||
s = (max - min) / (2 - max - min);
|
||||
delta = max - min;
|
||||
if (red == max)
|
||||
h = (green - blue) / delta;
|
||||
else if (green == max)
|
||||
h = 2 + (blue - red) / delta;
|
||||
else if (blue == max)
|
||||
h = 4 + (red - green) / delta;
|
||||
h *= 60;
|
||||
if (h < 0.0)
|
||||
h += 360;
|
||||
}
|
||||
*r = h;
|
||||
*g = l;
|
||||
*b = s;
|
||||
}
|
||||
|
||||
static void
|
||||
hls_to_rgb (gdouble *h,
|
||||
gdouble *l,
|
||||
gdouble *s)
|
||||
{
|
||||
gdouble hue;
|
||||
gdouble lightness;
|
||||
gdouble saturation;
|
||||
gdouble m1, m2;
|
||||
gdouble r, g, b;
|
||||
|
||||
lightness = *l;
|
||||
saturation = *s;
|
||||
if (lightness <= 0.5)
|
||||
m2 = lightness * (1 + saturation);
|
||||
else
|
||||
m2 = lightness + saturation - lightness * saturation;
|
||||
m1 = 2 * lightness - m2;
|
||||
if (saturation == 0)
|
||||
{
|
||||
*h = lightness;
|
||||
*l = lightness;
|
||||
*s = lightness;
|
||||
}
|
||||
else
|
||||
{
|
||||
hue = *h + 120;
|
||||
while (hue > 360)
|
||||
hue -= 360;
|
||||
while (hue < 0)
|
||||
hue += 360;
|
||||
if (hue < 60)
|
||||
r = m1 + (m2 - m1) * hue / 60;
|
||||
else if (hue < 180)
|
||||
r = m2;
|
||||
else if (hue < 240)
|
||||
r = m1 + (m2 - m1) * (240 - hue) / 60;
|
||||
else
|
||||
r = m1;
|
||||
hue = *h;
|
||||
while (hue > 360)
|
||||
hue -= 360;
|
||||
while (hue < 0)
|
||||
hue += 360;
|
||||
if (hue < 60)
|
||||
g = m1 + (m2 - m1) * hue / 60;
|
||||
else if (hue < 180)
|
||||
g = m2;
|
||||
else if (hue < 240)
|
||||
g = m1 + (m2 - m1) * (240 - hue) / 60;
|
||||
else
|
||||
g = m1;
|
||||
hue = *h - 120;
|
||||
while (hue > 360)
|
||||
hue -= 360;
|
||||
while (hue < 0)
|
||||
hue += 360;
|
||||
if (hue < 60)
|
||||
b = m1 + (m2 - m1) * hue / 60;
|
||||
else if (hue < 180)
|
||||
b = m2;
|
||||
else if (hue < 240)
|
||||
b = m1 + (m2 - m1) * (240 - hue) / 60;
|
||||
else
|
||||
b = m1;
|
||||
*h = r;
|
||||
*l = g;
|
||||
*s = b;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rgba_shade (const GdkRGBA *rgba,
|
||||
GdkRGBA *dst,
|
||||
gdouble k)
|
||||
{
|
||||
gdouble red;
|
||||
gdouble green;
|
||||
gdouble blue;
|
||||
|
||||
red = rgba->red;
|
||||
green = rgba->green;
|
||||
blue = rgba->blue;
|
||||
|
||||
rgb_to_hls (&red, &green, &blue);
|
||||
|
||||
green *= k;
|
||||
|
||||
if (green > 1.0)
|
||||
green = 1.0;
|
||||
else if (green < 0.0)
|
||||
green = 0.0;
|
||||
|
||||
blue *= k;
|
||||
|
||||
if (blue > 1.0)
|
||||
blue = 1.0;
|
||||
else if (blue < 0.0)
|
||||
blue = 0.0;
|
||||
|
||||
hls_to_rgb (&red, &green, &blue);
|
||||
|
||||
dst->red = red;
|
||||
dst->green = green;
|
||||
dst->blue = blue;
|
||||
dst->alpha = rgba->alpha;
|
||||
}
|
||||
|
||||
static void
|
||||
present_free (gpointer data)
|
||||
{
|
||||
@ -275,7 +446,7 @@ sysprof_marks_aid_present_finish (SysprofAid *aid,
|
||||
|
||||
if (!g_hash_table_contains (seen, GUINT_TO_POINTER (span->kind)))
|
||||
{
|
||||
dzl_rgba_shade (&rgba, &kind_rgba, 1 + (ratio * span->kind));
|
||||
rgba_shade (&rgba, &kind_rgba, 1 + (ratio * span->kind));
|
||||
g_hash_table_insert (seen,
|
||||
GUINT_TO_POINTER (span->kind),
|
||||
g_memdup2 (&kind_rgba, sizeof kind_rgba));
|
||||
|
||||
@ -50,6 +50,8 @@ typedef struct
|
||||
GtkLabel *end;
|
||||
GtkLabel *duration;
|
||||
GtkTextView *message;
|
||||
GtkWidget *failed;
|
||||
GtkWidget *marks;
|
||||
} SysprofMarksPagePrivate;
|
||||
|
||||
enum {
|
||||
@ -64,19 +66,21 @@ static GParamSpec *properties [N_PROPS];
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (SysprofMarksPage, sysprof_marks_page, SYSPROF_TYPE_PAGE)
|
||||
|
||||
static gboolean
|
||||
sysprof_marks_page_tree_view_key_press_event_cb (SysprofMarksPage *self,
|
||||
const GdkEventKey *key,
|
||||
GtkTreeView *tree_view)
|
||||
sysprof_marks_page_tree_view_key_press_event_cb (SysprofMarksPage *self,
|
||||
guint keyval,
|
||||
guint keycode,
|
||||
GdkModifierType state,
|
||||
GtkEventControllerKey *controller)
|
||||
{
|
||||
SysprofMarksPagePrivate *priv = sysprof_marks_page_get_instance_private (self);
|
||||
gint dir = 0;
|
||||
|
||||
g_assert (SYSPROF_MARKS_PAGE (self));
|
||||
g_assert (key != NULL);
|
||||
g_assert (GTK_IS_EVENT_CONTROLLER_KEY (controller));
|
||||
|
||||
if (key->state == 0)
|
||||
if ((state & (GDK_SHIFT_MASK|GDK_CONTROL_MASK|GDK_ALT_MASK)) == 0)
|
||||
{
|
||||
switch (key->keyval)
|
||||
switch (keyval)
|
||||
{
|
||||
case GDK_KEY_Left:
|
||||
dir = -1;
|
||||
@ -308,9 +312,9 @@ sysprof_marks_page_load_cb (GObject *object,
|
||||
gtk_tree_view_set_model (priv->tree_view, GTK_TREE_MODEL (model));
|
||||
|
||||
if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), NULL) == 0)
|
||||
gtk_stack_set_visible_child_name (priv->stack, "empty-state");
|
||||
gtk_stack_set_visible_child (priv->stack, GTK_WIDGET (priv->failed));
|
||||
else
|
||||
gtk_stack_set_visible_child_name (priv->stack, "marks");
|
||||
gtk_stack_set_visible_child (priv->stack, GTK_WIDGET (priv->marks));
|
||||
|
||||
g_task_return_boolean (task, TRUE);
|
||||
}
|
||||
@ -515,6 +519,8 @@ sysprof_marks_page_class_init (SysprofMarksPageClass *klass)
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMarksPage, duration);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMarksPage, time);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMarksPage, message);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMarksPage, marks);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMarksPage, failed);
|
||||
|
||||
properties [PROP_KIND] =
|
||||
g_param_spec_enum ("kind", NULL, NULL,
|
||||
@ -536,6 +542,7 @@ static void
|
||||
sysprof_marks_page_init (SysprofMarksPage *self)
|
||||
{
|
||||
SysprofMarksPagePrivate *priv = sysprof_marks_page_get_instance_private (self);
|
||||
GtkEventController *controller;
|
||||
|
||||
priv->kind = SYSPROF_MARKS_MODEL_MARKS;
|
||||
|
||||
@ -544,11 +551,14 @@ sysprof_marks_page_init (SysprofMarksPage *self)
|
||||
gtk_tree_selection_set_mode (gtk_tree_view_get_selection (priv->tree_view),
|
||||
GTK_SELECTION_MULTIPLE);
|
||||
|
||||
g_signal_connect_object (priv->tree_view,
|
||||
"key-press-event",
|
||||
controller = gtk_event_controller_key_new ();
|
||||
gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_CAPTURE);
|
||||
g_signal_connect_object (controller,
|
||||
"key-pressed",
|
||||
G_CALLBACK (sysprof_marks_page_tree_view_key_press_event_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
|
||||
g_signal_connect_object (priv->tree_view,
|
||||
"row-activated",
|
||||
|
||||
@ -3,22 +3,21 @@
|
||||
<template class="SysprofMarksPage" parent="SysprofPage">
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="homogeneous">false</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="hhomogeneous">false</property>
|
||||
<property name="vhomogeneous">false</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<object class="GtkBox" id="marks">
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="details_box">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin">6</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Details</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin-end">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
@ -30,164 +29,150 @@
|
||||
<property name="hexpand">false</property>
|
||||
<property name="vexpand">true</property>
|
||||
<property name="margin-start">6</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="margin-end">6</property>
|
||||
<property name="column-spacing">6</property>
|
||||
<property name="row-spacing">3</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Group</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="row">0</property>
|
||||
<property name="column">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top-attach">0</property>
|
||||
<property name="left-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Mark</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="yalign">0</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="row">1</property>
|
||||
<property name="column">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top-attach">1</property>
|
||||
<property name="left-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Time</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="row">2</property>
|
||||
<property name="column">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top-attach">2</property>
|
||||
<property name="left-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">End</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="row">3</property>
|
||||
<property name="column">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top-attach">3</property>
|
||||
<property name="left-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Duration</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="row">4</property>
|
||||
<property name="column">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top-attach">4</property>
|
||||
<property name="left-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Message</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="yalign">0</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="row">5</property>
|
||||
<property name="column">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top-attach">5</property>
|
||||
<property name="left-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="group">
|
||||
<property name="visible">true</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="wrap">true</property>
|
||||
<layout>
|
||||
<property name="row">0</property>
|
||||
<property name="column">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top-attach">0</property>
|
||||
<property name="left-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="mark">
|
||||
<property name="visible">true</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<property name="ellipsize">end</property>
|
||||
<layout>
|
||||
<property name="row">1</property>
|
||||
<property name="column">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top-attach">1</property>
|
||||
<property name="left-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="time">
|
||||
<property name="visible">true</property>
|
||||
<property name="xalign">0</property>
|
||||
<layout>
|
||||
<property name="row">2</property>
|
||||
<property name="column">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top-attach">2</property>
|
||||
<property name="left-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="end">
|
||||
<property name="visible">true</property>
|
||||
<property name="xalign">0</property>
|
||||
<layout>
|
||||
<property name="row">3</property>
|
||||
<property name="column">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top-attach">3</property>
|
||||
<property name="left-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="duration">
|
||||
<property name="visible">true</property>
|
||||
<property name="xalign">0</property>
|
||||
<layout>
|
||||
<property name="row">4</property>
|
||||
<property name="column">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top-attach">4</property>
|
||||
<property name="left-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hexpand">true</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="message">
|
||||
<property name="editable">false</property>
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="row">5</property>
|
||||
<property name="column">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top-attach">5</property>
|
||||
<property name="left-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
@ -196,20 +181,16 @@
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scroller">
|
||||
<property name="hscrollbar-policy">external</property>
|
||||
<property name="hexpand">true</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="tree_view">
|
||||
<property name="headers-visible">false</property>
|
||||
<property name="enable-grid-lines">horizontal</property>
|
||||
<property name="has-tooltip">true</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="duration_column">
|
||||
<property name="title" translatable="yes">Duration</property>
|
||||
@ -235,20 +216,42 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">marks</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="DzlEmptyState">
|
||||
<property name="icon-name">computer-fail-symbolic</property>
|
||||
<property name="title" translatable="yes">No Timings Available</property>
|
||||
<property name="subtitle" translatable="yes">No timing data was found for the current selection</property>
|
||||
<property name="visible">true</property>
|
||||
<object class="GtkBox" id="failed">
|
||||
<property name="halign">center</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">12</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="icon-name">computer-fail-symbolic</property>
|
||||
<property name="pixel-size">128</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="title">
|
||||
<property name="label" translatable="yes">No Timings Available</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<attributes>
|
||||
<attribute name="scale" value="2.0"/>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="subtitle">
|
||||
<property name="label" translatable="yes">No timing data was found for the current selection</property>
|
||||
<property name="use-markup">true</property>
|
||||
<property name="wrap">true</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">empty-state</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@ -39,11 +39,13 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <dazzle.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "../stackstash.h"
|
||||
|
||||
#include "egg-paned-private.h"
|
||||
#include "egg-three-grid.h"
|
||||
|
||||
#include "sysprof-cell-renderer-percent.h"
|
||||
#include "sysprof-memprof-page.h"
|
||||
#include "sysprof-profile.h"
|
||||
@ -59,15 +61,19 @@ typedef struct
|
||||
GtkTreeViewColumn *function_size_column;
|
||||
GtkCellRendererText *function_size_cell;
|
||||
GtkStack *stack;
|
||||
GtkRadioButton *summary;
|
||||
GtkRadioButton *all_allocs;
|
||||
GtkRadioButton *temp_allocs;
|
||||
GtkRadioButton *leaked_allocs_button;
|
||||
GtkToggleButton *summary;
|
||||
GtkToggleButton *all_allocs;
|
||||
GtkToggleButton *temp_allocs;
|
||||
GtkToggleButton *leaked_allocs_button;
|
||||
GtkLabel *temp_allocs_count;
|
||||
GtkLabel *num_allocs;
|
||||
GtkLabel *leaked_allocs;
|
||||
GtkLabel *peak_allocs;
|
||||
GtkListBox *by_size;
|
||||
GtkWidget *callgraph;
|
||||
GtkWidget *summary_page;
|
||||
GtkWidget *loading_state;
|
||||
GtkWidget *empty_state;
|
||||
|
||||
GCancellable *cancellable;
|
||||
|
||||
@ -174,6 +180,7 @@ update_summary (SysprofMemprofPage *self,
|
||||
SysprofMemprofPagePrivate *priv = sysprof_memprof_page_get_instance_private (self);
|
||||
SysprofMemprofStats stats;
|
||||
g_autoptr(GString) str = NULL;
|
||||
GtkWidget *child;
|
||||
|
||||
g_assert (SYSPROF_IS_MEMPROF_PAGE (self));
|
||||
g_assert (SYSPROF_IS_MEMPROF_PROFILE (profile));
|
||||
@ -194,9 +201,8 @@ update_summary (SysprofMemprofPage *self,
|
||||
gtk_label_set_label (priv->temp_allocs_count, str->str);
|
||||
g_string_truncate (str, 0);
|
||||
|
||||
gtk_container_foreach (GTK_CONTAINER (priv->by_size),
|
||||
(GtkCallback)gtk_widget_destroy,
|
||||
NULL);
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (priv->by_size))))
|
||||
gtk_list_box_remove (priv->by_size, child);
|
||||
|
||||
for (guint i = 0; i < G_N_ELEMENTS (stats.by_size); i++)
|
||||
{
|
||||
@ -237,7 +243,7 @@ update_summary (SysprofMemprofPage *self,
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (title), title_str);
|
||||
gtk_label_set_xalign (GTK_LABEL (title), 0);
|
||||
dzl_gtk_widget_add_style_class (title, "dim-label");
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (title)), "dim-label");
|
||||
|
||||
gtk_widget_set_margin_start (box, 6);
|
||||
gtk_widget_set_margin_end (box, 6);
|
||||
@ -267,13 +273,11 @@ update_summary (SysprofMemprofPage *self,
|
||||
gtk_level_bar_set_value (GTK_LEVEL_BAR (prog),
|
||||
stats.by_size[i].n_allocs);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (row), box);
|
||||
gtk_container_add (GTK_CONTAINER (box), title);
|
||||
gtk_container_add (GTK_CONTAINER (box), prog);
|
||||
gtk_container_add (GTK_CONTAINER (box), subtitle);
|
||||
gtk_container_add (GTK_CONTAINER (priv->by_size), row);
|
||||
|
||||
gtk_widget_show_all (row);
|
||||
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), box);
|
||||
gtk_box_append (GTK_BOX (box), title);
|
||||
gtk_box_append (GTK_BOX (box), prog);
|
||||
gtk_box_append (GTK_BOX (box), subtitle);
|
||||
gtk_list_box_append (priv->by_size, row);
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,7 +314,7 @@ sysprof_memprof_page_load (SysprofMemprofPage *self,
|
||||
|
||||
if (sysprof_memprof_profile_is_empty (profile))
|
||||
{
|
||||
gtk_stack_set_visible_child_name (priv->stack, "summary");
|
||||
gtk_stack_set_visible_child (priv->stack, priv->summary_page);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -345,7 +349,7 @@ sysprof_memprof_page_load (SysprofMemprofPage *self,
|
||||
gtk_tree_selection_select_iter (selection, &iter);
|
||||
}
|
||||
|
||||
gtk_stack_set_visible_child_name (priv->stack, "callgraph");
|
||||
gtk_stack_set_visible_child (priv->stack, priv->callgraph);
|
||||
|
||||
g_clear_object (&functions);
|
||||
}
|
||||
@ -357,7 +361,7 @@ _sysprof_memprof_page_set_failed (SysprofMemprofPage *self)
|
||||
|
||||
g_return_if_fail (SYSPROF_IS_MEMPROF_PAGE (self));
|
||||
|
||||
gtk_stack_set_visible_child_name (priv->stack, "empty-state");
|
||||
gtk_stack_set_visible_child (priv->stack, priv->empty_state);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -376,7 +380,7 @@ sysprof_memprof_page_unload (SysprofMemprofPage *self)
|
||||
gtk_tree_view_set_model (priv->functions_view, NULL);
|
||||
gtk_tree_view_set_model (priv->descendants_view, NULL);
|
||||
|
||||
gtk_stack_set_visible_child_name (priv->stack, "empty-state");
|
||||
gtk_stack_set_visible_child (priv->stack, priv->empty_state);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -887,7 +891,7 @@ static void
|
||||
copy_tree_view_selection (GtkTreeView *tree_view)
|
||||
{
|
||||
g_autoptr(GString) str = NULL;
|
||||
GtkClipboard *clipboard;
|
||||
GdkClipboard *clipboard;
|
||||
|
||||
g_assert (GTK_IS_TREE_VIEW (tree_view));
|
||||
|
||||
@ -896,24 +900,25 @@ copy_tree_view_selection (GtkTreeView *tree_view)
|
||||
copy_tree_view_selection_cb,
|
||||
str);
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (tree_view), GDK_SELECTION_CLIPBOARD);
|
||||
gtk_clipboard_set_text (clipboard, str->str, str->len);
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (tree_view));
|
||||
gdk_clipboard_set_text (clipboard, str->str);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_memprof_page_copy_cb (GtkWidget *widget,
|
||||
SysprofMemprofPage *self)
|
||||
sysprof_memprof_page_copy_cb (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *param)
|
||||
{
|
||||
SysprofMemprofPage *self = (SysprofMemprofPage *)widget;
|
||||
SysprofMemprofPagePrivate *priv = sysprof_memprof_page_get_instance_private (self);
|
||||
GtkWidget *toplevel;
|
||||
GtkWidget *focus;
|
||||
GtkRoot *toplevel;
|
||||
|
||||
g_assert (GTK_IS_WIDGET (widget));
|
||||
g_assert (SYSPROF_IS_MEMPROF_PAGE (self));
|
||||
|
||||
if (!(toplevel = gtk_widget_get_toplevel (widget)) ||
|
||||
!GTK_IS_WINDOW (toplevel) ||
|
||||
!(focus = gtk_window_get_focus (GTK_WINDOW (toplevel))))
|
||||
if (!(toplevel = gtk_widget_get_root (widget)) ||
|
||||
!GTK_IS_ROOT (toplevel) ||
|
||||
!(focus = gtk_root_get_focus (toplevel)))
|
||||
return;
|
||||
|
||||
if (focus == GTK_WIDGET (priv->descendants_view))
|
||||
@ -973,7 +978,7 @@ sysprof_memprof_page_load_async (SysprofPage *page,
|
||||
else
|
||||
g_set_object (&priv->cancellable, cancellable);
|
||||
|
||||
gtk_stack_set_visible_child_name (priv->stack, "loading");
|
||||
gtk_stack_set_visible_child (priv->stack, priv->loading_state);
|
||||
|
||||
task = g_task_new (self, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, sysprof_memprof_page_load_async);
|
||||
@ -1015,12 +1020,12 @@ do_allocs (SysprofMemprofPage *self,
|
||||
static void
|
||||
mode_notify_active (SysprofMemprofPage *self,
|
||||
GParamSpec *pspec,
|
||||
GtkRadioButton *button)
|
||||
GtkToggleButton *button)
|
||||
{
|
||||
SysprofMemprofPagePrivate *priv = sysprof_memprof_page_get_instance_private (self);
|
||||
|
||||
g_assert (SYSPROF_IS_MEMPROF_PAGE (self));
|
||||
g_assert (GTK_IS_RADIO_BUTTON (button));
|
||||
g_assert (GTK_IS_TOGGLE_BUTTON (button));
|
||||
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
|
||||
{
|
||||
@ -1106,7 +1111,6 @@ sysprof_memprof_page_class_init (SysprofMemprofPageClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
SysprofPageClass *page_class = SYSPROF_PAGE_CLASS (klass);
|
||||
GtkBindingSet *bindings;
|
||||
|
||||
object_class->finalize = sysprof_memprof_page_finalize;
|
||||
object_class->get_property = sysprof_memprof_page_get_property;
|
||||
@ -1152,10 +1156,18 @@ sysprof_memprof_page_class_init (SysprofMemprofPageClass *klass)
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMemprofPage, leaked_allocs);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMemprofPage, leaked_allocs_button);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMemprofPage, peak_allocs);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMemprofPage, loading_state);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMemprofPage, empty_state);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMemprofPage, summary_page);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMemprofPage, callgraph);
|
||||
|
||||
bindings = gtk_binding_set_by_class (klass);
|
||||
gtk_binding_entry_add_signal (bindings, GDK_KEY_Left, GDK_MOD1_MASK, "go-previous", 0);
|
||||
gtk_widget_class_install_action (widget_class, "page.copy", NULL, sysprof_memprof_page_copy_cb);
|
||||
|
||||
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_c, GDK_CONTROL_MASK, "page.copy", NULL);
|
||||
gtk_widget_class_add_binding_signal (widget_class, GDK_KEY_Left, GDK_ALT_MASK, "go-previous", NULL);
|
||||
|
||||
g_type_ensure (EGG_TYPE_PANED);
|
||||
g_type_ensure (EGG_TYPE_THREE_GRID);
|
||||
g_type_ensure (SYSPROF_TYPE_CELL_RENDERER_PERCENT);
|
||||
}
|
||||
|
||||
@ -1163,7 +1175,6 @@ static void
|
||||
sysprof_memprof_page_init (SysprofMemprofPage *self)
|
||||
{
|
||||
SysprofMemprofPagePrivate *priv = sysprof_memprof_page_get_instance_private (self);
|
||||
DzlShortcutController *controller;
|
||||
GtkTreeSelection *selection;
|
||||
GtkCellRenderer *cell;
|
||||
|
||||
@ -1172,7 +1183,7 @@ sysprof_memprof_page_init (SysprofMemprofPage *self)
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
gtk_stack_set_visible_child_name (priv->stack, "empty-state");
|
||||
gtk_stack_set_visible_child (priv->stack, priv->empty_state);
|
||||
|
||||
gtk_list_box_set_header_func (priv->by_size, sep_header_func, NULL, NULL);
|
||||
|
||||
@ -1246,16 +1257,6 @@ sysprof_memprof_page_init (SysprofMemprofPage *self)
|
||||
|
||||
gtk_tree_selection_set_mode (gtk_tree_view_get_selection (priv->descendants_view),
|
||||
GTK_SELECTION_MULTIPLE);
|
||||
|
||||
controller = dzl_shortcut_controller_find (GTK_WIDGET (self));
|
||||
|
||||
dzl_shortcut_controller_add_command_callback (controller,
|
||||
"org.gnome.sysprof3.capture.copy",
|
||||
"<Control>c",
|
||||
DZL_SHORTCUT_PHASE_BUBBLE,
|
||||
(GtkCallback) sysprof_memprof_page_copy_cb,
|
||||
self,
|
||||
NULL);
|
||||
}
|
||||
|
||||
typedef struct _Descendant Descendant;
|
||||
@ -1542,7 +1543,7 @@ _sysprof_memprof_page_set_loading (SysprofMemprofPage *self,
|
||||
priv->loading--;
|
||||
|
||||
if (priv->loading)
|
||||
gtk_stack_set_visible_child_name (priv->stack, "loading");
|
||||
gtk_stack_set_visible_child (priv->stack, priv->loading_state);
|
||||
else
|
||||
gtk_stack_set_visible_child_name (priv->stack, "callgraph");
|
||||
gtk_stack_set_visible_child (priv->stack, priv->callgraph);
|
||||
}
|
||||
|
||||
@ -1,45 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="SysprofMemprofPage" parent="SysprofPage">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<object class="GtkCenterBox">
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="visible">true</property>
|
||||
<child type="center">
|
||||
<object class="GtkBox">
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="homogeneous">true</property>
|
||||
<property name="visible">true</property>
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="summary">
|
||||
<object class="GtkToggleButton" id="summary">
|
||||
<property name="label" translatable="yes">Summary</property>
|
||||
<property name="draw-indicator">false</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="active">false</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="all_allocs">
|
||||
<object class="GtkToggleButton" id="all_allocs">
|
||||
<property name="label" translatable="yes">All Allocations</property>
|
||||
<property name="draw-indicator">false</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="group">summary</property>
|
||||
<property name="active">true</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="temp_allocs">
|
||||
<object class="GtkToggleButton" id="temp_allocs">
|
||||
<property name="label" translatable="yes">Temporary Allocations</property>
|
||||
<property name="draw-indicator">false</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="active">false</property>
|
||||
<property name="group">summary</property>
|
||||
</object>
|
||||
@ -48,7 +40,6 @@
|
||||
<object class="GtkRadioButton" id="leaked_allocs_button">
|
||||
<property name="label" translatable="yes">Leaked Allocations</property>
|
||||
<property name="draw-indicator">false</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="active">false</property>
|
||||
<property name="group">summary</property>
|
||||
</object>
|
||||
@ -60,27 +51,25 @@
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<object class="GtkScrolledWindow" id="summary_page">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="margin">16</property>
|
||||
<property name="margin-top">16</property>
|
||||
<property name="margin-bottom">16</property>
|
||||
<property name="margin-start">16</property>
|
||||
<property name="margin-end">16</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="DzlThreeGrid">
|
||||
<property name="expand">true</property>
|
||||
<object class="EggThreeGrid">
|
||||
<property name="hexpand">true</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">18</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Peak Allocation</property>
|
||||
@ -89,47 +78,45 @@
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">left</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="peak_allocs">
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">true</property>
|
||||
<property name="visible">false</property>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Number of Allocations</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="visible">true</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">left</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="num_allocs">
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">true</property>
|
||||
<property name="visible">true</property>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
@ -139,104 +126,92 @@
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">left</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="leaked_allocs">
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">true</property>
|
||||
<property name="visible">false</property>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Temporary Allocations</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="visible">true</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">left</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="temp_allocs_count">
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">true</property>
|
||||
<property name="width-chars">50</property>
|
||||
<property name="visible">true</property>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Allocations by Size</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="visible">true</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">left</property>
|
||||
<property name="row">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkListBox" id="by_size">
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">summary</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPaned">
|
||||
<object class="EggPaned" id="callgraph">
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="position">450</property>
|
||||
<property name="expand">true</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="vexpand">true</property>
|
||||
<child>
|
||||
<object class="GtkPaned">
|
||||
<object class="EggPaned">
|
||||
<property name="width-request">400</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="functions_view">
|
||||
<property name="fixed-height-mode">true</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="function_name_column">
|
||||
<property name="expand">true</property>
|
||||
@ -289,16 +264,11 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">true</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="callers_view">
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="callers_name_column">
|
||||
<property name="expand">true</property>
|
||||
@ -351,18 +321,13 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">true</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="descendants_view">
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="descendants_name_column">
|
||||
<property name="expand">true</property>
|
||||
@ -421,31 +386,20 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">callgraph</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="DzlEmptyState">
|
||||
<object class="AdwStatusPage" id="loading_state">
|
||||
<property name="icon-name">content-loading-symbolic</property>
|
||||
<property name="title" translatable="yes">Analyzing Memory Allocations</property>
|
||||
<property name="subtitle" translatable="yes">Sysprof is busy analyzing memory allocations.</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="description" translatable="yes">Sysprof is busy analyzing memory allocations.</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">loading</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="DzlEmptyState">
|
||||
<object class="AdwStatusPage" id="empty_state">
|
||||
<property name="icon-name">computer-fail-symbolic</property>
|
||||
<property name="title" translatable="yes">Not Enough Samples</property>
|
||||
<property name="subtitle" translatable="yes">More samples are necessary to display a callgraph.</property>
|
||||
<property name="visible">false</property>
|
||||
<property name="description" translatable="yes">More samples are necessary to display a callgraph.</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">empty-state</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@ -528,49 +528,46 @@ sysprof_memprof_visualizer_queue_redraw (SysprofMemprofVisualizer *self)
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_memprof_visualizer_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *alloc)
|
||||
sysprof_memprof_visualizer_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
SysprofMemprofVisualizer *self = (SysprofMemprofVisualizer *)widget;
|
||||
|
||||
g_assert (GTK_IS_WIDGET (widget));
|
||||
g_assert (alloc != NULL);
|
||||
|
||||
GTK_WIDGET_CLASS (sysprof_memprof_visualizer_parent_class)->size_allocate (widget, alloc);
|
||||
|
||||
sysprof_memprof_visualizer_queue_redraw (self);
|
||||
sysprof_memprof_visualizer_queue_redraw (SYSPROF_MEMPROF_VISUALIZER (widget));
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_memprof_visualizer_destroy (GtkWidget *widget)
|
||||
sysprof_memprof_visualizer_dispose (GObject *object)
|
||||
{
|
||||
SysprofMemprofVisualizer *self = (SysprofMemprofVisualizer *)widget;
|
||||
SysprofMemprofVisualizer *self = (SysprofMemprofVisualizer *)object;
|
||||
|
||||
g_clear_pointer (&self->reader, sysprof_capture_reader_unref);
|
||||
g_clear_pointer (&self->surface, cairo_surface_destroy);
|
||||
g_clear_handle_id (&self->queued_draw, g_source_remove);
|
||||
|
||||
GTK_WIDGET_CLASS (sysprof_memprof_visualizer_parent_class)->destroy (widget);
|
||||
G_OBJECT_CLASS (sysprof_memprof_visualizer_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sysprof_memprof_visualizer_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
static void
|
||||
sysprof_memprof_visualizer_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
SysprofMemprofVisualizer *self = (SysprofMemprofVisualizer *)widget;
|
||||
gboolean ret;
|
||||
|
||||
g_assert (SYSPROF_IS_MEMPROF_VISUALIZER (self));
|
||||
g_assert (cr != NULL);
|
||||
g_assert (GTK_IS_SNAPSHOT (snapshot));
|
||||
|
||||
ret = GTK_WIDGET_CLASS (sysprof_memprof_visualizer_parent_class)->draw (widget, cr);
|
||||
GTK_WIDGET_CLASS (sysprof_memprof_visualizer_parent_class)->snapshot (widget, snapshot);
|
||||
|
||||
if (self->surface != NULL)
|
||||
{
|
||||
cairo_t *cr;
|
||||
GtkAllocation alloc;
|
||||
|
||||
gtk_widget_get_allocation (widget, &alloc);
|
||||
|
||||
cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT (0, 0, alloc.width, alloc.height));
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_rectangle (cr, 0, 0, alloc.width, alloc.height);
|
||||
|
||||
@ -590,19 +587,21 @@ sysprof_memprof_visualizer_draw (GtkWidget *widget,
|
||||
cairo_set_source_surface (cr, self->surface, 0, 0);
|
||||
cairo_paint (cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_memprof_visualizer_class_init (SysprofMemprofVisualizerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
SysprofVisualizerClass *visualizer_class = SYSPROF_VISUALIZER_CLASS (klass);
|
||||
|
||||
widget_class->destroy = sysprof_memprof_visualizer_destroy;
|
||||
widget_class->draw = sysprof_memprof_visualizer_draw;
|
||||
object_class->dispose = sysprof_memprof_visualizer_dispose;
|
||||
|
||||
widget_class->snapshot = sysprof_memprof_visualizer_snapshot;
|
||||
widget_class->size_allocate = sysprof_memprof_visualizer_size_allocate;
|
||||
|
||||
visualizer_class->set_reader = sysprof_memprof_visualizer_set_reader;
|
||||
|
||||
@ -242,7 +242,7 @@ sysprof_netdev_aid_present_finish (SysprofAid *aid,
|
||||
if (counters->len > 0)
|
||||
sysprof_display_add_group (present->display, group);
|
||||
else
|
||||
gtk_widget_destroy (GTK_WIDGET (group));
|
||||
g_object_unref (g_object_ref_sink (group));
|
||||
}
|
||||
|
||||
return counters != NULL;
|
||||
|
||||
@ -29,10 +29,15 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkNotebook *notebook;
|
||||
guint always_show_tabs : 1;
|
||||
} SysprofNotebookPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (SysprofNotebook, sysprof_notebook, GTK_TYPE_NOTEBOOK)
|
||||
static void buildable_iface_init (GtkBuildableIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (SysprofNotebook, sysprof_notebook, GTK_TYPE_WIDGET,
|
||||
G_ADD_PRIVATE (SysprofNotebook)
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, buildable_iface_init))
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@ -83,15 +88,16 @@ sysprof_notebook_notify_can_replay_cb (SysprofNotebook *self,
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_notebook_page_added (GtkNotebook *notebook,
|
||||
GtkWidget *child,
|
||||
guint page_num)
|
||||
sysprof_notebook_page_added (SysprofNotebook *self,
|
||||
GtkWidget *child,
|
||||
guint page_num,
|
||||
GtkNotebook *notebook)
|
||||
{
|
||||
SysprofNotebook *self = (SysprofNotebook *)notebook;
|
||||
SysprofNotebookPrivate *priv = sysprof_notebook_get_instance_private (self);
|
||||
|
||||
g_assert (SYSPROF_IS_NOTEBOOK (self));
|
||||
g_assert (GTK_IS_WIDGET (child));
|
||||
g_assert (GTK_IS_NOTEBOOK (notebook));
|
||||
|
||||
gtk_notebook_set_show_tabs (notebook,
|
||||
(priv->always_show_tabs ||
|
||||
@ -107,13 +113,13 @@ sysprof_notebook_page_added (GtkNotebook *notebook,
|
||||
g_signal_connect_object (child,
|
||||
"notify::can-replay",
|
||||
G_CALLBACK (sysprof_notebook_notify_can_replay_cb),
|
||||
notebook,
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
g_signal_connect_object (child,
|
||||
"notify::can-save",
|
||||
G_CALLBACK (sysprof_notebook_notify_can_save_cb),
|
||||
notebook,
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CAN_REPLAY]);
|
||||
@ -125,15 +131,16 @@ sysprof_notebook_page_added (GtkNotebook *notebook,
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_notebook_page_removed (GtkNotebook *notebook,
|
||||
GtkWidget *child,
|
||||
guint page_num)
|
||||
sysprof_notebook_page_removed (SysprofNotebook *self,
|
||||
GtkWidget *child,
|
||||
guint page_num,
|
||||
GtkNotebook *notebook)
|
||||
{
|
||||
SysprofNotebook *self = (SysprofNotebook *)notebook;
|
||||
SysprofNotebookPrivate *priv = sysprof_notebook_get_instance_private (self);
|
||||
|
||||
g_assert (SYSPROF_IS_NOTEBOOK (self));
|
||||
g_assert (GTK_IS_WIDGET (child));
|
||||
g_assert (GTK_IS_NOTEBOOK (notebook));
|
||||
|
||||
if (gtk_widget_in_destruction (GTK_WIDGET (notebook)))
|
||||
return;
|
||||
@ -141,16 +148,16 @@ sysprof_notebook_page_removed (GtkNotebook *notebook,
|
||||
if (gtk_notebook_get_n_pages (notebook) == 0)
|
||||
{
|
||||
child = sysprof_display_new ();
|
||||
gtk_container_add (GTK_CONTAINER (notebook), child);
|
||||
gtk_notebook_append_page (notebook, child, NULL);
|
||||
gtk_widget_show (child);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (child,
|
||||
G_CALLBACK (sysprof_notebook_notify_can_save_cb),
|
||||
notebook);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CAN_REPLAY]);
|
||||
g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CAN_SAVE]);
|
||||
g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CURRENT]);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CAN_REPLAY]);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CAN_SAVE]);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CURRENT]);
|
||||
}
|
||||
|
||||
gtk_notebook_set_show_tabs (notebook,
|
||||
@ -159,18 +166,33 @@ sysprof_notebook_page_removed (GtkNotebook *notebook,
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_notebook_switch_page (GtkNotebook *notebook,
|
||||
GtkWidget *widget,
|
||||
guint page)
|
||||
sysprof_notebook_switch_page (SysprofNotebook *self,
|
||||
GtkWidget *widget,
|
||||
guint page,
|
||||
GtkNotebook *notebook)
|
||||
{
|
||||
g_assert (SYSPROF_IS_NOTEBOOK (self));
|
||||
g_assert (GTK_IS_NOTEBOOK (notebook));
|
||||
g_assert (GTK_IS_WIDGET (widget));
|
||||
|
||||
GTK_NOTEBOOK_CLASS (sysprof_notebook_parent_class)->switch_page (notebook, widget, page);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CAN_REPLAY]);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CAN_SAVE]);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CURRENT]);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CAN_REPLAY]);
|
||||
g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CAN_SAVE]);
|
||||
g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CURRENT]);
|
||||
static void
|
||||
sysprof_notebook_dispose (GObject *object)
|
||||
{
|
||||
SysprofNotebook *self = (SysprofNotebook *)object;
|
||||
SysprofNotebookPrivate *priv = sysprof_notebook_get_instance_private (self);
|
||||
|
||||
if (priv->notebook)
|
||||
{
|
||||
gtk_widget_unparent (GTK_WIDGET (priv->notebook));
|
||||
priv->notebook = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (sysprof_notebook_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -227,15 +249,12 @@ static void
|
||||
sysprof_notebook_class_init (SysprofNotebookClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkNotebookClass *notebook_class = GTK_NOTEBOOK_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = sysprof_notebook_dispose;
|
||||
object_class->get_property = sysprof_notebook_get_property;
|
||||
object_class->set_property = sysprof_notebook_set_property;
|
||||
|
||||
notebook_class->page_added = sysprof_notebook_page_added;
|
||||
notebook_class->page_removed = sysprof_notebook_page_removed;
|
||||
notebook_class->switch_page = sysprof_notebook_switch_page;
|
||||
|
||||
properties [PROP_ALWAYS_SHOW_TABS] =
|
||||
g_param_spec_boolean ("always-show-tabs",
|
||||
"Always Show Tabs",
|
||||
@ -265,71 +284,86 @@ sysprof_notebook_class_init (SysprofNotebookClass *klass)
|
||||
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_notebook_init (SysprofNotebook *self)
|
||||
{
|
||||
gtk_notebook_set_show_border (GTK_NOTEBOOK (self), FALSE);
|
||||
gtk_notebook_set_scrollable (GTK_NOTEBOOK (self), TRUE);
|
||||
gtk_notebook_popup_enable (GTK_NOTEBOOK (self));
|
||||
SysprofNotebookPrivate *priv = sysprof_notebook_get_instance_private (self);
|
||||
|
||||
priv->notebook = GTK_NOTEBOOK (gtk_notebook_new ());
|
||||
gtk_widget_set_parent (GTK_WIDGET (priv->notebook), GTK_WIDGET (self));
|
||||
|
||||
gtk_notebook_set_show_border (priv->notebook, FALSE);
|
||||
gtk_notebook_set_scrollable (priv->notebook, TRUE);
|
||||
gtk_notebook_popup_enable (priv->notebook);
|
||||
|
||||
g_signal_connect_object (priv->notebook,
|
||||
"page-added",
|
||||
G_CALLBACK (sysprof_notebook_page_added),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
g_signal_connect_object (priv->notebook,
|
||||
"page-removed",
|
||||
G_CALLBACK (sysprof_notebook_page_removed),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
g_signal_connect_object (priv->notebook,
|
||||
"switch-page",
|
||||
G_CALLBACK (sysprof_notebook_switch_page),
|
||||
self,
|
||||
G_CONNECT_SWAPPED | G_CONNECT_AFTER);
|
||||
}
|
||||
|
||||
void
|
||||
sysprof_notebook_close_current (SysprofNotebook *self)
|
||||
{
|
||||
SysprofNotebookPrivate *priv = sysprof_notebook_get_instance_private (self);
|
||||
gint page;
|
||||
|
||||
g_return_if_fail (SYSPROF_IS_NOTEBOOK (self));
|
||||
|
||||
if ((page = gtk_notebook_get_current_page (GTK_NOTEBOOK (self))) >= 0)
|
||||
gtk_widget_destroy (gtk_notebook_get_nth_page (GTK_NOTEBOOK (self), page));
|
||||
}
|
||||
|
||||
static void
|
||||
find_empty_display_cb (GtkWidget *widget,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget **display = user_data;
|
||||
|
||||
g_assert (GTK_IS_WIDGET (widget));
|
||||
g_assert (display != NULL);
|
||||
|
||||
if (*display != NULL)
|
||||
return;
|
||||
|
||||
if (SYSPROF_IS_DISPLAY (widget) &&
|
||||
sysprof_display_is_empty (SYSPROF_DISPLAY (widget)))
|
||||
*display = widget;
|
||||
if ((page = gtk_notebook_get_current_page (priv->notebook)) >= 0)
|
||||
gtk_notebook_remove_page (priv->notebook, page);
|
||||
}
|
||||
|
||||
void
|
||||
sysprof_notebook_open (SysprofNotebook *self,
|
||||
GFile *file)
|
||||
{
|
||||
GtkWidget *display = NULL;
|
||||
gint page;
|
||||
SysprofNotebookPrivate *priv = sysprof_notebook_get_instance_private (self);
|
||||
SysprofDisplay *display = NULL;
|
||||
int page;
|
||||
|
||||
g_return_if_fail (SYSPROF_IS_NOTEBOOK (self));
|
||||
g_return_if_fail (g_file_is_native (file));
|
||||
|
||||
gtk_container_foreach (GTK_CONTAINER (self),
|
||||
find_empty_display_cb,
|
||||
&display);
|
||||
for (page = 0; page < sysprof_notebook_get_n_pages (self); page++)
|
||||
{
|
||||
SysprofDisplay *child = sysprof_notebook_get_nth_page (self, page);
|
||||
|
||||
if (sysprof_display_is_empty (child))
|
||||
{
|
||||
display = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (display == NULL)
|
||||
{
|
||||
|
||||
display = sysprof_display_new ();
|
||||
page = gtk_notebook_insert_page (GTK_NOTEBOOK (self), display, NULL, -1);
|
||||
gtk_widget_show (display);
|
||||
display = SYSPROF_DISPLAY (sysprof_display_new ());
|
||||
page = sysprof_notebook_append (self, display);
|
||||
}
|
||||
else
|
||||
{
|
||||
page = gtk_notebook_page_num (GTK_NOTEBOOK (self), display);
|
||||
page = gtk_notebook_page_num (priv->notebook, GTK_WIDGET (display));
|
||||
}
|
||||
|
||||
gtk_notebook_set_current_page (GTK_NOTEBOOK (self), page);
|
||||
sysprof_notebook_set_current_page (self, page);
|
||||
|
||||
sysprof_display_open (SYSPROF_DISPLAY (display), file);
|
||||
}
|
||||
@ -337,12 +371,13 @@ sysprof_notebook_open (SysprofNotebook *self,
|
||||
SysprofDisplay *
|
||||
sysprof_notebook_get_current (SysprofNotebook *self)
|
||||
{
|
||||
SysprofNotebookPrivate *priv = sysprof_notebook_get_instance_private (self);
|
||||
gint page;
|
||||
|
||||
g_assert (SYSPROF_IS_NOTEBOOK (self));
|
||||
|
||||
if ((page = gtk_notebook_get_current_page (GTK_NOTEBOOK (self))) >= 0)
|
||||
return SYSPROF_DISPLAY (gtk_notebook_get_nth_page (GTK_NOTEBOOK (self), page));
|
||||
if ((page = gtk_notebook_get_current_page (priv->notebook)) >= 0)
|
||||
return SYSPROF_DISPLAY (gtk_notebook_get_nth_page (priv->notebook, page));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -387,6 +422,7 @@ sysprof_notebook_get_can_replay (SysprofNotebook *self)
|
||||
void
|
||||
sysprof_notebook_replay (SysprofNotebook *self)
|
||||
{
|
||||
SysprofNotebookPrivate *priv = sysprof_notebook_get_instance_private (self);
|
||||
SysprofDisplay *display;
|
||||
SysprofDisplay *replay;
|
||||
gint page;
|
||||
@ -401,15 +437,16 @@ sysprof_notebook_replay (SysprofNotebook *self)
|
||||
g_return_if_fail (SYSPROF_IS_DISPLAY (replay));
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (replay));
|
||||
gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (replay));
|
||||
page = gtk_notebook_page_num (GTK_NOTEBOOK (self), GTK_WIDGET (replay));
|
||||
gtk_notebook_set_current_page (GTK_NOTEBOOK (self), page);
|
||||
gtk_notebook_append_page (priv->notebook, GTK_WIDGET (replay), NULL);
|
||||
page = gtk_notebook_page_num (priv->notebook, GTK_WIDGET (replay));
|
||||
gtk_notebook_set_current_page (priv->notebook, page);
|
||||
}
|
||||
|
||||
void
|
||||
sysprof_notebook_add_profiler (SysprofNotebook *self,
|
||||
SysprofProfiler *profiler)
|
||||
{
|
||||
SysprofNotebookPrivate *priv = sysprof_notebook_get_instance_private (self);
|
||||
GtkWidget *display;
|
||||
gint page;
|
||||
|
||||
@ -419,9 +456,9 @@ sysprof_notebook_add_profiler (SysprofNotebook *self,
|
||||
display = sysprof_display_new_for_profiler (profiler);
|
||||
|
||||
gtk_widget_show (display);
|
||||
gtk_container_add (GTK_CONTAINER (self), display);
|
||||
page = gtk_notebook_page_num (GTK_NOTEBOOK (self), display);
|
||||
gtk_notebook_set_current_page (GTK_NOTEBOOK (self), page);
|
||||
gtk_notebook_append_page (priv->notebook, GTK_WIDGET (display), NULL);
|
||||
page = gtk_notebook_page_num (priv->notebook, display);
|
||||
gtk_notebook_set_current_page (priv->notebook, page);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@ -447,9 +484,78 @@ sysprof_notebook_set_always_show_tabs (SysprofNotebook *self,
|
||||
if (always_show_tabs != priv->always_show_tabs)
|
||||
{
|
||||
priv->always_show_tabs = always_show_tabs;
|
||||
gtk_notebook_set_show_tabs (GTK_NOTEBOOK (self),
|
||||
gtk_notebook_set_show_tabs (priv->notebook,
|
||||
(priv->always_show_tabs ||
|
||||
gtk_notebook_get_n_pages (GTK_NOTEBOOK (self)) > 1));
|
||||
gtk_notebook_get_n_pages (priv->notebook) > 1));
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ALWAYS_SHOW_TABS]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_notebook_add_child (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const char *type)
|
||||
{
|
||||
SysprofNotebook *self = (SysprofNotebook *)buildable;
|
||||
SysprofNotebookPrivate *priv = sysprof_notebook_get_instance_private (self);
|
||||
|
||||
g_assert (SYSPROF_IS_NOTEBOOK (self));
|
||||
|
||||
if (SYSPROF_IS_DISPLAY (child))
|
||||
gtk_notebook_append_page (priv->notebook, GTK_WIDGET (child), NULL);
|
||||
else
|
||||
g_warning ("Cannot add child of type %s to %s",
|
||||
G_OBJECT_TYPE_NAME (child),
|
||||
G_OBJECT_TYPE_NAME (self));
|
||||
}
|
||||
|
||||
static void
|
||||
buildable_iface_init (GtkBuildableIface *iface)
|
||||
{
|
||||
iface->add_child = sysprof_notebook_add_child;
|
||||
}
|
||||
|
||||
guint
|
||||
sysprof_notebook_get_n_pages (SysprofNotebook *self)
|
||||
{
|
||||
SysprofNotebookPrivate *priv = sysprof_notebook_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (SYSPROF_IS_NOTEBOOK (self), 0);
|
||||
|
||||
return gtk_notebook_get_n_pages (priv->notebook);
|
||||
}
|
||||
|
||||
SysprofDisplay *
|
||||
sysprof_notebook_get_nth_page (SysprofNotebook *self,
|
||||
guint nth)
|
||||
{
|
||||
SysprofNotebookPrivate *priv = sysprof_notebook_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (SYSPROF_IS_NOTEBOOK (self), NULL);
|
||||
|
||||
return SYSPROF_DISPLAY (gtk_notebook_get_nth_page (priv->notebook, nth));
|
||||
}
|
||||
|
||||
void
|
||||
sysprof_notebook_set_current_page (SysprofNotebook *self,
|
||||
int nth)
|
||||
{
|
||||
SysprofNotebookPrivate *priv = sysprof_notebook_get_instance_private (self);
|
||||
|
||||
g_return_if_fail (SYSPROF_IS_NOTEBOOK (self));
|
||||
|
||||
gtk_notebook_set_current_page (priv->notebook, nth);
|
||||
}
|
||||
|
||||
int
|
||||
sysprof_notebook_append (SysprofNotebook *self,
|
||||
SysprofDisplay *display)
|
||||
{
|
||||
SysprofNotebookPrivate *priv = sysprof_notebook_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (SYSPROF_IS_NOTEBOOK (self), -1);
|
||||
g_return_val_if_fail (SYSPROF_IS_DISPLAY (display), -1);
|
||||
|
||||
return gtk_notebook_append_page (priv->notebook, GTK_WIDGET (display), NULL);
|
||||
}
|
||||
|
||||
@ -35,11 +35,11 @@ G_BEGIN_DECLS
|
||||
#define SYSPROF_TYPE_NOTEBOOK (sysprof_notebook_get_type())
|
||||
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
G_DECLARE_DERIVABLE_TYPE (SysprofNotebook, sysprof_notebook, SYSPROF, NOTEBOOK, GtkNotebook)
|
||||
G_DECLARE_DERIVABLE_TYPE (SysprofNotebook, sysprof_notebook, SYSPROF, NOTEBOOK, GtkWidget)
|
||||
|
||||
struct _SysprofNotebookClass
|
||||
{
|
||||
GtkNotebookClass parent_class;
|
||||
GtkWidgetClass parent_class;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _reserved[16];
|
||||
@ -70,5 +70,16 @@ gboolean sysprof_notebook_get_always_show_tabs (SysprofNotebook *self);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
void sysprof_notebook_set_always_show_tabs (SysprofNotebook *self,
|
||||
gboolean always_show_tabs);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
guint sysprof_notebook_get_n_pages (SysprofNotebook *self);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
SysprofDisplay *sysprof_notebook_get_nth_page (SysprofNotebook *self,
|
||||
guint nth);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
void sysprof_notebook_set_current_page (SysprofNotebook *self,
|
||||
int page);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
int sysprof_notebook_append (SysprofNotebook *self,
|
||||
SysprofDisplay *display);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@ -31,7 +31,7 @@ typedef struct
|
||||
gchar *title;
|
||||
} SysprofPagePrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (SysprofPage, sysprof_page, GTK_TYPE_BIN)
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (SysprofPage, sysprof_page, GTK_TYPE_WIDGET)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@ -105,14 +105,18 @@ sysprof_page_real_load_finish (SysprofPage *self,
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_page_finalize (GObject *object)
|
||||
sysprof_page_dispose (GObject *object)
|
||||
{
|
||||
SysprofPage *self = (SysprofPage *)object;
|
||||
SysprofPagePrivate *priv = sysprof_page_get_instance_private (self);
|
||||
GtkWidget *child;
|
||||
|
||||
g_clear_pointer (&priv->title, g_free);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_page_parent_class)->finalize (object);
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self))))
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_page_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -157,8 +161,9 @@ static void
|
||||
sysprof_page_class_init (SysprofPageClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->finalize = sysprof_page_finalize;
|
||||
object_class->dispose = sysprof_page_dispose;
|
||||
object_class->get_property = sysprof_page_get_property;
|
||||
object_class->set_property = sysprof_page_set_property;
|
||||
|
||||
@ -173,11 +178,14 @@ sysprof_page_class_init (SysprofPageClass *klass)
|
||||
(G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_page_init (SysprofPage *self)
|
||||
{
|
||||
gtk_widget_set_vexpand (GTK_WIDGET (self), TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -32,11 +32,11 @@ G_BEGIN_DECLS
|
||||
#define SYSPROF_TYPE_PAGE (sysprof_page_get_type())
|
||||
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
G_DECLARE_DERIVABLE_TYPE (SysprofPage, sysprof_page, SYSPROF, PAGE, GtkBin)
|
||||
G_DECLARE_DERIVABLE_TYPE (SysprofPage, sysprof_page, SYSPROF, PAGE, GtkWidget)
|
||||
|
||||
struct _SysprofPageClass
|
||||
{
|
||||
GtkBinClass parent_class;
|
||||
GtkWidgetClass parent_class;
|
||||
|
||||
void (*load_async) (SysprofPage *self,
|
||||
SysprofCaptureReader *reader,
|
||||
|
||||
@ -4,7 +4,10 @@
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">true</property>
|
||||
<property name="margin">6</property>
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin-end">6</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image">
|
||||
|
||||
@ -183,24 +183,24 @@ sysprof_procs_visualizer_set_reader (SysprofVisualizer *visualizer,
|
||||
g_task_run_in_thread (task, discovery_worker);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sysprof_procs_visualizer_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
static void
|
||||
sysprof_procs_visualizer_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
SysprofProcsVisualizer *self = (SysprofProcsVisualizer *)widget;
|
||||
g_autofree SysprofVisualizerAbsolutePoint *points = NULL;
|
||||
gboolean ret = GDK_EVENT_PROPAGATE;
|
||||
GtkAllocation alloc;
|
||||
GdkRGBA background;
|
||||
GdkRGBA foreground;
|
||||
const Point *fpoints;
|
||||
guint n_fpoints = 0;
|
||||
Discovery *d;
|
||||
cairo_t *cr;
|
||||
gdouble last_x = 0;
|
||||
gdouble last_y = 0;
|
||||
|
||||
g_assert (SYSPROF_IS_PROCS_VISUALIZER (self));
|
||||
g_assert (cr != NULL);
|
||||
g_assert (snapshot != NULL);
|
||||
|
||||
gtk_widget_get_allocation (widget, &alloc);
|
||||
|
||||
@ -208,14 +208,17 @@ sysprof_procs_visualizer_draw (GtkWidget *widget,
|
||||
background = foreground;
|
||||
background.alpha *= .5;
|
||||
|
||||
ret = GTK_WIDGET_CLASS (sysprof_procs_visualizer_parent_class)->draw (widget, cr);
|
||||
GTK_WIDGET_CLASS (sysprof_procs_visualizer_parent_class)->snapshot (widget, snapshot);
|
||||
|
||||
if (!(d = self->discovery) || d->cache == NULL)
|
||||
return ret;
|
||||
return;
|
||||
|
||||
if (!(fpoints = point_cache_get_points (d->cache, 1, &n_fpoints)))
|
||||
return ret;
|
||||
return;
|
||||
|
||||
/* This is all going to need offscreen drawing instead of new cairo every frame */
|
||||
|
||||
cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT (0, 0, alloc.width, alloc.height));
|
||||
points = g_new0 (SysprofVisualizerAbsolutePoint, n_fpoints);
|
||||
|
||||
sysprof_visualizer_translate_points (SYSPROF_VISUALIZER (self),
|
||||
@ -254,7 +257,7 @@ sysprof_procs_visualizer_draw (GtkWidget *widget,
|
||||
gdk_cairo_set_source_rgba (cr, &foreground);
|
||||
cairo_stroke (cr);
|
||||
|
||||
return ret;
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -276,7 +279,7 @@ sysprof_procs_visualizer_class_init (SysprofProcsVisualizerClass *klass)
|
||||
|
||||
object_class->finalize = sysprof_procs_visualizer_finalize;
|
||||
|
||||
widget_class->draw = sysprof_procs_visualizer_draw;
|
||||
widget_class->snapshot = sysprof_procs_visualizer_snapshot;
|
||||
|
||||
visualizer_class->set_reader = sysprof_procs_visualizer_set_reader;
|
||||
}
|
||||
|
||||
@ -24,6 +24,8 @@
|
||||
|
||||
#include <sysprof.h>
|
||||
|
||||
#include "egg-three-grid.h"
|
||||
|
||||
#include "sysprof-platform.h"
|
||||
|
||||
#include "sysprof-aid-icon.h"
|
||||
@ -45,7 +47,7 @@
|
||||
|
||||
struct _SysprofProfilerAssistant
|
||||
{
|
||||
GtkBin parent_instance;
|
||||
GtkWidget parent_instance;
|
||||
|
||||
SysprofProcessModel *process_model;
|
||||
|
||||
@ -61,6 +63,7 @@ struct _SysprofProfilerAssistant
|
||||
GtkSwitch *whole_system_switch;
|
||||
GtkSwitch *launch_switch;
|
||||
GtkSwitch *inherit_switch;
|
||||
GtkWidget *scroller;
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -70,7 +73,7 @@ enum {
|
||||
|
||||
static guint signals [N_SIGNALS];
|
||||
|
||||
G_DEFINE_TYPE (SysprofProfilerAssistant, sysprof_profiler_assistant, GTK_TYPE_BIN)
|
||||
G_DEFINE_TYPE (SysprofProfilerAssistant, sysprof_profiler_assistant, GTK_TYPE_WIDGET)
|
||||
|
||||
/**
|
||||
* sysprof_profiler_assistant_new:
|
||||
@ -155,12 +158,12 @@ sysprof_profiler_assistant_command_line_changed_cb (SysprofProfilerAssistant *se
|
||||
g_assert (GTK_IS_ENTRY (entry));
|
||||
|
||||
style_context = gtk_widget_get_style_context (GTK_WIDGET (entry));
|
||||
text = gtk_entry_get_text (entry);
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (entry));
|
||||
|
||||
if (text == NULL || text[0] == 0 || g_shell_parse_argv (text, &argc, &argv, NULL))
|
||||
gtk_style_context_remove_class (style_context, GTK_STYLE_CLASS_ERROR);
|
||||
gtk_style_context_remove_class (style_context, "error");
|
||||
else
|
||||
gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_ERROR);
|
||||
gtk_style_context_add_class (style_context, "error");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -222,9 +225,10 @@ sysprof_profiler_assistant_record_clicked_cb (SysprofProfilerAssistant *self,
|
||||
sysprof_profiler_set_writer (profiler, writer);
|
||||
|
||||
/* Add pids to profiler */
|
||||
gtk_container_foreach (GTK_CONTAINER (self->process_list_box),
|
||||
(GtkCallback) sysprof_profiler_assistant_foreach_cb,
|
||||
profiler);
|
||||
for (GtkWidget *child = gtk_widget_get_first_child (GTK_WIDGET (self->process_list_box));
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
sysprof_profiler_assistant_foreach_cb (child, profiler);
|
||||
|
||||
/* Setup whole system profiling */
|
||||
sysprof_profiler_set_whole_system (profiler, gtk_switch_get_active (self->whole_system_switch));
|
||||
@ -237,7 +241,7 @@ sysprof_profiler_assistant_record_clicked_cb (SysprofProfilerAssistant *self,
|
||||
const gchar *command;
|
||||
gint argc;
|
||||
|
||||
command = gtk_entry_get_text (self->command_line);
|
||||
command = gtk_editable_get_text (GTK_EDITABLE (self->command_line));
|
||||
g_shell_parse_argv (command, &argc, &argv, NULL);
|
||||
|
||||
sysprof_profiler_set_spawn (profiler, TRUE);
|
||||
@ -269,9 +273,10 @@ sysprof_profiler_assistant_record_clicked_cb (SysprofProfilerAssistant *self,
|
||||
sysprof_profiler_add_source (profiler, symbols_source);
|
||||
|
||||
/* Now allow the aids to add their sources */
|
||||
gtk_container_foreach (GTK_CONTAINER (self->aid_flow_box),
|
||||
(GtkCallback) sysprof_profiler_assistant_foreach_cb,
|
||||
profiler);
|
||||
for (GtkWidget *child = gtk_widget_get_first_child (GTK_WIDGET (self->aid_flow_box));
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
sysprof_profiler_assistant_foreach_cb (child, profiler);
|
||||
|
||||
g_signal_emit (self, signals [START_RECORDING], 0, profiler);
|
||||
}
|
||||
@ -322,7 +327,7 @@ sysprof_profiler_assistant_search_changed_cb (SysprofProfilerAssistant *self,
|
||||
|
||||
sysprof_process_model_queue_reload (self->process_model);
|
||||
|
||||
text = gtk_entry_get_text (GTK_ENTRY (search_entry));
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (search_entry));
|
||||
|
||||
if (text[0] == 0)
|
||||
{
|
||||
@ -345,21 +350,23 @@ sysprof_profiler_assistant_search_changed_cb (SysprofProfilerAssistant *self,
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_profiler_assistant_destroy (GtkWidget *widget)
|
||||
sysprof_profiler_assistant_dispose (GObject *object)
|
||||
{
|
||||
SysprofProfilerAssistant *self = (SysprofProfilerAssistant *)widget;
|
||||
SysprofProfilerAssistant *self = (SysprofProfilerAssistant *)object;
|
||||
|
||||
g_clear_object (&self->process_model);
|
||||
g_clear_pointer (&self->scroller, gtk_widget_unparent);
|
||||
|
||||
GTK_WIDGET_CLASS (sysprof_profiler_assistant_parent_class)->destroy (widget);
|
||||
G_OBJECT_CLASS (sysprof_profiler_assistant_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_profiler_assistant_class_init (SysprofProfilerAssistantClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
widget_class->destroy = sysprof_profiler_assistant_destroy;
|
||||
object_class->dispose = sysprof_profiler_assistant_dispose;
|
||||
|
||||
/**
|
||||
* SysprofProfilerAssistant::start-recording:
|
||||
@ -377,6 +384,7 @@ sysprof_profiler_assistant_class_init (SysprofProfilerAssistantClass *klass)
|
||||
G_TYPE_NONE, 1, SYSPROF_TYPE_PROFILER);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/sysprof/ui/sysprof-profiler-assistant.ui");
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofProfilerAssistant, allow_throttling);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofProfilerAssistant, aid_flow_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofProfilerAssistant, command_line);
|
||||
@ -388,6 +396,9 @@ sysprof_profiler_assistant_class_init (SysprofProfilerAssistantClass *klass)
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofProfilerAssistant, launch_switch);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofProfilerAssistant, inherit_switch);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofProfilerAssistant, search_entry);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofProfilerAssistant, scroller);
|
||||
|
||||
g_type_ensure (EGG_TYPE_THREE_GRID);
|
||||
|
||||
g_type_ensure (SYSPROF_TYPE_AID_ICON);
|
||||
g_type_ensure (SYSPROF_TYPE_BATTERY_AID);
|
||||
@ -465,12 +476,12 @@ sysprof_profiler_assistant_set_executable (SysprofProfilerAssistant *self,
|
||||
|
||||
if (path == NULL || path[0] == 0)
|
||||
{
|
||||
gtk_entry_set_text (GTK_ENTRY (self->command_line), "");
|
||||
gtk_editable_set_text (GTK_EDITABLE (self->command_line), "");
|
||||
gtk_switch_set_active (self->launch_switch, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_entry_set_text (GTK_ENTRY (self->command_line), path);
|
||||
gtk_editable_set_text (GTK_EDITABLE (self->command_line), path);
|
||||
gtk_switch_set_active (self->launch_switch, TRUE);
|
||||
gtk_widget_grab_focus (GTK_WIDGET (self->command_line));
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ G_BEGIN_DECLS
|
||||
|
||||
#define SYSPROF_TYPE_PROFILER_ASSISTANT (sysprof_profiler_assistant_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (SysprofProfilerAssistant, sysprof_profiler_assistant, SYSPROF, PROFILER_ASSISTANT, GtkBin)
|
||||
G_DECLARE_FINAL_TYPE (SysprofProfilerAssistant, sysprof_profiler_assistant, SYSPROF, PROFILER_ASSISTANT, GtkWidget)
|
||||
|
||||
GtkWidget *sysprof_profiler_assistant_new (void);
|
||||
void sysprof_profiler_assistant_set_executable (SysprofProfilerAssistant *self,
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.22"/>
|
||||
<object class="SysprofCpuAid" id="cpu_aid">
|
||||
<property name="icon-name">sysprof-cpu</property>
|
||||
</object>
|
||||
@ -62,21 +61,24 @@
|
||||
<object class="SysprofDiskstatSource"/>
|
||||
</child>
|
||||
</object>
|
||||
<template class="SysprofProfilerAssistant" parent="GtkBin">
|
||||
<template class="SysprofProfilerAssistant" parent="GtkWidget">
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<object class="GtkScrolledWindow" id="scroller">
|
||||
<property name="propagate-natural-width">true</property>
|
||||
<property name="propagate-natural-height">true</property>
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="margin">36</property>
|
||||
<property name="margin-top">36</property>
|
||||
<property name="margin-bottom">36</property>
|
||||
<property name="margin-start">36</property>
|
||||
<property name="margin-end">36</property>
|
||||
<property name="spacing">12</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="DzlThreeGrid" id="three_grid">
|
||||
<object class="EggThreeGrid" id="three_grid">
|
||||
<property name="column-spacing">12</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="visible">true</property>
|
||||
@ -199,11 +201,11 @@
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">5</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
@ -213,11 +215,11 @@
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">left</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="whole_system_switch">
|
||||
@ -225,11 +227,11 @@
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="visible">true</property>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
@ -271,7 +273,6 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="shadow-type">in</property>
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="min-content-height">175</property>
|
||||
<property name="max-content-height">175</property>
|
||||
@ -282,8 +283,8 @@
|
||||
<property name="visible">true</property>
|
||||
<child type="placeholder">
|
||||
<object class="GtkLabel">
|
||||
<property name="margin-left">12</property>
|
||||
<property name="margin-right">12</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="label" translatable="yes">Loading Processes…</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="visible">true</property>
|
||||
@ -300,11 +301,11 @@
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label2">
|
||||
@ -315,11 +316,11 @@
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">left</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
@ -399,7 +400,6 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<property name="shadow-type">in</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="SysprofEnvironEditor" id="environ_editor">
|
||||
@ -452,11 +452,11 @@
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label3">
|
||||
@ -467,11 +467,11 @@
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">left</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
@ -501,11 +501,11 @@
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="record_button">
|
||||
@ -519,17 +519,13 @@
|
||||
<style>
|
||||
<class name="suggested-action"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">center</property>
|
||||
<property name="row">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">start</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@ -227,7 +227,7 @@ sysprof_rapl_aid_present_finish (SysprofAid *aid,
|
||||
if (found > 0)
|
||||
sysprof_display_add_group (present->display, energy);
|
||||
else
|
||||
gtk_widget_destroy (GTK_WIDGET (energy));
|
||||
g_object_unref (g_object_ref_sink (energy));
|
||||
}
|
||||
|
||||
return counters != NULL;
|
||||
|
||||
@ -31,7 +31,7 @@ typedef struct
|
||||
gulong notify_elapsed_handler;
|
||||
} SysprofRecordingStateViewPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (SysprofRecordingStateView, sysprof_recording_state_view, GTK_TYPE_BIN)
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (SysprofRecordingStateView, sysprof_recording_state_view, GTK_TYPE_WIDGET)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@ -79,18 +79,22 @@ sysprof_recording_state_view_notify_elapsed (SysprofRecordingStateView *self,
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_recording_state_view_destroy (GtkWidget *widget)
|
||||
sysprof_recording_state_view_dispose (GObject *object)
|
||||
{
|
||||
SysprofRecordingStateView *self = (SysprofRecordingStateView *)widget;
|
||||
SysprofRecordingStateView *self = (SysprofRecordingStateView *)object;
|
||||
SysprofRecordingStateViewPrivate *priv = sysprof_recording_state_view_get_instance_private (self);
|
||||
GtkWidget *child;
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self))))
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
if (priv->profiler != NULL)
|
||||
{
|
||||
g_signal_handler_disconnect (priv->profiler, priv->notify_elapsed_handler);
|
||||
g_clear_signal_handler (&priv->notify_elapsed_handler, priv->profiler);
|
||||
g_clear_object (&priv->profiler);
|
||||
}
|
||||
|
||||
GTK_WIDGET_CLASS (sysprof_recording_state_view_parent_class)->destroy (widget);
|
||||
G_OBJECT_CLASS (sysprof_recording_state_view_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -138,11 +142,10 @@ sysprof_recording_state_view_class_init (SysprofRecordingStateViewClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = sysprof_recording_state_view_dispose;
|
||||
object_class->get_property = sysprof_recording_state_view_get_property;
|
||||
object_class->set_property = sysprof_recording_state_view_set_property;
|
||||
|
||||
widget_class->destroy = sysprof_recording_state_view_destroy;
|
||||
|
||||
properties [PROP_PROFILER] =
|
||||
g_param_spec_object ("profiler",
|
||||
"Profiler",
|
||||
@ -153,6 +156,7 @@ sysprof_recording_state_view_class_init (SysprofRecordingStateViewClass *klass)
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/sysprof/ui/sysprof-recording-state-view.ui");
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofRecordingStateView, elapsed);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofRecordingStateView, samples);
|
||||
|
||||
|
||||
@ -27,13 +27,11 @@ G_BEGIN_DECLS
|
||||
|
||||
#define SYSPROF_TYPE_RECORDING_STATE_VIEW (sysprof_recording_state_view_get_type())
|
||||
|
||||
G_DECLARE_DERIVABLE_TYPE (SysprofRecordingStateView, sysprof_recording_state_view, SYSPROF, RECORDING_STATE_VIEW, GtkBin)
|
||||
G_DECLARE_DERIVABLE_TYPE (SysprofRecordingStateView, sysprof_recording_state_view, SYSPROF, RECORDING_STATE_VIEW, GtkWidget)
|
||||
|
||||
struct _SysprofRecordingStateViewClass
|
||||
{
|
||||
GtkBinClass parent;
|
||||
|
||||
gpointer padding[4];
|
||||
GtkWidgetClass parent;
|
||||
};
|
||||
|
||||
GtkWidget *sysprof_recording_state_view_new (void);
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
<?xml version="1.0"?>
|
||||
<interface>
|
||||
<template class="SysprofRecordingStateView" parent="GtkBin">
|
||||
<template class="SysprofRecordingStateView" parent="GtkWidget">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="width-request">500</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="border-width">36</property>
|
||||
<property name="margin-start">36</property>
|
||||
<property name="margin-end">36</property>
|
||||
<property name="margin-top">36</property>
|
||||
<property name="margin-bottom">36</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">12</property>
|
||||
<property name="visible">true</property>
|
||||
|
||||
@ -28,7 +28,9 @@
|
||||
|
||||
struct _SysprofScrollmap
|
||||
{
|
||||
GtkScrollbar parent_instance;
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *scrollbar;
|
||||
|
||||
gint64 begin_time;
|
||||
gint64 end_time;
|
||||
@ -49,7 +51,7 @@ typedef struct
|
||||
gint height;
|
||||
} Recalculate;
|
||||
|
||||
G_DEFINE_TYPE (SysprofScrollmap, sysprof_scrollmap, GTK_TYPE_SCROLLBAR)
|
||||
G_DEFINE_TYPE (SysprofScrollmap, sysprof_scrollmap, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
recalculate_free (gpointer data)
|
||||
@ -152,68 +154,62 @@ sysprof_scrollmap_recalculate_finish (SysprofScrollmap *self,
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
static void
|
||||
static inline void
|
||||
draw_boxes (const GtkAllocation *alloc,
|
||||
cairo_t *cr,
|
||||
gint x,
|
||||
gint n_boxes)
|
||||
GtkSnapshot *snapshot,
|
||||
int x,
|
||||
int n_boxes,
|
||||
const GdkRGBA *color)
|
||||
{
|
||||
gint y;
|
||||
int y = alloc->y + alloc->height - BOX_SIZE;
|
||||
|
||||
g_assert (cr != NULL);
|
||||
|
||||
y = alloc->height - BOX_SIZE;
|
||||
|
||||
for (gint i = 0; i < n_boxes; i++)
|
||||
for (int i = 0; i < n_boxes; i++)
|
||||
{
|
||||
cairo_rectangle (cr, x, y, BOX_SIZE, -BOX_SIZE);
|
||||
gtk_snapshot_append_color (snapshot, color, &GRAPHENE_RECT_INIT (x, y, BOX_SIZE, -BOX_SIZE));
|
||||
y -= (BOX_SIZE + 1);
|
||||
}
|
||||
|
||||
cairo_fill (cr);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sysprof_scrollmap_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
static void
|
||||
sysprof_scrollmap_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
SysprofScrollmap *self = (SysprofScrollmap *)widget;
|
||||
GtkStyleContext *style_context;
|
||||
GtkAllocation alloc;
|
||||
GdkRGBA color;
|
||||
gint max_boxes;
|
||||
int max_boxes;
|
||||
|
||||
g_assert (SYSPROF_IS_SCROLLMAP (self));
|
||||
g_assert (cr != NULL);
|
||||
g_assert (GTK_IS_SNAPSHOT (snapshot));
|
||||
|
||||
if (self->buckets == NULL)
|
||||
goto chainup;
|
||||
|
||||
gtk_widget_get_allocation (widget, &alloc);
|
||||
|
||||
alloc.y += 3;
|
||||
alloc.height -= 6;
|
||||
|
||||
max_boxes = alloc.height / (BOX_SIZE + 1) - 1;
|
||||
|
||||
style_context = gtk_widget_get_style_context (widget);
|
||||
gtk_style_context_get_color (style_context,
|
||||
gtk_style_context_get_state (style_context),
|
||||
&color);
|
||||
gdk_cairo_set_source_rgba (cr, &color);
|
||||
gtk_style_context_get_color (style_context, &color);
|
||||
|
||||
for (guint i = 0; i < self->buckets->len; i++)
|
||||
{
|
||||
gint n = g_array_index (self->buckets, gint, i);
|
||||
gint x = 1 + i * (BOX_SIZE + 1);
|
||||
gint b = max_boxes * (n / (gdouble)self->most);
|
||||
int n = g_array_index (self->buckets, gint, i);
|
||||
int x = 1 + i * (BOX_SIZE + 1);
|
||||
int b = max_boxes * (n / (gdouble)self->most);
|
||||
|
||||
#if 1
|
||||
if (n > 0)
|
||||
b = MAX (b, 1);
|
||||
#endif
|
||||
|
||||
draw_boxes (&alloc, cr, x, b);
|
||||
draw_boxes (&alloc, snapshot, x, b, &color);
|
||||
}
|
||||
|
||||
chainup:
|
||||
return GTK_WIDGET_CLASS (sysprof_scrollmap_parent_class)->draw (widget, cr);
|
||||
GTK_WIDGET_CLASS (sysprof_scrollmap_parent_class)->snapshot (widget, snapshot);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -246,14 +242,20 @@ sysprof_scrollmap_recalculate_cb (GObject *object,
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_scrollmap_finalize (GObject *object)
|
||||
sysprof_scrollmap_dispose (GObject *object)
|
||||
{
|
||||
SysprofScrollmap *self = (SysprofScrollmap *)object;
|
||||
|
||||
if (self->scrollbar)
|
||||
{
|
||||
gtk_widget_unparent (GTK_WIDGET (self->scrollbar));
|
||||
self->scrollbar = NULL;
|
||||
}
|
||||
|
||||
g_clear_pointer (&self->buckets, g_array_unref);
|
||||
g_clear_pointer (&self->timings, g_array_unref);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_scrollmap_parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (sysprof_scrollmap_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -262,14 +264,21 @@ sysprof_scrollmap_class_init (SysprofScrollmapClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->finalize = sysprof_scrollmap_finalize;
|
||||
object_class->dispose = sysprof_scrollmap_dispose;
|
||||
|
||||
widget_class->draw = sysprof_scrollmap_draw;
|
||||
widget_class->snapshot = sysprof_scrollmap_snapshot;
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
gtk_widget_class_set_css_name (widget_class, "scrollmap");
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_scrollmap_init (SysprofScrollmap *self)
|
||||
{
|
||||
self->scrollbar = g_object_new (GTK_TYPE_SCROLLBAR,
|
||||
"orientation", GTK_ORIENTATION_HORIZONTAL,
|
||||
NULL);
|
||||
gtk_widget_set_parent (GTK_WIDGET (self->scrollbar), GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
void
|
||||
@ -304,3 +313,21 @@ sysprof_scrollmap_set_time_range (SysprofScrollmap *self,
|
||||
sysprof_scrollmap_recalculate_cb,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
sysprof_scrollmap_set_adjustment (SysprofScrollmap *self,
|
||||
GtkAdjustment *adjustment)
|
||||
{
|
||||
g_return_if_fail (SYSPROF_IS_SCROLLMAP (self));
|
||||
g_return_if_fail (!adjustment || GTK_IS_ADJUSTMENT (adjustment));
|
||||
|
||||
gtk_scrollbar_set_adjustment (GTK_SCROLLBAR (self->scrollbar), adjustment);
|
||||
}
|
||||
|
||||
GtkAdjustment *
|
||||
sysprof_scrollmap_get_adjustment (SysprofScrollmap *self)
|
||||
{
|
||||
g_return_val_if_fail (SYSPROF_IS_SCROLLMAP (self), NULL);
|
||||
|
||||
return gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (self->scrollbar));
|
||||
}
|
||||
|
||||
@ -26,12 +26,15 @@ G_BEGIN_DECLS
|
||||
|
||||
#define SYSPROF_TYPE_SCROLLMAP (sysprof_scrollmap_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (SysprofScrollmap, sysprof_scrollmap, SYSPROF, SCROLLMAP, GtkScrollbar)
|
||||
G_DECLARE_FINAL_TYPE (SysprofScrollmap, sysprof_scrollmap, SYSPROF, SCROLLMAP, GtkWidget)
|
||||
|
||||
void sysprof_scrollmap_set_timings (SysprofScrollmap *self,
|
||||
GArray *timings);
|
||||
void sysprof_scrollmap_set_time_range (SysprofScrollmap *self,
|
||||
gint64 begin_time,
|
||||
gint64 end_time);
|
||||
GtkAdjustment *sysprof_scrollmap_get_adjustment (SysprofScrollmap *self);
|
||||
void sysprof_scrollmap_set_adjustment (SysprofScrollmap *self,
|
||||
GtkAdjustment *adjustment);
|
||||
void sysprof_scrollmap_set_timings (SysprofScrollmap *self,
|
||||
GArray *timings);
|
||||
void sysprof_scrollmap_set_time_range (SysprofScrollmap *self,
|
||||
gint64 begin_time,
|
||||
gint64 end_time);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@ -22,14 +22,15 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysprof-display.h"
|
||||
#include "sysprof-display-private.h"
|
||||
#include "sysprof-tab.h"
|
||||
#include "sysprof-ui-private.h"
|
||||
|
||||
struct _SysprofTab
|
||||
{
|
||||
GtkBox parent_instance;
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *center_box;
|
||||
GtkButton *close_button;
|
||||
GtkLabel *title;
|
||||
GtkImage *recording;
|
||||
@ -37,7 +38,7 @@ struct _SysprofTab
|
||||
SysprofDisplay *display;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (SysprofTab, sysprof_tab, GTK_TYPE_BOX)
|
||||
G_DEFINE_TYPE (SysprofTab, sysprof_tab, GTK_TYPE_WIDGET)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@ -62,18 +63,19 @@ sysprof_tab_close_clicked (SysprofTab *self,
|
||||
g_assert (SYSPROF_IS_TAB (self));
|
||||
g_assert (GTK_IS_BUTTON (button));
|
||||
|
||||
if (self->display != NULL)
|
||||
gtk_widget_destroy (GTK_WIDGET (self->display));
|
||||
if (self->display)
|
||||
_sysprof_display_destroy (self->display);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_tab_finalize (GObject *object)
|
||||
sysprof_tab_dispose (GObject *object)
|
||||
{
|
||||
SysprofTab *self = (SysprofTab *)object;
|
||||
|
||||
g_clear_pointer (&self->center_box, gtk_widget_unparent);
|
||||
g_clear_weak_pointer (&self->display);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_tab_parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (sysprof_tab_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -122,11 +124,13 @@ sysprof_tab_class_init (SysprofTabClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->finalize = sysprof_tab_finalize;
|
||||
object_class->dispose = sysprof_tab_dispose;
|
||||
object_class->get_property = sysprof_tab_get_property;
|
||||
object_class->set_property = sysprof_tab_set_property;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/sysprof/ui/sysprof-tab.ui");
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofTab, center_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofTab, close_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofTab, recording);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofTab, title);
|
||||
|
||||
@ -28,7 +28,7 @@ G_BEGIN_DECLS
|
||||
|
||||
#define SYSPROF_TYPE_TAB (sysprof_tab_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (SysprofTab, sysprof_tab, SYSPROF, TAB, GtkBox)
|
||||
G_DECLARE_FINAL_TYPE (SysprofTab, sysprof_tab, SYSPROF, TAB, GtkWidget)
|
||||
|
||||
GtkWidget *sysprof_tab_new (SysprofDisplay *display);
|
||||
|
||||
|
||||
@ -1,60 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.0"/>
|
||||
<template class="SysprofTab" parent="GtkBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<template class="SysprofTab" parent="GtkWidget">
|
||||
<property name="hexpand">true</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="recording">
|
||||
<property name="visible">false</property>
|
||||
<property name="icon-name">media-record-symbolic</property>
|
||||
<property name="pixel-size">16</property>
|
||||
<property name="hexpand">true</property>
|
||||
<property name="halign">end</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
<property name="pack-type">start</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child type="center">
|
||||
<object class="GtkLabel" id="title">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="close_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">window-close-symbolic</property>
|
||||
<object class="GtkCenterBox" id="center_box">
|
||||
<child type="start">
|
||||
<object class="GtkImage" id="recording">
|
||||
<property name="visible">false</property>
|
||||
<property name="icon-name">media-record-symbolic</property>
|
||||
<property name="pixel-size">16</property>
|
||||
<property name="hexpand">true</property>
|
||||
<property name="halign">end</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="center">
|
||||
<object class="GtkLabel" id="title">
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin-end">6</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkButton" id="close_button">
|
||||
<property name="receives_default">False</property>
|
||||
<property name="icon_name">window-close-symbolic</property>
|
||||
<style>
|
||||
<class name="flat"/>
|
||||
<class name="small-button"/>
|
||||
<class name="image-button"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="flat"/>
|
||||
<class name="small-button"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
|
||||
@ -58,8 +58,8 @@ theme_resource_free (gpointer data)
|
||||
|
||||
if (theme_resource->provider != NULL)
|
||||
{
|
||||
gtk_style_context_remove_provider_for_screen (gdk_screen_get_default (),
|
||||
GTK_STYLE_PROVIDER (theme_resource->provider));
|
||||
gtk_style_context_remove_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (theme_resource->provider));
|
||||
g_clear_object (&theme_resource->provider);
|
||||
}
|
||||
|
||||
@ -121,17 +121,17 @@ sysprof_theme_manager_do_reload (gpointer data)
|
||||
{
|
||||
theme_resource->provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (theme_resource->provider, theme_resource->resource);
|
||||
gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
|
||||
GTK_STYLE_PROVIDER (theme_resource->provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION - 1);
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (theme_resource->provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_THEME+1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (theme_resource->provider != NULL)
|
||||
{
|
||||
gtk_style_context_remove_provider_for_screen (gdk_screen_get_default (),
|
||||
GTK_STYLE_PROVIDER (theme_resource->provider));
|
||||
gtk_style_context_remove_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (theme_resource->provider));
|
||||
g_clear_object (&theme_resource->provider);
|
||||
}
|
||||
}
|
||||
@ -146,10 +146,10 @@ sysprof_theme_manager_queue_reload (SysprofThemeManager *self)
|
||||
g_assert (SYSPROF_IS_THEME_MANAGER (self));
|
||||
|
||||
if (self->reload_source == 0)
|
||||
self->reload_source = gdk_threads_add_idle_full (G_PRIORITY_LOW,
|
||||
sysprof_theme_manager_do_reload,
|
||||
self,
|
||||
NULL);
|
||||
self->reload_source = g_idle_add_full (G_PRIORITY_LOW,
|
||||
sysprof_theme_manager_do_reload,
|
||||
self,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -181,7 +181,8 @@ sysprof_theme_manager_init (SysprofThemeManager *self)
|
||||
{
|
||||
self->theme_resources = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, theme_resource_free);
|
||||
|
||||
gtk_icon_theme_add_resource_path (gtk_icon_theme_get_default (), "/org/gnome/sysprof/icons");
|
||||
gtk_icon_theme_add_resource_path (gtk_icon_theme_get_for_display (gdk_display_get_default ()),
|
||||
"/org/gnome/sysprof/icons");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -26,17 +26,37 @@
|
||||
|
||||
struct _SysprofTimeLabel
|
||||
{
|
||||
GtkBox parent;
|
||||
|
||||
GtkLabel *minutes;
|
||||
GtkLabel *seconds;
|
||||
GtkWidget parent_instance;
|
||||
GtkCenterBox *box;
|
||||
GtkLabel *minutes;
|
||||
GtkLabel *seconds;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (SysprofTimeLabel, sysprof_time_label, GTK_TYPE_BOX)
|
||||
G_DEFINE_TYPE (SysprofTimeLabel, sysprof_time_label, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
sysprof_time_label_dispose (GObject *object)
|
||||
{
|
||||
SysprofTimeLabel *self = (SysprofTimeLabel *)object;
|
||||
|
||||
if (self->box)
|
||||
{
|
||||
gtk_widget_unparent (GTK_WIDGET (self->box));
|
||||
self->box = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (sysprof_time_label_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_time_label_class_init (SysprofTimeLabelClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = sysprof_time_label_dispose;
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -48,36 +68,32 @@ sysprof_time_label_init (SysprofTimeLabel *self)
|
||||
pango_attr_list_insert (attrs, pango_attr_scale_new (4));
|
||||
pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
|
||||
|
||||
gtk_box_set_spacing (GTK_BOX (self), 3);
|
||||
self->box = GTK_CENTER_BOX (gtk_center_box_new ());
|
||||
gtk_widget_set_parent (GTK_WIDGET (self->box), GTK_WIDGET (self));
|
||||
|
||||
self->minutes = g_object_new (GTK_TYPE_LABEL,
|
||||
"attributes", attrs,
|
||||
"visible", TRUE,
|
||||
"xalign", 1.0f,
|
||||
"hexpand", TRUE,
|
||||
NULL);
|
||||
gtk_container_add_with_properties (GTK_CONTAINER (self), GTK_WIDGET (self->minutes),
|
||||
"pack-type", GTK_PACK_START,
|
||||
"expand", TRUE,
|
||||
"fill", TRUE,
|
||||
NULL);
|
||||
gtk_center_box_set_start_widget (self->box, GTK_WIDGET (self->minutes));
|
||||
|
||||
sep = g_object_new (GTK_TYPE_LABEL,
|
||||
"margin-start", 3,
|
||||
"margin-end", 3,
|
||||
"attributes", attrs,
|
||||
"visible", TRUE,
|
||||
"label", ":",
|
||||
NULL);
|
||||
gtk_box_set_center_widget (GTK_BOX (self), sep);
|
||||
gtk_center_box_set_center_widget (self->box, sep);
|
||||
|
||||
self->seconds = g_object_new (GTK_TYPE_LABEL,
|
||||
"attributes", attrs,
|
||||
"visible", TRUE,
|
||||
"xalign", 0.0f,
|
||||
"hexpand", TRUE,
|
||||
NULL);
|
||||
gtk_container_add_with_properties (GTK_CONTAINER (self), GTK_WIDGET (self->seconds),
|
||||
"pack-type", GTK_PACK_END,
|
||||
"expand", TRUE,
|
||||
"fill", TRUE,
|
||||
NULL);
|
||||
gtk_center_box_set_end_widget (self->box, GTK_WIDGET (self->seconds));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -26,7 +26,7 @@ G_BEGIN_DECLS
|
||||
|
||||
#define SYSPROF_TYPE_TIME_LABEL (sysprof_time_label_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (SysprofTimeLabel, sysprof_time_label, SYSPROF, TIME_LABEL, GtkBox)
|
||||
G_DECLARE_FINAL_TYPE (SysprofTimeLabel, sysprof_time_label, SYSPROF, TIME_LABEL, GtkWidget)
|
||||
|
||||
void sysprof_time_label_set_duration (SysprofTimeLabel *self,
|
||||
guint duration);
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.0"/>
|
||||
<template class="SysprofTimeLabel" parent="GtkBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">2</property>
|
||||
<child type="center">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label">:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="minute">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label">00</property>
|
||||
<property name="width_chars">2</property>
|
||||
<property name="xalign">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="second">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label">00</property>
|
||||
<property name="width_chars">2</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@ -114,35 +114,39 @@ copy_array (GArray *ar)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sysprof_time_visualizer_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
static void
|
||||
sysprof_time_visualizer_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
SysprofTimeVisualizer *self = (SysprofTimeVisualizer *)widget;
|
||||
SysprofTimeVisualizerPrivate *priv = sysprof_time_visualizer_get_instance_private (self);
|
||||
GtkStyleContext *style_context;
|
||||
GtkStateFlags flags;
|
||||
cairo_t *cr;
|
||||
GtkAllocation alloc;
|
||||
GdkRectangle clip;
|
||||
GdkRGBA foreground;
|
||||
gboolean ret;
|
||||
|
||||
g_assert (SYSPROF_IS_TIME_VISUALIZER (widget));
|
||||
g_assert (cr != NULL);
|
||||
g_assert (snapshot != NULL);
|
||||
|
||||
gtk_widget_get_allocation (widget, &alloc);
|
||||
|
||||
ret = GTK_WIDGET_CLASS (sysprof_time_visualizer_parent_class)->draw (widget, cr);
|
||||
GTK_WIDGET_CLASS (sysprof_time_visualizer_parent_class)->snapshot (widget, snapshot);
|
||||
|
||||
if (priv->cache == NULL)
|
||||
return ret;
|
||||
return;
|
||||
|
||||
#if 0
|
||||
if (!gdk_cairo_get_clip_rectangle (cr, &clip))
|
||||
return ret;
|
||||
#else
|
||||
alloc.x = 0;
|
||||
alloc.y = 0;
|
||||
#endif
|
||||
|
||||
style_context = gtk_widget_get_style_context (widget);
|
||||
flags = gtk_widget_get_state_flags (widget);
|
||||
gtk_style_context_get_color (style_context, flags, &foreground);
|
||||
gtk_style_context_get_color (style_context, &foreground);
|
||||
|
||||
cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT (0, 0, alloc.width, alloc.height));
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, &foreground);
|
||||
|
||||
@ -187,7 +191,7 @@ sysprof_time_visualizer_draw (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -243,10 +247,10 @@ sysprof_time_visualizer_queue_reload (SysprofTimeVisualizer *self)
|
||||
|
||||
if (priv->queued_load == 0)
|
||||
priv->queued_load =
|
||||
gdk_threads_add_idle_full (G_PRIORITY_LOW,
|
||||
sysprof_time_visualizer_do_reload,
|
||||
self,
|
||||
NULL);
|
||||
g_idle_add_full (G_PRIORITY_LOW,
|
||||
sysprof_time_visualizer_do_reload,
|
||||
self,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -283,11 +287,7 @@ sysprof_time_visualizer_finalize (GObject *object)
|
||||
g_clear_pointer (&priv->cache, point_cache_unref);
|
||||
g_clear_pointer (&priv->reader, sysprof_capture_reader_unref);
|
||||
|
||||
if (priv->queued_load != 0)
|
||||
{
|
||||
g_source_remove (priv->queued_load);
|
||||
priv->queued_load = 0;
|
||||
}
|
||||
g_clear_handle_id (&priv->queued_load, g_source_remove);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_time_visualizer_parent_class)->finalize (object);
|
||||
}
|
||||
@ -301,7 +301,7 @@ sysprof_time_visualizer_class_init (SysprofTimeVisualizerClass *klass)
|
||||
|
||||
object_class->finalize = sysprof_time_visualizer_finalize;
|
||||
|
||||
widget_class->draw = sysprof_time_visualizer_draw;
|
||||
widget_class->snapshot = sysprof_time_visualizer_snapshot;
|
||||
|
||||
visualizer_class->set_reader = sysprof_time_visualizer_set_reader;
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <dazzle.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <sysprof.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -38,17 +38,28 @@ struct _SysprofVisualizerGroupHeader
|
||||
G_DEFINE_TYPE (SysprofVisualizerGroupHeader, sysprof_visualizer_group_header, GTK_TYPE_LIST_BOX_ROW)
|
||||
|
||||
static void
|
||||
sysprof_visualizer_group_header_finalize (GObject *object)
|
||||
sysprof_visualizer_group_header_dispose (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (sysprof_visualizer_group_header_parent_class)->finalize (object);
|
||||
SysprofVisualizerGroupHeader *self = (SysprofVisualizerGroupHeader *)object;
|
||||
|
||||
if (self->box)
|
||||
{
|
||||
gtk_widget_unparent (GTK_WIDGET (self->box));
|
||||
self->box = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (sysprof_visualizer_group_header_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_visualizer_group_header_class_init (SysprofVisualizerGroupHeaderClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->finalize = sysprof_visualizer_group_header_finalize;
|
||||
object_class->dispose = sysprof_visualizer_group_header_dispose;
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -58,7 +69,7 @@ sysprof_visualizer_group_header_init (SysprofVisualizerGroupHeader *self)
|
||||
"orientation", GTK_ORIENTATION_VERTICAL,
|
||||
"visible", TRUE,
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (self->box));
|
||||
gtk_widget_set_parent (GTK_WIDGET (self->box), GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
void
|
||||
@ -68,8 +79,9 @@ _sysprof_visualizer_group_header_add_row (SysprofVisualizerGroupHeader *self,
|
||||
GMenuModel *menu,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkBox *box;
|
||||
GtkWidget *group;
|
||||
GtkWidget *sibling;
|
||||
GtkBox *box;
|
||||
|
||||
g_return_if_fail (SYSPROF_IS_VISUALIZER_GROUP_HEADER (self));
|
||||
g_return_if_fail (SYSPROF_IS_VISUALIZER (widget));
|
||||
@ -81,9 +93,11 @@ _sysprof_visualizer_group_header_add_row (SysprofVisualizerGroupHeader *self,
|
||||
"visible", TRUE,
|
||||
NULL);
|
||||
g_object_bind_property (widget, "visible", box, "visible", G_BINDING_SYNC_CREATE);
|
||||
gtk_container_add_with_properties (GTK_CONTAINER (self->box), GTK_WIDGET (box),
|
||||
"position", position,
|
||||
NULL);
|
||||
|
||||
sibling = gtk_widget_get_first_child (GTK_WIDGET (self->box));
|
||||
for (; position > 1 && sibling; position--)
|
||||
sibling = gtk_widget_get_next_sibling (sibling);
|
||||
gtk_box_insert_child_after (self->box, GTK_WIDGET (box), sibling);
|
||||
|
||||
if (title != NULL)
|
||||
{
|
||||
@ -95,13 +109,16 @@ _sysprof_visualizer_group_header_add_row (SysprofVisualizerGroupHeader *self,
|
||||
label = g_object_new (GTK_TYPE_LABEL,
|
||||
"attributes", attrs,
|
||||
"ellipsize", PANGO_ELLIPSIZE_MIDDLE,
|
||||
"margin", 6,
|
||||
"margin-top", 6,
|
||||
"margin-bottom", 6,
|
||||
"margin-start", 6,
|
||||
"margin-end", 6,
|
||||
"hexpand", TRUE,
|
||||
"label", title,
|
||||
"visible", TRUE,
|
||||
"xalign", 0.0f,
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (box), GTK_WIDGET (label));
|
||||
gtk_box_append (box, GTK_WIDGET (label));
|
||||
pango_attr_list_unref (attrs);
|
||||
|
||||
gtk_size_group_add_widget (size_group, widget);
|
||||
@ -120,8 +137,8 @@ _sysprof_visualizer_group_header_add_row (SysprofVisualizerGroupHeader *self,
|
||||
"pixel-size", 16,
|
||||
"visible", TRUE,
|
||||
NULL);
|
||||
dzl_gtk_widget_add_style_class (GTK_WIDGET (image), "dim-label");
|
||||
gtk_container_add (GTK_CONTAINER (box), GTK_WIDGET (image));
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (image)), "dim-label");
|
||||
gtk_box_append (box, GTK_WIDGET (image));
|
||||
}
|
||||
|
||||
if (menu != NULL)
|
||||
@ -134,12 +151,11 @@ _sysprof_visualizer_group_header_add_row (SysprofVisualizerGroupHeader *self,
|
||||
"icon-name", "view-more-symbolic",
|
||||
"visible", TRUE,
|
||||
NULL),
|
||||
"margin-right", 6,
|
||||
"margin-end", 6,
|
||||
"direction", GTK_ARROW_RIGHT,
|
||||
"halign", GTK_ALIGN_CENTER,
|
||||
"menu-model", menu,
|
||||
"tooltip-text", _("Display supplemental graphs"),
|
||||
"use-popover", FALSE,
|
||||
"valign", GTK_ALIGN_CENTER,
|
||||
"visible", TRUE,
|
||||
NULL);
|
||||
@ -148,7 +164,7 @@ _sysprof_visualizer_group_header_add_row (SysprofVisualizerGroupHeader *self,
|
||||
gtk_style_context_add_class (style_context, "small-button");
|
||||
gtk_style_context_add_class (style_context, "flat");
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (box), GTK_WIDGET (button));
|
||||
gtk_box_append (box, GTK_WIDGET (button));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -22,7 +22,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <dazzle.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "sysprof-visualizer.h"
|
||||
@ -158,21 +157,6 @@ create_action_name (const gchar *str)
|
||||
return g_string_free (ret, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_visualizer_group_add (GtkContainer *container,
|
||||
GtkWidget *child)
|
||||
{
|
||||
SysprofVisualizerGroup *self = (SysprofVisualizerGroup *)container;
|
||||
|
||||
g_assert (SYSPROF_IS_VISUALIZER_GROUP (self));
|
||||
g_assert (GTK_IS_WIDGET (child));
|
||||
|
||||
if (SYSPROF_IS_VISUALIZER (child))
|
||||
sysprof_visualizer_group_insert (self, SYSPROF_VISUALIZER (child), -1, FALSE);
|
||||
else
|
||||
GTK_CONTAINER_CLASS (sysprof_visualizer_group_parent_class)->add (container, child);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_visualizer_group_finalize (GObject *object)
|
||||
{
|
||||
@ -186,7 +170,7 @@ sysprof_visualizer_group_finalize (GObject *object)
|
||||
g_clear_object (&priv->rows_menu);
|
||||
g_clear_object (&priv->actions);
|
||||
|
||||
dzl_clear_weak_pointer (&priv->header);
|
||||
g_clear_weak_pointer (&priv->header);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_visualizer_group_parent_class)->finalize (object);
|
||||
}
|
||||
@ -258,14 +242,11 @@ sysprof_visualizer_group_class_init (SysprofVisualizerGroupClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
|
||||
|
||||
object_class->finalize = sysprof_visualizer_group_finalize;
|
||||
object_class->get_property = sysprof_visualizer_group_get_property;
|
||||
object_class->set_property = sysprof_visualizer_group_set_property;
|
||||
|
||||
container_class->add = sysprof_visualizer_group_add;
|
||||
|
||||
properties [PROP_HAS_PAGE] =
|
||||
g_param_spec_boolean ("has-page",
|
||||
"Has Page",
|
||||
@ -331,7 +312,7 @@ sysprof_visualizer_group_init (SysprofVisualizerGroup *self)
|
||||
"orientation", GTK_ORIENTATION_VERTICAL,
|
||||
"visible", TRUE,
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (priv->visualizers));
|
||||
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (self), GTK_WIDGET (priv->visualizers));
|
||||
}
|
||||
|
||||
void
|
||||
@ -343,11 +324,10 @@ _sysprof_visualizer_group_set_header (SysprofVisualizerGroup *self,
|
||||
g_return_if_fail (SYSPROF_IS_VISUALIZER_GROUP (self));
|
||||
g_return_if_fail (!header || SYSPROF_IS_VISUALIZER_GROUP_HEADER (header));
|
||||
|
||||
if (dzl_set_weak_pointer (&priv->header, header))
|
||||
if (g_set_weak_pointer (&priv->header, header))
|
||||
{
|
||||
if (header != NULL)
|
||||
{
|
||||
GList *children;
|
||||
guint position = 0;
|
||||
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (header),
|
||||
@ -355,11 +335,11 @@ _sysprof_visualizer_group_set_header (SysprofVisualizerGroup *self,
|
||||
G_ACTION_GROUP (priv->actions));
|
||||
gtk_size_group_add_widget (priv->size_group, GTK_WIDGET (header));
|
||||
|
||||
children = gtk_container_get_children (GTK_CONTAINER (priv->visualizers));
|
||||
|
||||
for (const GList *iter = children; iter; iter = iter->next)
|
||||
for (GtkWidget *child = gtk_widget_get_first_child (GTK_WIDGET (priv->visualizers));
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
SysprofVisualizer *vis = iter->data;
|
||||
SysprofVisualizer *vis = SYSPROF_VISUALIZER (child);
|
||||
const gchar *title;
|
||||
GMenuModel *menu = NULL;
|
||||
|
||||
@ -381,19 +361,10 @@ _sysprof_visualizer_group_set_header (SysprofVisualizerGroup *self,
|
||||
|
||||
position++;
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_visualizer_group_set_reader_cb (SysprofVisualizer *visualizer,
|
||||
SysprofCaptureReader *reader)
|
||||
{
|
||||
sysprof_visualizer_set_reader (visualizer, reader);
|
||||
}
|
||||
|
||||
void
|
||||
_sysprof_visualizer_group_set_reader (SysprofVisualizerGroup *self,
|
||||
SysprofCaptureReader *reader)
|
||||
@ -403,9 +374,10 @@ _sysprof_visualizer_group_set_reader (SysprofVisualizerGroup *self,
|
||||
g_return_if_fail (SYSPROF_IS_VISUALIZER_GROUP (self));
|
||||
g_return_if_fail (reader != NULL);
|
||||
|
||||
gtk_container_foreach (GTK_CONTAINER (priv->visualizers),
|
||||
(GtkCallback) sysprof_visualizer_group_set_reader_cb,
|
||||
reader);
|
||||
for (GtkWidget *child = gtk_widget_get_first_child (GTK_WIDGET (priv->visualizers));
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
sysprof_visualizer_set_reader (SYSPROF_VISUALIZER (child), reader);
|
||||
}
|
||||
|
||||
void
|
||||
@ -415,13 +387,18 @@ sysprof_visualizer_group_insert (SysprofVisualizerGroup *self,
|
||||
gboolean can_toggle)
|
||||
{
|
||||
SysprofVisualizerGroupPrivate *priv = sysprof_visualizer_group_get_instance_private (self);
|
||||
GtkWidget *sibling = NULL;
|
||||
|
||||
g_return_if_fail (SYSPROF_IS_VISUALIZER_GROUP (self));
|
||||
g_return_if_fail (SYSPROF_IS_VISUALIZER (visualizer));
|
||||
|
||||
gtk_container_add_with_properties (GTK_CONTAINER (priv->visualizers), GTK_WIDGET (visualizer),
|
||||
"position", position,
|
||||
NULL);
|
||||
sibling = gtk_widget_get_first_child (GTK_WIDGET (priv->visualizers));
|
||||
while (position > 1 && sibling)
|
||||
{
|
||||
sibling = gtk_widget_get_next_sibling (sibling);
|
||||
position--;
|
||||
}
|
||||
gtk_box_insert_child_after (priv->visualizers, GTK_WIDGET (visualizer), sibling);
|
||||
|
||||
if (can_toggle)
|
||||
{
|
||||
|
||||
@ -135,10 +135,11 @@ update_label_text (PangoLayout *layout,
|
||||
|
||||
static gboolean
|
||||
draw_ticks (SysprofVisualizerTicks *self,
|
||||
cairo_t *cr,
|
||||
GtkAllocation *area,
|
||||
gint ticks,
|
||||
gboolean label_mode)
|
||||
GtkSnapshot *snapshot,
|
||||
GtkAllocation *area,
|
||||
gint ticks,
|
||||
gboolean label_mode,
|
||||
const GdkRGBA *color)
|
||||
{
|
||||
GtkAllocation alloc;
|
||||
gint64 begin_time, end_time;
|
||||
@ -146,7 +147,7 @@ draw_ticks (SysprofVisualizerTicks *self,
|
||||
gint count = 0;
|
||||
|
||||
g_assert (SYSPROF_IS_VISUALIZER_TICKS (self));
|
||||
g_assert (cr != NULL);
|
||||
g_assert (snapshot != NULL);
|
||||
g_assert (area != NULL);
|
||||
g_assert (ticks >= 0);
|
||||
g_assert (ticks < N_TICKS);
|
||||
@ -195,12 +196,16 @@ draw_ticks (SysprofVisualizerTicks *self,
|
||||
if (x < (last_x2 + MIN_TICK_DISTANCE))
|
||||
continue;
|
||||
|
||||
cairo_move_to (cr, (gint)x + 2.5 - (gint)half, 2);
|
||||
update_label_text (layout, t - begin_time, want_msec);
|
||||
pango_layout_get_pixel_size (layout, &w, &h);
|
||||
|
||||
if (x + w <= alloc.width)
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
{
|
||||
gtk_snapshot_save (snapshot);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT ((int)x + 2.5 - (int)half, 2));
|
||||
gtk_snapshot_append_layout (snapshot, layout, color);
|
||||
gtk_snapshot_restore (snapshot);
|
||||
}
|
||||
|
||||
last_x2 = x + w;
|
||||
}
|
||||
@ -212,48 +217,44 @@ draw_ticks (SysprofVisualizerTicks *self,
|
||||
for (gint64 t = begin_time; t <= end_time; t += tick_sizing[ticks].span)
|
||||
{
|
||||
gdouble x = sysprof_visualizer_get_x_for_time (SYSPROF_VISUALIZER (self), t);
|
||||
cairo_move_to (cr, (gint)x - .5 - (gint)half, alloc.height);
|
||||
cairo_line_to (cr, (gint)x - .5 - (gint)half, alloc.height - tick_sizing[ticks].height);
|
||||
|
||||
gtk_snapshot_append_color (snapshot, color,
|
||||
&GRAPHENE_RECT_INIT ((int)x - .5 - (int)half,
|
||||
alloc.height,
|
||||
(int)x - .5 - (int)half + tick_sizing[ticks].width,
|
||||
alloc.height - tick_sizing[ticks].height));
|
||||
count++;
|
||||
}
|
||||
|
||||
cairo_set_line_width (cr, tick_sizing[ticks].width);
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
|
||||
return count > 2;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sysprof_visualizer_ticks_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
static void
|
||||
sysprof_visualizer_ticks_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
SysprofVisualizerTicks *self = SYSPROF_VISUALIZER_TICKS (widget);
|
||||
GtkStyleContext *style;
|
||||
GtkAllocation alloc;
|
||||
GtkStateFlags state;
|
||||
gint64 timespan;
|
||||
GdkRGBA color;
|
||||
|
||||
g_assert (SYSPROF_IS_VISUALIZER_TICKS (self));
|
||||
g_assert (cr != NULL);
|
||||
g_assert (snapshot != NULL);
|
||||
|
||||
timespan = sysprof_visualizer_get_duration (SYSPROF_VISUALIZER (self));
|
||||
if (timespan == 0)
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
|
||||
style = gtk_widget_get_style_context (widget);
|
||||
return;
|
||||
|
||||
gtk_widget_get_allocation (GTK_WIDGET (self), &alloc);
|
||||
alloc.x = 0;
|
||||
alloc.y = 0;
|
||||
|
||||
gtk_render_background (style, cr, 0, 0, alloc.width, alloc.height);
|
||||
style = gtk_widget_get_style_context (widget);
|
||||
gtk_style_context_get_color (style, &color);
|
||||
|
||||
state = gtk_widget_get_state_flags (widget);
|
||||
gtk_style_context_get_color (style, state, &color);
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, &color);
|
||||
gtk_snapshot_render_background (snapshot, style, 0, 0, alloc.width, alloc.height);
|
||||
|
||||
/*
|
||||
* We need to discover up to what level we will draw tick marks.
|
||||
@ -272,27 +273,32 @@ sysprof_visualizer_ticks_draw (GtkWidget *widget,
|
||||
|
||||
for (guint j = i; j > 0; j--)
|
||||
{
|
||||
if (draw_ticks (self, cr, &alloc, j - 1, FALSE))
|
||||
if (draw_ticks (self, snapshot, &alloc, j - 1, FALSE, &color))
|
||||
largest_match = j - 1;
|
||||
}
|
||||
|
||||
if (largest_match != -1)
|
||||
draw_ticks (self, cr, &alloc, largest_match, TRUE);
|
||||
draw_ticks (self, snapshot, &alloc, largest_match, TRUE, &color);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_visualizer_ticks_get_preferred_height (GtkWidget *widget,
|
||||
gint *min_height,
|
||||
gint *nat_height)
|
||||
sysprof_visualizer_ticks_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
g_assert (SYSPROF_IS_VISUALIZER_TICKS (widget));
|
||||
|
||||
*min_height = *nat_height = tick_sizing[0].height + LABEL_HEIGHT_PX;
|
||||
if (orientation == GTK_ORIENTATION_VERTICAL)
|
||||
*minimum = *natural = tick_sizing[0].height + LABEL_HEIGHT_PX;
|
||||
else
|
||||
*minimum = *natural = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -300,8 +306,8 @@ sysprof_visualizer_ticks_class_init (SysprofVisualizerTicksClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
widget_class->draw = sysprof_visualizer_ticks_draw;
|
||||
widget_class->get_preferred_height = sysprof_visualizer_ticks_get_preferred_height;
|
||||
widget_class->snapshot = sysprof_visualizer_ticks_snapshot;
|
||||
widget_class->measure = sysprof_visualizer_ticks_measure;
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "SysprofVisualizerTicks");
|
||||
}
|
||||
|
||||
@ -31,14 +31,9 @@ typedef struct
|
||||
gint64 begin_time;
|
||||
gint64 end_time;
|
||||
gint64 duration;
|
||||
|
||||
/* A cached allocation that has the borders subtracted so that
|
||||
* we place the content within the expected area.
|
||||
*/
|
||||
GtkAllocation cache_alloc;
|
||||
} SysprofVisualizerPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (SysprofVisualizer, sysprof_visualizer, DZL_TYPE_BIN)
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (SysprofVisualizer, sysprof_visualizer, GTK_TYPE_WIDGET)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@ -50,53 +45,6 @@ enum {
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
static inline void
|
||||
subtract_border (GtkAllocation *alloc,
|
||||
GtkBorder *border)
|
||||
{
|
||||
#if 0
|
||||
g_print ("Border; %d %d %d %d\n", border->top, border->left, border->bottom, border->right);
|
||||
#endif
|
||||
|
||||
alloc->x += border->left;
|
||||
alloc->y += border->top;
|
||||
alloc->width -= border->left + border->right;
|
||||
alloc->height -= border->top + border->bottom;
|
||||
}
|
||||
|
||||
static void
|
||||
adjust_alloc_for_borders (SysprofVisualizer *self,
|
||||
GtkAllocation *alloc)
|
||||
{
|
||||
GtkStyleContext *style_context;
|
||||
GtkBorder border;
|
||||
GtkStateFlags state;
|
||||
|
||||
g_assert (SYSPROF_IS_VISUALIZER (self));
|
||||
g_assert (alloc != NULL);
|
||||
|
||||
state = gtk_widget_get_state_flags (GTK_WIDGET (self));
|
||||
style_context = gtk_widget_get_style_context (GTK_WIDGET (self));
|
||||
gtk_style_context_get_border (style_context, state, &border);
|
||||
|
||||
subtract_border (alloc, &border);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_visualizer_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *alloc)
|
||||
{
|
||||
SysprofVisualizer *self = (SysprofVisualizer *)widget;
|
||||
SysprofVisualizerPrivate *priv = sysprof_visualizer_get_instance_private (self);
|
||||
|
||||
g_assert (SYSPROF_IS_VISUALIZER (self));
|
||||
|
||||
GTK_WIDGET_CLASS (sysprof_visualizer_parent_class)->size_allocate (widget, alloc);
|
||||
|
||||
priv->cache_alloc = *alloc;
|
||||
adjust_alloc_for_borders (self, &priv->cache_alloc);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_visualizer_finalize (GObject *object)
|
||||
{
|
||||
@ -175,8 +123,6 @@ sysprof_visualizer_class_init (SysprofVisualizerClass *klass)
|
||||
object_class->get_property = sysprof_visualizer_get_property;
|
||||
object_class->set_property = sysprof_visualizer_set_property;
|
||||
|
||||
widget_class->size_allocate = sysprof_visualizer_size_allocate;
|
||||
|
||||
properties [PROP_BEGIN_TIME] =
|
||||
g_param_spec_int64 ("begin-time",
|
||||
"Begin Time",
|
||||
@ -296,20 +242,21 @@ sysprof_visualizer_translate_points (SysprofVisualizer *self,
|
||||
SysprofVisualizerAbsolutePoint *out_points,
|
||||
guint n_out_points)
|
||||
{
|
||||
SysprofVisualizerPrivate *priv = sysprof_visualizer_get_instance_private (self);
|
||||
const GtkAllocation *a;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
g_return_if_fail (SYSPROF_IS_VISUALIZER (self));
|
||||
g_return_if_fail (in_points != NULL);
|
||||
g_return_if_fail (out_points != NULL);
|
||||
g_return_if_fail (n_in_points == n_out_points);
|
||||
|
||||
a = &priv->cache_alloc;
|
||||
width = gtk_widget_get_width (GTK_WIDGET (self));
|
||||
height = gtk_widget_get_height (GTK_WIDGET (self));
|
||||
|
||||
for (guint i = 0; i < n_in_points; i++)
|
||||
{
|
||||
out_points[i].x = (in_points[i].x * a->width);
|
||||
out_points[i].y = a->height - (ABS (in_points[i].y) * a->height);
|
||||
out_points[i].x = (in_points[i].x * width);
|
||||
out_points[i].y = height - (ABS (in_points[i].y) * height);
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,7 +266,7 @@ sysprof_visualizer_get_x_for_time (SysprofVisualizer *self,
|
||||
{
|
||||
SysprofVisualizerPrivate *priv = sysprof_visualizer_get_instance_private (self);
|
||||
|
||||
return ((time - priv->begin_time) / (gdouble)priv->duration) * priv->cache_alloc.width;
|
||||
return ((time - priv->begin_time) / (gdouble)priv->duration) * gtk_widget_get_width (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
# error "Only <sysprof-ui.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <dazzle.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <sysprof.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@ -44,11 +44,11 @@ typedef struct
|
||||
#define SYSPROF_TYPE_VISUALIZER (sysprof_visualizer_get_type())
|
||||
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
G_DECLARE_DERIVABLE_TYPE (SysprofVisualizer, sysprof_visualizer, SYSPROF, VISUALIZER, DzlBin)
|
||||
G_DECLARE_DERIVABLE_TYPE (SysprofVisualizer, sysprof_visualizer, SYSPROF, VISUALIZER, GtkWidget)
|
||||
|
||||
struct _SysprofVisualizerClass
|
||||
{
|
||||
DzlBinClass parent_class;
|
||||
GtkWidgetClass parent_class;
|
||||
|
||||
void (*set_reader) (SysprofVisualizer *self,
|
||||
SysprofCaptureReader *reader);
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
|
||||
struct _SysprofVisualizersFrame
|
||||
{
|
||||
GtkBin parent_instance;
|
||||
GtkWidget parent_instance;
|
||||
|
||||
/* Drag selection tracking */
|
||||
SysprofSelection *selection;
|
||||
@ -65,13 +65,14 @@ typedef struct
|
||||
{
|
||||
GtkListBox *list;
|
||||
GtkStyleContext *style_context;
|
||||
cairo_t *cr;
|
||||
GtkAllocation alloc;
|
||||
GtkSnapshot *snapshot;
|
||||
int width;
|
||||
int height;
|
||||
gint64 begin_time;
|
||||
gint64 duration;
|
||||
} SelectionDraw;
|
||||
|
||||
G_DEFINE_TYPE (SysprofVisualizersFrame, sysprof_visualizers_frame, GTK_TYPE_BIN)
|
||||
G_DEFINE_TYPE (SysprofVisualizersFrame, sysprof_visualizers_frame, GTK_TYPE_WIDGET)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@ -115,16 +116,16 @@ draw_selection_cb (SysprofSelection *selection,
|
||||
|
||||
g_assert (SYSPROF_IS_SELECTION (selection));
|
||||
g_assert (draw != NULL);
|
||||
g_assert (draw->cr != NULL);
|
||||
g_assert (draw->snapshot != NULL);
|
||||
g_assert (GTK_IS_LIST_BOX (draw->list));
|
||||
|
||||
x = (range_begin - draw->begin_time) / (gdouble)draw->duration;
|
||||
x2 = (range_end - draw->begin_time) / (gdouble)draw->duration;
|
||||
|
||||
area.x = x * draw->alloc.width;
|
||||
area.width = (x2 * draw->alloc.width) - area.x;
|
||||
area.x = x * draw->width;
|
||||
area.width = (x2 * draw->width) - area.x;
|
||||
area.y = 0;
|
||||
area.height = draw->alloc.height;
|
||||
area.height = draw->height;
|
||||
|
||||
if (area.width < 0)
|
||||
{
|
||||
@ -132,104 +133,106 @@ draw_selection_cb (SysprofSelection *selection,
|
||||
area.x -= area.width;
|
||||
}
|
||||
|
||||
gtk_render_background (draw->style_context, draw->cr, area.x + 2, area.y + 2, area.width - 4, area.height - 4);
|
||||
gtk_snapshot_render_background (draw->snapshot, draw->style_context, area.x + 2, area.y + 2, area.width - 4, area.height - 4);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
visualizers_draw_after_cb (SysprofVisualizersFrame *self,
|
||||
cairo_t *cr,
|
||||
GtkListBox *list)
|
||||
static void
|
||||
sysprof_visualizers_frame_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
SysprofVisualizersFrame *self = (SysprofVisualizersFrame *)widget;
|
||||
SelectionDraw draw;
|
||||
GtkAllocation alloc;
|
||||
|
||||
g_assert (SYSPROF_IS_VISUALIZERS_FRAME (self));
|
||||
g_assert (GTK_IS_LIST_BOX (list));
|
||||
g_assert (GTK_IS_SNAPSHOT (snapshot));
|
||||
|
||||
GTK_WIDGET_CLASS (sysprof_visualizers_frame_parent_class)->snapshot (widget, snapshot);
|
||||
|
||||
draw.style_context = gtk_widget_get_style_context (GTK_WIDGET (list));
|
||||
draw.list = list;
|
||||
draw.cr = cr;
|
||||
draw.begin_time = self->begin_time;
|
||||
draw.duration = sysprof_visualizer_get_duration (SYSPROF_VISUALIZER (self->ticks));
|
||||
|
||||
if (draw.duration == 0)
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
return;
|
||||
|
||||
gtk_widget_get_allocation (GTK_WIDGET (list), &draw.alloc);
|
||||
draw.style_context = gtk_widget_get_style_context (GTK_WIDGET (self->visualizers));
|
||||
draw.list = self->visualizers;
|
||||
draw.snapshot = snapshot;
|
||||
draw.begin_time = self->begin_time;
|
||||
|
||||
gtk_widget_get_allocation (GTK_WIDGET (self->visualizers), &alloc);
|
||||
draw.width = alloc.width;
|
||||
draw.height = alloc.height;
|
||||
|
||||
if (sysprof_selection_get_has_selection (self->selection) || self->button_pressed)
|
||||
{
|
||||
double x, y;
|
||||
|
||||
gtk_snapshot_save (snapshot);
|
||||
gtk_widget_translate_coordinates (GTK_WIDGET (self->visualizers),
|
||||
GTK_WIDGET (self),
|
||||
0, 0, &x, &y);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x, y));
|
||||
|
||||
gtk_style_context_add_class (draw.style_context, "selection");
|
||||
sysprof_selection_foreach (self->selection, draw_selection_cb, &draw);
|
||||
if (self->button_pressed)
|
||||
draw_selection_cb (self->selection, self->drag_begin_at, self->drag_selection_at, &draw);
|
||||
gtk_style_context_remove_class (draw.style_context, "selection");
|
||||
}
|
||||
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
gtk_snapshot_restore (snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
visualizers_realize_after_cb (SysprofVisualizersFrame *self,
|
||||
GtkListBox *list)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkWindow *window;
|
||||
GdkCursor *cursor;
|
||||
|
||||
g_assert (SYSPROF_IS_VISUALIZERS_FRAME (self));
|
||||
g_assert (GTK_IS_LIST_BOX (list));
|
||||
|
||||
window = gtk_widget_get_window (GTK_WIDGET (list));
|
||||
display = gdk_window_get_display (window);
|
||||
cursor = gdk_cursor_new_from_name (display, "text");
|
||||
gdk_window_set_cursor (window, cursor);
|
||||
g_clear_object (&cursor);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
visualizers_button_press_event_cb (SysprofVisualizersFrame *self,
|
||||
GdkEventButton *ev,
|
||||
GtkListBox *visualizers)
|
||||
int n_presses,
|
||||
double x,
|
||||
double y,
|
||||
GtkGestureClick *gesture)
|
||||
{
|
||||
g_assert (SYSPROF_IS_VISUALIZERS_FRAME (self));
|
||||
g_assert (ev != NULL);
|
||||
g_assert (GTK_IS_LIST_BOX (visualizers));
|
||||
GdkModifierType state;
|
||||
guint button;
|
||||
|
||||
if (ev->button != GDK_BUTTON_PRIMARY)
|
||||
g_assert (SYSPROF_IS_VISUALIZERS_FRAME (self));
|
||||
g_assert (GTK_IS_GESTURE_CLICK (gesture));
|
||||
|
||||
button = gtk_gesture_single_get_button (GTK_GESTURE_SINGLE (gesture));
|
||||
|
||||
if (button != GDK_BUTTON_PRIMARY)
|
||||
{
|
||||
if (sysprof_selection_get_has_selection (self->selection))
|
||||
{
|
||||
sysprof_selection_unselect_all (self->selection);
|
||||
return GDK_EVENT_STOP;
|
||||
}
|
||||
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
sysprof_selection_unselect_all (self->selection);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ev->state & GDK_SHIFT_MASK) == 0)
|
||||
state = gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
if ((state & GDK_SHIFT_MASK) == 0)
|
||||
sysprof_selection_unselect_all (self->selection);
|
||||
|
||||
self->button_pressed = TRUE;
|
||||
|
||||
self->drag_begin_at = get_time_from_x (self, ev->x);
|
||||
self->drag_begin_at = get_time_from_x (self, x);
|
||||
self->drag_selection_at = self->drag_begin_at;
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (visualizers));
|
||||
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static void
|
||||
visualizers_button_release_event_cb (SysprofVisualizersFrame *self,
|
||||
GdkEventButton *ev,
|
||||
GtkListBox *list)
|
||||
int n_release,
|
||||
double x,
|
||||
double y,
|
||||
GtkGestureClick *gesture)
|
||||
{
|
||||
g_assert (SYSPROF_IS_VISUALIZERS_FRAME (self));
|
||||
g_assert (ev != NULL);
|
||||
g_assert (GTK_IS_LIST_BOX (list));
|
||||
guint button;
|
||||
|
||||
if (!self->button_pressed || ev->button != GDK_BUTTON_PRIMARY)
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
g_assert (SYSPROF_IS_VISUALIZERS_FRAME (self));
|
||||
g_assert (GTK_IS_GESTURE_CLICK (gesture));
|
||||
|
||||
button = gtk_gesture_single_get_button (GTK_GESTURE_SINGLE (gesture));
|
||||
|
||||
if (!self->button_pressed || button != GDK_BUTTON_PRIMARY)
|
||||
return;
|
||||
|
||||
self->button_pressed = FALSE;
|
||||
|
||||
@ -242,46 +245,33 @@ visualizers_button_release_event_cb (SysprofVisualizersFrame *self,
|
||||
self->drag_selection_at = -1;
|
||||
}
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (list));
|
||||
|
||||
return GDK_EVENT_STOP;
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
visualizers_motion_notify_event_cb (SysprofVisualizersFrame *self,
|
||||
GdkEventMotion *ev,
|
||||
GtkListBox *list)
|
||||
static void
|
||||
visualizers_motion_notify_event_cb (SysprofVisualizersFrame *self,
|
||||
double x,
|
||||
double y,
|
||||
GtkEventControllerMotion *motion)
|
||||
{
|
||||
g_assert (SYSPROF_IS_VISUALIZERS_FRAME (self));
|
||||
g_assert (ev != NULL);
|
||||
g_assert (GTK_IS_LIST_BOX (list));
|
||||
g_assert (GTK_IS_EVENT_CONTROLLER_MOTION (motion));
|
||||
|
||||
if (!self->button_pressed)
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
|
||||
self->drag_selection_at = get_time_from_x (self, ev->x);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (list));
|
||||
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
if (self->button_pressed)
|
||||
{
|
||||
self->drag_selection_at = get_time_from_x (self, x);
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_children_width_request_cb (GtkWidget *widget,
|
||||
gpointer data)
|
||||
set_children_width_request (GtkWidget *widget,
|
||||
int width)
|
||||
{
|
||||
gtk_widget_set_size_request (widget, GPOINTER_TO_INT (data), -1);
|
||||
}
|
||||
|
||||
static void
|
||||
set_children_width_request (GtkContainer *container,
|
||||
gint width)
|
||||
{
|
||||
g_assert (GTK_IS_CONTAINER (container));
|
||||
|
||||
gtk_container_foreach (container,
|
||||
set_children_width_request_cb,
|
||||
GINT_TO_POINTER (width));
|
||||
for (GtkWidget *child = gtk_widget_get_first_child (widget);
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
gtk_widget_set_size_request (child, width, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -297,8 +287,8 @@ sysprof_visualizers_frame_notify_zoom (SysprofVisualizersFrame *self,
|
||||
|
||||
duration = self->end_time - self->begin_time;
|
||||
data_width = sysprof_zoom_manager_get_width_for_duration (self->zoom_manager, duration);
|
||||
set_children_width_request (GTK_CONTAINER (self->ticks_viewport), data_width);
|
||||
set_children_width_request (GTK_CONTAINER (self->visualizers_viewport), data_width);
|
||||
set_children_width_request (GTK_WIDGET (self->ticks_viewport), data_width);
|
||||
set_children_width_request (GTK_WIDGET (self->visualizers_viewport), data_width);
|
||||
}
|
||||
|
||||
static gint
|
||||
@ -306,17 +296,16 @@ find_pos (SysprofVisualizersFrame *self,
|
||||
const gchar *title,
|
||||
gint priority)
|
||||
{
|
||||
GList *list;
|
||||
gint pos = 0;
|
||||
|
||||
if (title == NULL)
|
||||
return -1;
|
||||
|
||||
list = gtk_container_get_children (GTK_CONTAINER (self->visualizers));
|
||||
|
||||
for (const GList *iter = list; iter; iter = iter->next)
|
||||
for (GtkWidget *child = gtk_widget_get_first_child (GTK_WIDGET (self->visualizers));
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
SysprofVisualizerGroup *group = iter->data;
|
||||
SysprofVisualizerGroup *group = SYSPROF_VISUALIZER_GROUP (child);
|
||||
gint prio = sysprof_visualizer_group_get_priority (group);
|
||||
const gchar *item = sysprof_visualizer_group_get_title (group);
|
||||
|
||||
@ -327,41 +316,34 @@ find_pos (SysprofVisualizersFrame *self,
|
||||
pos++;
|
||||
}
|
||||
|
||||
g_list_free (list);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_visualizers_frame_add (GtkContainer *container,
|
||||
GtkWidget *child)
|
||||
void
|
||||
sysprof_visualizers_frame_add_group (SysprofVisualizersFrame *self,
|
||||
SysprofVisualizerGroup *group)
|
||||
{
|
||||
SysprofVisualizersFrame *self = (SysprofVisualizersFrame *)container;
|
||||
SysprofVisualizerGroupHeader *header;
|
||||
const char *title;
|
||||
int priority;
|
||||
int pos;
|
||||
|
||||
g_assert (SYSPROF_IS_VISUALIZERS_FRAME (self));
|
||||
g_assert (GTK_IS_WIDGET (child));
|
||||
g_return_if_fail (SYSPROF_IS_VISUALIZERS_FRAME (self));
|
||||
g_return_if_fail (SYSPROF_IS_VISUALIZER_GROUP (group));
|
||||
|
||||
if (SYSPROF_IS_VISUALIZER_GROUP (child))
|
||||
{
|
||||
SysprofVisualizerGroupHeader *header;
|
||||
const gchar *title = sysprof_visualizer_group_get_title (SYSPROF_VISUALIZER_GROUP (child));
|
||||
gint priority = sysprof_visualizer_group_get_priority (SYSPROF_VISUALIZER_GROUP (child));
|
||||
gint pos = find_pos (self, title, priority);
|
||||
title = sysprof_visualizer_group_get_title (group);
|
||||
priority = sysprof_visualizer_group_get_priority (group);
|
||||
pos = find_pos (self, title, priority);
|
||||
|
||||
gtk_list_box_insert (self->visualizers, child, pos);
|
||||
gtk_list_box_insert (self->visualizers, GTK_WIDGET (group), pos);
|
||||
|
||||
header = _sysprof_visualizer_group_header_new ();
|
||||
g_object_set_data (G_OBJECT (header), "VISUALIZER_GROUP", child);
|
||||
gtk_list_box_insert (self->groups, GTK_WIDGET (header), pos);
|
||||
_sysprof_visualizer_group_set_header (SYSPROF_VISUALIZER_GROUP (child), header);
|
||||
gtk_widget_show (GTK_WIDGET (header));
|
||||
header = _sysprof_visualizer_group_header_new ();
|
||||
g_object_set_data (G_OBJECT (header), "VISUALIZER_GROUP", group);
|
||||
gtk_list_box_insert (self->groups, GTK_WIDGET (header), pos);
|
||||
_sysprof_visualizer_group_set_header (group, header);
|
||||
gtk_widget_show (GTK_WIDGET (header));
|
||||
|
||||
sysprof_visualizers_frame_notify_zoom (self, NULL, self->zoom_manager);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
GTK_CONTAINER_CLASS (sysprof_visualizers_frame_parent_class)->add (container, child);
|
||||
sysprof_visualizers_frame_notify_zoom (self, NULL, self->zoom_manager);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -392,27 +374,17 @@ sysprof_visualizers_frame_group_activated_cb (SysprofVisualizersFrame *self
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_visualizers_frame_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *alloc)
|
||||
{
|
||||
SysprofVisualizersFrame *self = (SysprofVisualizersFrame *)widget;
|
||||
|
||||
g_assert (SYSPROF_IS_VISUALIZERS_FRAME (self));
|
||||
g_assert (alloc != NULL);
|
||||
|
||||
sysprof_scrollmap_set_time_range (self->hscrollbar, self->begin_time, self->end_time);
|
||||
|
||||
GTK_WIDGET_CLASS (sysprof_visualizers_frame_parent_class)->size_allocate (widget, alloc);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_visualizers_frame_finalize (GObject *object)
|
||||
sysprof_visualizers_frame_dispose (GObject *object)
|
||||
{
|
||||
SysprofVisualizersFrame *self = (SysprofVisualizersFrame *)object;
|
||||
GtkWidget *child;
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self))))
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
g_clear_object (&self->selection);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_visualizers_frame_parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (sysprof_visualizers_frame_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -443,16 +415,14 @@ sysprof_visualizers_frame_class_init (SysprofVisualizersFrameClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
|
||||
|
||||
object_class->finalize = sysprof_visualizers_frame_finalize;
|
||||
object_class->dispose = sysprof_visualizers_frame_dispose;
|
||||
object_class->get_property = sysprof_visualizers_frame_get_property;
|
||||
|
||||
widget_class->size_allocate = sysprof_visualizers_frame_size_allocate;
|
||||
|
||||
container_class->add = sysprof_visualizers_frame_add;
|
||||
widget_class->snapshot = sysprof_visualizers_frame_snapshot;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/sysprof/ui/sysprof-visualizers-frame.ui");
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
gtk_widget_class_set_css_name (widget_class, "SysprofVisualizersFrame");
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofVisualizersFrame, groups);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofVisualizersFrame, hscrollbar);
|
||||
@ -491,18 +461,43 @@ sysprof_visualizers_frame_class_init (SysprofVisualizersFrameClass *klass)
|
||||
static void
|
||||
sysprof_visualizers_frame_init (SysprofVisualizersFrame *self)
|
||||
{
|
||||
GtkEventController *controller;
|
||||
GtkAdjustment *hadj;
|
||||
GtkAdjustment *zadj;
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
gtk_widget_set_cursor_from_name (GTK_WIDGET (self->visualizers), "text");
|
||||
|
||||
controller = GTK_EVENT_CONTROLLER (gtk_gesture_click_new ());
|
||||
g_signal_connect_object (controller,
|
||||
"pressed",
|
||||
G_CALLBACK (visualizers_button_press_event_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (controller,
|
||||
"released",
|
||||
G_CALLBACK (visualizers_button_release_event_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_CAPTURE);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self->visualizers), controller);
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect_object (controller,
|
||||
"motion",
|
||||
G_CALLBACK (visualizers_motion_notify_event_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self->visualizers), controller);
|
||||
|
||||
self->selection = g_object_new (SYSPROF_TYPE_SELECTION, NULL);
|
||||
|
||||
zadj = sysprof_zoom_manager_get_adjustment (self->zoom_manager);
|
||||
hadj = gtk_scrolled_window_get_hadjustment (self->hscroller);
|
||||
|
||||
gtk_scrolled_window_set_hadjustment (self->ticks_scroller, hadj);
|
||||
gtk_range_set_adjustment (GTK_RANGE (self->hscrollbar), hadj);
|
||||
sysprof_scrollmap_set_adjustment (self->hscrollbar, hadj);
|
||||
gtk_range_set_adjustment (GTK_RANGE (self->zoom_scale), zadj);
|
||||
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (self),
|
||||
@ -521,36 +516,6 @@ sysprof_visualizers_frame_init (SysprofVisualizersFrame *self)
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
g_signal_connect_object (self->visualizers,
|
||||
"draw",
|
||||
G_CALLBACK (visualizers_draw_after_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED | G_CONNECT_AFTER);
|
||||
|
||||
g_signal_connect_object (self->visualizers,
|
||||
"realize",
|
||||
G_CALLBACK (visualizers_realize_after_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED | G_CONNECT_AFTER);
|
||||
|
||||
g_signal_connect_object (self->visualizers,
|
||||
"button-press-event",
|
||||
G_CALLBACK (visualizers_button_press_event_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
g_signal_connect_object (self->visualizers,
|
||||
"button-release-event",
|
||||
G_CALLBACK (visualizers_button_release_event_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
g_signal_connect_object (self->visualizers,
|
||||
"motion-notify-event",
|
||||
G_CALLBACK (visualizers_motion_notify_event_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
g_signal_connect_object (self->zoom_manager,
|
||||
"notify::zoom",
|
||||
G_CALLBACK (sysprof_visualizers_frame_notify_zoom),
|
||||
@ -745,7 +710,7 @@ sysprof_visualizers_frame_get_hadjustment (SysprofVisualizersFrame *self)
|
||||
{
|
||||
g_return_val_if_fail (SYSPROF_IS_VISUALIZERS_FRAME (self), NULL);
|
||||
|
||||
return gtk_range_get_adjustment (GTK_RANGE (self->hscrollbar));
|
||||
return sysprof_scrollmap_get_adjustment (self->hscrollbar);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -30,8 +30,10 @@ G_BEGIN_DECLS
|
||||
|
||||
#define SYSPROF_TYPE_VISUALIZERS_FRAME (sysprof_visualizers_frame_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (SysprofVisualizersFrame, sysprof_visualizers_frame, SYSPROF, VISUALIZERS_FRAME, GtkBin)
|
||||
G_DECLARE_FINAL_TYPE (SysprofVisualizersFrame, sysprof_visualizers_frame, SYSPROF, VISUALIZERS_FRAME, GtkWidget)
|
||||
|
||||
void sysprof_visualizers_frame_add_group (SysprofVisualizersFrame *self,
|
||||
SysprofVisualizerGroup *group);
|
||||
SysprofSelection *sysprof_visualizers_frame_get_selection (SysprofVisualizersFrame *self);
|
||||
SysprofVisualizerGroup *sysprof_visualizers_frame_get_selected_group (SysprofVisualizersFrame *self);
|
||||
SysprofZoomManager *sysprof_visualizers_frame_get_zoom_manager (SysprofVisualizersFrame *self);
|
||||
|
||||
@ -1,44 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.22"/>
|
||||
<template class="SysprofVisualizersFrame" parent="GtkBin">
|
||||
<property name="can_focus">False</property>
|
||||
<template class="SysprofVisualizersFrame" parent="GtkWidget">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="box1">
|
||||
<property name="width_request">125</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<object class="GtkCenterBox">
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="margin-top">3</property>
|
||||
<property name="margin-bottom">3</property>
|
||||
<property name="margin-start">7</property>
|
||||
<property name="margin-end">7</property>
|
||||
<property name="hexpand">false</property>
|
||||
<style>
|
||||
<class name="left-column"/>
|
||||
</style>
|
||||
<child type="center">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_start">6</property>
|
||||
<property name="margin_end">6</property>
|
||||
<property name="margin_top">3</property>
|
||||
<property name="margin_bottom">3</property>
|
||||
<property name="label" translatable="yes">Instruments</property>
|
||||
<property name="hexpand">true</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
@ -47,12 +34,11 @@
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<child type="end">
|
||||
<object class="GtkButton">
|
||||
<property name="action-name">display.page</property>
|
||||
<property name="action-target">'details'</property>
|
||||
<property name="tooltip-text" translatable="yes">Select for more details</property>
|
||||
<property name="visible">true</property>
|
||||
<style>
|
||||
<class name="image-button"/>
|
||||
<class name="small-button"/>
|
||||
@ -66,339 +52,170 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="ticks_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="vexpand">False</property>
|
||||
<property name="vexpand">false</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="ticks_scroller">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="hscrollbar_policy">external</property>
|
||||
<property name="vscrollbar_policy">never</property>
|
||||
<property name="hexpand">true</property>
|
||||
<property name="vexpand">true</property>
|
||||
<property name="hscrollbar-policy">external</property>
|
||||
<property name="vscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="GtkViewport" id="ticks_viewport">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<style>
|
||||
<class name="visualizers"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="SysprofVisualizerTicks" id="ticks">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="vscroller">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="propagate_natural_height">True</property>
|
||||
<property name="vexpand">true</property>
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="propagate-natural-height">true</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkListBox" id="groups">
|
||||
<property name="width_request">125</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">False</property>
|
||||
<property name="selection_mode">single</property>
|
||||
<property name="hexpand">false</property>
|
||||
<property name="selection-mode">single</property>
|
||||
<style>
|
||||
<class name="left-column"/>
|
||||
<class name="visualizer-groups"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="hscroller">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="hscrollbar_policy">external</property>
|
||||
<property name="vscrollbar_policy">never</property>
|
||||
<property name="propagate_natural_height">True</property>
|
||||
<property name="hexpand">true</property>
|
||||
<property name="hscrollbar-policy">external</property>
|
||||
<property name="vscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="GtkViewport" id="visualizers_viewport">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<property name="halign">start</property>
|
||||
<style>
|
||||
<class name="visualizers"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkListBox" id="visualizers">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="selection_mode">none</property>
|
||||
<property name="activate_on_single_click">False</property>
|
||||
<property name="activate_on_single_click">false</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<style>
|
||||
<class name="inline-toolbar"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkBox" id="box2">
|
||||
<property name="width_request">125</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin-end">6</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">False</property>
|
||||
<property name="hexpand">false</property>
|
||||
<style>
|
||||
<class name="left-column"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkButton" id="zoom_out">
|
||||
<property name="action-name">zoom.zoom-out</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">zoom-out-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
<property name="icon_name">zoom-out-symbolic</property>
|
||||
<style>
|
||||
<class name="image-button"/>
|
||||
<class name="small-button"/>
|
||||
<class name="flat"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale" id="zoom_scale">
|
||||
<property name="width_request">175</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="hexpand">true</property>
|
||||
<property name="round_digits">1</property>
|
||||
<property name="draw_value">False</property>
|
||||
<property name="draw_value">false</property>
|
||||
<marks>
|
||||
<mark value="0.0" position="bottom"/>
|
||||
</marks>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="zoom_in">
|
||||
<property name="action-name">zoom.zoom-in</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">zoom-in-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
<property name="icon-name">zoom-in-symbolic</property>
|
||||
<style>
|
||||
<class name="image-button"/>
|
||||
<class name="small-button"/>
|
||||
<class name="flat"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="SysprofScrollmap" id="hscrollbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="hexpand">true</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
sysprof_header_subdir = 'sysprof-@0@'.format(libsysprof_api_version)
|
||||
sysprof_ui_header_subdir = 'sysprof-ui-@0@'.format(libsysprof_ui_api_version)
|
||||
|
||||
sysprof_version_conf = configuration_data()
|
||||
sysprof_version = meson.project_version().split('.')
|
||||
|
||||
639
src/sysprof/egg-binding-group.c
Normal file
639
src/sysprof/egg-binding-group.c
Normal file
@ -0,0 +1,639 @@
|
||||
/* egg-binding-group.c
|
||||
*
|
||||
* Copyright (C) 2015 Christian Hergert <christian@hergert.me>
|
||||
* Copyright (C) 2015 Garrett Regier <garrettregier@gmail.com>
|
||||
*
|
||||
* This file 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 file 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "egg-binding-group.h"
|
||||
|
||||
/**
|
||||
* SECTION:eggbindinggroup
|
||||
* @title: EggBindingGroup
|
||||
* @short_description: Manage a collection of #GBindings on
|
||||
* a #GObject as a group.
|
||||
*
|
||||
* #EggBindingGroup manages to simplify the process of binding
|
||||
* many properties from a #GObject as a group. As such there is no API
|
||||
* to unbind a property from the group.
|
||||
*
|
||||
* In particular, this allows you to change the source instance for the
|
||||
* bindings. This automatically causes the unbinding of the properties
|
||||
* from the old instance and binding to the new instance.
|
||||
*
|
||||
* This should not be confused with #GtkBindingGroup.
|
||||
*/
|
||||
|
||||
struct _EggBindingGroup
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GObject *source;
|
||||
GPtrArray *lazy_bindings;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
EggBindingGroup *group;
|
||||
const gchar *source_property;
|
||||
const gchar *target_property;
|
||||
GObject *target;
|
||||
GBinding *binding;
|
||||
gpointer user_data;
|
||||
GDestroyNotify user_data_destroy;
|
||||
gpointer transform_to;
|
||||
gpointer transform_from;
|
||||
GBindingFlags binding_flags;
|
||||
guint using_closures : 1;
|
||||
} LazyBinding;
|
||||
|
||||
G_DEFINE_TYPE (EggBindingGroup, egg_binding_group, G_TYPE_OBJECT)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_SOURCE,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static GParamSpec *properties [LAST_PROP];
|
||||
|
||||
/*#define DEBUG_BINDINGS 1*/
|
||||
|
||||
#ifdef DEBUG_BINDINGS
|
||||
static gchar *
|
||||
_g_flags_to_string (GFlagsClass *flags_class,
|
||||
guint value)
|
||||
{
|
||||
GString *str;
|
||||
GFlagsValue *flags_value;
|
||||
gboolean first = TRUE;
|
||||
|
||||
str = g_string_new (NULL);
|
||||
|
||||
while ((first || value != 0) &&
|
||||
(flags_value = g_flags_get_first_value (flags_class, value)) != NULL)
|
||||
{
|
||||
if (!first)
|
||||
g_string_append (str, " | ");
|
||||
|
||||
g_string_append (str, flags_value->value_name);
|
||||
|
||||
first = FALSE;
|
||||
value &= ~(flags_value->value);
|
||||
}
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
egg_binding_group_connect (EggBindingGroup *self,
|
||||
LazyBinding *lazy_binding)
|
||||
{
|
||||
GBinding *binding;
|
||||
|
||||
g_assert (EGG_IS_BINDING_GROUP (self));
|
||||
g_assert (self->source != NULL);
|
||||
g_assert (lazy_binding != NULL);
|
||||
g_assert (lazy_binding->binding == NULL);
|
||||
g_assert (lazy_binding->target != NULL);
|
||||
g_assert (lazy_binding->target_property != NULL);
|
||||
g_assert (lazy_binding->source_property != NULL);
|
||||
|
||||
#ifdef DEBUG_BINDINGS
|
||||
{
|
||||
GFlagsClass *flags_class;
|
||||
g_autofree gchar *flags_str = NULL;
|
||||
|
||||
flags_class = g_type_class_ref (G_TYPE_BINDING_FLAGS);
|
||||
flags_str = _g_flags_to_string (flags_class,
|
||||
lazy_binding->binding_flags);
|
||||
|
||||
g_print ("Binding %s(%p):%s to %s(%p):%s (flags=%s)\n",
|
||||
G_OBJECT_TYPE_NAME (self->source),
|
||||
self->source,
|
||||
lazy_binding->source_property,
|
||||
G_OBJECT_TYPE_NAME (lazy_binding->target),
|
||||
lazy_binding->target,
|
||||
lazy_binding->target_property,
|
||||
flags_str);
|
||||
|
||||
g_type_class_unref (flags_class);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!lazy_binding->using_closures)
|
||||
{
|
||||
binding = g_object_bind_property_full (self->source,
|
||||
lazy_binding->source_property,
|
||||
lazy_binding->target,
|
||||
lazy_binding->target_property,
|
||||
lazy_binding->binding_flags,
|
||||
lazy_binding->transform_to,
|
||||
lazy_binding->transform_from,
|
||||
lazy_binding->user_data,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
binding = g_object_bind_property_with_closures (self->source,
|
||||
lazy_binding->source_property,
|
||||
lazy_binding->target,
|
||||
lazy_binding->target_property,
|
||||
lazy_binding->binding_flags,
|
||||
lazy_binding->transform_to,
|
||||
lazy_binding->transform_from);
|
||||
}
|
||||
|
||||
lazy_binding->binding = binding;
|
||||
}
|
||||
|
||||
static void
|
||||
egg_binding_group_disconnect (LazyBinding *lazy_binding)
|
||||
{
|
||||
g_assert (lazy_binding != NULL);
|
||||
|
||||
if (lazy_binding->binding != NULL)
|
||||
{
|
||||
g_binding_unbind (lazy_binding->binding);
|
||||
lazy_binding->binding = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
egg_binding_group__source_weak_notify (gpointer data,
|
||||
GObject *where_object_was)
|
||||
{
|
||||
EggBindingGroup *self = data;
|
||||
gsize i;
|
||||
|
||||
g_assert (EGG_IS_BINDING_GROUP (self));
|
||||
|
||||
self->source = NULL;
|
||||
|
||||
for (i = 0; i < self->lazy_bindings->len; i++)
|
||||
{
|
||||
LazyBinding *lazy_binding;
|
||||
|
||||
lazy_binding = g_ptr_array_index (self->lazy_bindings, i);
|
||||
lazy_binding->binding = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
egg_binding_group__target_weak_notify (gpointer data,
|
||||
GObject *where_object_was)
|
||||
{
|
||||
EggBindingGroup *self = data;
|
||||
gsize i;
|
||||
|
||||
g_assert (EGG_IS_BINDING_GROUP (self));
|
||||
|
||||
for (i = 0; i < self->lazy_bindings->len; i++)
|
||||
{
|
||||
LazyBinding *lazy_binding;
|
||||
|
||||
lazy_binding = g_ptr_array_index (self->lazy_bindings, i);
|
||||
|
||||
if (lazy_binding->target == where_object_was)
|
||||
{
|
||||
lazy_binding->target = NULL;
|
||||
lazy_binding->binding = NULL;
|
||||
|
||||
g_ptr_array_remove_index_fast (self->lazy_bindings, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
lazy_binding_free (gpointer data)
|
||||
{
|
||||
LazyBinding *lazy_binding = data;
|
||||
|
||||
if (lazy_binding->target != NULL)
|
||||
{
|
||||
g_object_weak_unref (lazy_binding->target,
|
||||
egg_binding_group__target_weak_notify,
|
||||
lazy_binding->group);
|
||||
lazy_binding->target = NULL;
|
||||
}
|
||||
|
||||
egg_binding_group_disconnect (lazy_binding);
|
||||
|
||||
lazy_binding->group = NULL;
|
||||
lazy_binding->source_property = NULL;
|
||||
lazy_binding->target_property = NULL;
|
||||
|
||||
if (lazy_binding->user_data_destroy)
|
||||
lazy_binding->user_data_destroy (lazy_binding->user_data);
|
||||
|
||||
if (lazy_binding->using_closures)
|
||||
{
|
||||
g_clear_pointer (&lazy_binding->transform_to, g_closure_unref);
|
||||
g_clear_pointer (&lazy_binding->transform_from, g_closure_unref);
|
||||
}
|
||||
|
||||
g_slice_free (LazyBinding, lazy_binding);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_binding_group_dispose (GObject *object)
|
||||
{
|
||||
EggBindingGroup *self = (EggBindingGroup *)object;
|
||||
|
||||
g_assert (EGG_IS_BINDING_GROUP (self));
|
||||
|
||||
if (self->source != NULL)
|
||||
{
|
||||
g_object_weak_unref (self->source,
|
||||
egg_binding_group__source_weak_notify,
|
||||
self);
|
||||
self->source = NULL;
|
||||
}
|
||||
|
||||
if (self->lazy_bindings->len != 0)
|
||||
g_ptr_array_remove_range (self->lazy_bindings, 0, self->lazy_bindings->len);
|
||||
|
||||
G_OBJECT_CLASS (egg_binding_group_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_binding_group_finalize (GObject *object)
|
||||
{
|
||||
EggBindingGroup *self = (EggBindingGroup *)object;
|
||||
|
||||
g_assert (self->lazy_bindings != NULL);
|
||||
g_assert (self->lazy_bindings->len == 0);
|
||||
|
||||
g_clear_pointer (&self->lazy_bindings, g_ptr_array_unref);
|
||||
|
||||
G_OBJECT_CLASS (egg_binding_group_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_binding_group_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EggBindingGroup *self = EGG_BINDING_GROUP (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SOURCE:
|
||||
g_value_set_object (value, egg_binding_group_get_source (self));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
egg_binding_group_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EggBindingGroup *self = EGG_BINDING_GROUP (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SOURCE:
|
||||
egg_binding_group_set_source (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
egg_binding_group_class_init (EggBindingGroupClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = egg_binding_group_dispose;
|
||||
object_class->finalize = egg_binding_group_finalize;
|
||||
object_class->get_property = egg_binding_group_get_property;
|
||||
object_class->set_property = egg_binding_group_set_property;
|
||||
|
||||
/**
|
||||
* EggBindingGroup:source
|
||||
*
|
||||
* The source object used for binding properties.
|
||||
*/
|
||||
properties [PROP_SOURCE] =
|
||||
g_param_spec_object ("source",
|
||||
"Source",
|
||||
"The source GObject used for binding properties.",
|
||||
G_TYPE_OBJECT,
|
||||
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_binding_group_init (EggBindingGroup *self)
|
||||
{
|
||||
self->lazy_bindings = g_ptr_array_new_with_free_func (lazy_binding_free);
|
||||
}
|
||||
|
||||
/**
|
||||
* egg_binding_group_new:
|
||||
*
|
||||
* Creates a new #EggBindingGroup.
|
||||
*
|
||||
* Returns: a new #EggBindingGroup
|
||||
*/
|
||||
EggBindingGroup *
|
||||
egg_binding_group_new (void)
|
||||
{
|
||||
return g_object_new (EGG_TYPE_BINDING_GROUP, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* egg_binding_group_get_source:
|
||||
* @self: the #EggBindingGroup
|
||||
*
|
||||
* Gets the source object used for binding properties.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the source object.
|
||||
*/
|
||||
GObject *
|
||||
egg_binding_group_get_source (EggBindingGroup *self)
|
||||
{
|
||||
g_return_val_if_fail (EGG_IS_BINDING_GROUP (self), NULL);
|
||||
|
||||
return self->source;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
egg_binding_group_check_source (EggBindingGroup *self,
|
||||
gpointer source)
|
||||
{
|
||||
gsize i;
|
||||
|
||||
for (i = 0; i < self->lazy_bindings->len; i++)
|
||||
{
|
||||
LazyBinding *lazy_binding;
|
||||
|
||||
lazy_binding = g_ptr_array_index (self->lazy_bindings, i);
|
||||
|
||||
g_return_val_if_fail (g_object_class_find_property (G_OBJECT_GET_CLASS (source),
|
||||
lazy_binding->source_property) != NULL,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* egg_binding_group_set_source:
|
||||
* @self: the #EggBindingGroup
|
||||
* @source: (type GObject) (nullable): the source #GObject
|
||||
*
|
||||
* Sets @source as the source object used for creating property
|
||||
* bindings. If there is already a source object all bindings from it
|
||||
* will be removed.
|
||||
*
|
||||
* Note: All properties that have been bound must exist on @source.
|
||||
*/
|
||||
void
|
||||
egg_binding_group_set_source (EggBindingGroup *self,
|
||||
gpointer source)
|
||||
{
|
||||
g_return_if_fail (EGG_IS_BINDING_GROUP (self));
|
||||
g_return_if_fail (!source || G_IS_OBJECT (source));
|
||||
g_return_if_fail (source != (gpointer)self);
|
||||
|
||||
if (source == (gpointer)self->source)
|
||||
return;
|
||||
|
||||
if (self->source != NULL)
|
||||
{
|
||||
gsize i;
|
||||
|
||||
g_object_weak_unref (self->source,
|
||||
egg_binding_group__source_weak_notify,
|
||||
self);
|
||||
self->source = NULL;
|
||||
|
||||
for (i = 0; i < self->lazy_bindings->len; i++)
|
||||
{
|
||||
LazyBinding *lazy_binding;
|
||||
|
||||
lazy_binding = g_ptr_array_index (self->lazy_bindings, i);
|
||||
egg_binding_group_disconnect (lazy_binding);
|
||||
}
|
||||
}
|
||||
|
||||
if (source != NULL && egg_binding_group_check_source (self, source))
|
||||
{
|
||||
gsize i;
|
||||
|
||||
self->source = source;
|
||||
g_object_weak_ref (self->source,
|
||||
egg_binding_group__source_weak_notify,
|
||||
self);
|
||||
|
||||
for (i = 0; i < self->lazy_bindings->len; i++)
|
||||
{
|
||||
LazyBinding *lazy_binding;
|
||||
|
||||
lazy_binding = g_ptr_array_index (self->lazy_bindings, i);
|
||||
egg_binding_group_connect (self, lazy_binding);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_SOURCE]);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_binding_group_bind_helper (EggBindingGroup *self,
|
||||
const gchar *source_property,
|
||||
gpointer target,
|
||||
const gchar *target_property,
|
||||
GBindingFlags flags,
|
||||
gpointer transform_to,
|
||||
gpointer transform_from,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_data_destroy,
|
||||
gboolean using_closures)
|
||||
{
|
||||
LazyBinding *lazy_binding;
|
||||
|
||||
g_return_if_fail (EGG_IS_BINDING_GROUP (self));
|
||||
g_return_if_fail (source_property != NULL);
|
||||
g_return_if_fail (self->source == NULL ||
|
||||
g_object_class_find_property (G_OBJECT_GET_CLASS (self->source),
|
||||
source_property) != NULL);
|
||||
g_return_if_fail (G_IS_OBJECT (target));
|
||||
g_return_if_fail (target_property != NULL);
|
||||
g_return_if_fail (g_object_class_find_property (G_OBJECT_GET_CLASS (target),
|
||||
target_property) != NULL);
|
||||
g_return_if_fail (target != (gpointer)self ||
|
||||
strcmp (source_property, target_property) != 0);
|
||||
|
||||
lazy_binding = g_slice_new0 (LazyBinding);
|
||||
lazy_binding->group = self;
|
||||
lazy_binding->source_property = g_intern_string (source_property);
|
||||
lazy_binding->target_property = g_intern_string (target_property);
|
||||
lazy_binding->target = target;
|
||||
lazy_binding->binding_flags = flags | G_BINDING_SYNC_CREATE;
|
||||
lazy_binding->user_data = user_data;
|
||||
lazy_binding->user_data_destroy = user_data_destroy;
|
||||
lazy_binding->transform_to = transform_to;
|
||||
lazy_binding->transform_from = transform_from;
|
||||
|
||||
if (using_closures)
|
||||
{
|
||||
lazy_binding->using_closures = TRUE;
|
||||
|
||||
if (transform_to != NULL)
|
||||
g_closure_sink (g_closure_ref (transform_to));
|
||||
|
||||
if (transform_from != NULL)
|
||||
g_closure_sink (g_closure_ref (transform_from));
|
||||
}
|
||||
|
||||
g_object_weak_ref (target,
|
||||
egg_binding_group__target_weak_notify,
|
||||
self);
|
||||
|
||||
g_ptr_array_add (self->lazy_bindings, lazy_binding);
|
||||
|
||||
if (self->source != NULL)
|
||||
egg_binding_group_connect (self, lazy_binding);
|
||||
}
|
||||
|
||||
/**
|
||||
* egg_binding_group_bind:
|
||||
* @self: the #EggBindingGroup
|
||||
* @source_property: the property on the source to bind
|
||||
* @target: (type GObject): the target #GObject
|
||||
* @target_property: the property on @target to bind
|
||||
* @flags: the flags used to create the #GBinding
|
||||
*
|
||||
* Creates a binding between @source_property on the source object
|
||||
* and @target_property on @target. Whenever the @source_property
|
||||
* is changed the @target_property is updated using the same value.
|
||||
* The binding flags #G_BINDING_SYNC_CREATE is automatically specified.
|
||||
*
|
||||
* See: g_object_bind_property().
|
||||
*/
|
||||
void
|
||||
egg_binding_group_bind (EggBindingGroup *self,
|
||||
const gchar *source_property,
|
||||
gpointer target,
|
||||
const gchar *target_property,
|
||||
GBindingFlags flags)
|
||||
{
|
||||
egg_binding_group_bind_full (self, source_property,
|
||||
target, target_property,
|
||||
flags,
|
||||
NULL, NULL,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* egg_binding_group_bind_full:
|
||||
* @self: the #EggBindingGroup
|
||||
* @source_property: the property on the source to bind
|
||||
* @target: (type GObject): the target #GObject
|
||||
* @target_property: the property on @target to bind
|
||||
* @flags: the flags used to create the #GBinding
|
||||
* @transform_to: (scope notified) (nullable): the transformation function
|
||||
* from the source object to the @target, or %NULL to use the default
|
||||
* @transform_from: (scope notified) (nullable): the transformation function
|
||||
* from the @target to the source object, or %NULL to use the default
|
||||
* @user_data: custom data to be passed to the transformation
|
||||
* functions, or %NULL
|
||||
* @user_data_destroy: function to be called when disposing the binding,
|
||||
* to free the resources used by the transformation functions
|
||||
*
|
||||
* Creates a binding between @source_property on the source object and
|
||||
* @target_property on @target, allowing you to set the transformation
|
||||
* functions to be used by the binding. The binding flags
|
||||
* #G_BINDING_SYNC_CREATE is automatically specified.
|
||||
*
|
||||
* See: g_object_bind_property_full().
|
||||
*/
|
||||
void
|
||||
egg_binding_group_bind_full (EggBindingGroup *self,
|
||||
const gchar *source_property,
|
||||
gpointer target,
|
||||
const gchar *target_property,
|
||||
GBindingFlags flags,
|
||||
GBindingTransformFunc transform_to,
|
||||
GBindingTransformFunc transform_from,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_data_destroy)
|
||||
{
|
||||
egg_binding_group_bind_helper (self, source_property,
|
||||
target, target_property,
|
||||
flags,
|
||||
transform_to, transform_from,
|
||||
user_data, user_data_destroy,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* egg_binding_group_bind_with_closures: (rename-to egg_binding_group_bind_full)
|
||||
* @self: the #EggBindingGroup
|
||||
* @source_property: the property on the source to bind
|
||||
* @target: (type GObject): the target #GObject
|
||||
* @target_property: the property on @target to bind
|
||||
* @flags: the flags used to create the #GBinding
|
||||
* @transform_to: (nullable): a #GClosure wrapping the
|
||||
* transformation function from the source object to the @target,
|
||||
* or %NULL to use the default
|
||||
* @transform_from: (nullable): a #GClosure wrapping the
|
||||
* transformation function from the @target to the source object,
|
||||
* or %NULL to use the default
|
||||
*
|
||||
* Creates a binding between @source_property on the source object and
|
||||
* @target_property on @target, allowing you to set the transformation
|
||||
* functions to be used by the binding. The binding flags
|
||||
* #G_BINDING_SYNC_CREATE is automatically specified.
|
||||
*
|
||||
* This function is the language bindings friendly version of
|
||||
* egg_binding_group_bind_property_full(), using #GClosures
|
||||
* instead of function pointers.
|
||||
*
|
||||
* See: g_object_bind_property_with_closures().
|
||||
*/
|
||||
void
|
||||
egg_binding_group_bind_with_closures (EggBindingGroup *self,
|
||||
const gchar *source_property,
|
||||
gpointer target,
|
||||
const gchar *target_property,
|
||||
GBindingFlags flags,
|
||||
GClosure *transform_to,
|
||||
GClosure *transform_from)
|
||||
{
|
||||
egg_binding_group_bind_helper (self, source_property,
|
||||
target, target_property,
|
||||
flags,
|
||||
transform_to, transform_from,
|
||||
NULL, NULL,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
57
src/sysprof/egg-binding-group.h
Normal file
57
src/sysprof/egg-binding-group.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* egg-binding-group.h
|
||||
*
|
||||
* Copyright (C) 2015 Christian Hergert <christian@hergert.me>
|
||||
* Copyright (C) 2015 Garrett Regier <garrettregier@gmail.com>
|
||||
*
|
||||
* This file 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 file 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 General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EGG_TYPE_BINDING_GROUP (egg_binding_group_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (EggBindingGroup, egg_binding_group, EGG, BINDING_GROUP, GObject)
|
||||
|
||||
EggBindingGroup *egg_binding_group_new (void);
|
||||
GObject *egg_binding_group_get_source (EggBindingGroup *self);
|
||||
void egg_binding_group_set_source (EggBindingGroup *self,
|
||||
gpointer source);
|
||||
void egg_binding_group_bind (EggBindingGroup *self,
|
||||
const gchar *source_property,
|
||||
gpointer target,
|
||||
const gchar *target_property,
|
||||
GBindingFlags flags);
|
||||
void egg_binding_group_bind_full (EggBindingGroup *self,
|
||||
const gchar *source_property,
|
||||
gpointer target,
|
||||
const gchar *target_property,
|
||||
GBindingFlags flags,
|
||||
GBindingTransformFunc transform_to,
|
||||
GBindingTransformFunc transform_from,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_data_destroy);
|
||||
void egg_binding_group_bind_with_closures (EggBindingGroup *self,
|
||||
const gchar *source_property,
|
||||
gpointer target,
|
||||
const gchar *target_property,
|
||||
GBindingFlags flags,
|
||||
GClosure *transform_to,
|
||||
GClosure *transform_from);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
if get_option('enable_gtk') and get_option('libsysprof')
|
||||
|
||||
sysprof_sources = [
|
||||
'egg-binding-group.c',
|
||||
'sysprof.c',
|
||||
'sysprof-application.c',
|
||||
'sysprof-window.c',
|
||||
'sysprof-window-settings.c',
|
||||
]
|
||||
|
||||
sysprof_resources = gnome.compile_resources('sysprof-resources', 'sysprof.gresource.xml',
|
||||
@ -18,6 +18,7 @@ sysprof_deps = [
|
||||
libsysprof_dep,
|
||||
libsysprof_ui_dep,
|
||||
dependency('pangoft2', required: false),
|
||||
dependency('libadwaita-1'),
|
||||
]
|
||||
|
||||
sysprof = executable('sysprof', sysprof_resources + sysprof_sources,
|
||||
|
||||
@ -27,10 +27,10 @@
|
||||
|
||||
struct _SysprofApplication
|
||||
{
|
||||
DzlApplication parent_instance;
|
||||
AdwApplication parent_instance;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (SysprofApplication, sysprof_application, DZL_TYPE_APPLICATION)
|
||||
G_DEFINE_TYPE (SysprofApplication, sysprof_application, ADW_TYPE_APPLICATION)
|
||||
|
||||
struct {
|
||||
const gchar *action_name;
|
||||
@ -110,9 +110,6 @@ static void
|
||||
sysprof_application_startup (GApplication *application)
|
||||
{
|
||||
g_autoptr(GtkCssProvider) provider = NULL;
|
||||
#ifdef DEVELOPMENT_BUILD
|
||||
g_autoptr(GtkCssProvider) adwaita = NULL;
|
||||
#endif
|
||||
|
||||
g_assert (SYSPROF_IS_APPLICATION (application));
|
||||
|
||||
@ -120,17 +117,9 @@ sysprof_application_startup (GApplication *application)
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider, "/org/gnome/sysprof/theme/shared.css");
|
||||
gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
#ifdef DEVELOPMENT_BUILD
|
||||
adwaita = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (adwaita, "/org/gnome/sysprof/theme/Adwaita-shared.css");
|
||||
gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
|
||||
GTK_STYLE_PROVIDER (adwaita),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
#endif
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_THEME+1);
|
||||
|
||||
for (guint i = 0; default_accels[i].action_name; i++)
|
||||
gtk_application_set_accels_for_action (GTK_APPLICATION (application),
|
||||
@ -138,14 +127,31 @@ sysprof_application_startup (GApplication *application)
|
||||
default_accels[i].accels);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_application_window_added (GtkApplication *application,
|
||||
GtkWindow *window)
|
||||
{
|
||||
g_assert (SYSPROF_IS_APPLICATION (application));
|
||||
g_assert (GTK_IS_WINDOW (window));
|
||||
|
||||
#ifdef DEVELOPMENT_BUILD
|
||||
gtk_widget_add_css_class (GTK_WIDGET (window), "devel");
|
||||
#endif
|
||||
|
||||
GTK_APPLICATION_CLASS (sysprof_application_parent_class)->window_added (application, window);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_application_class_init (SysprofApplicationClass *klass)
|
||||
{
|
||||
GApplicationClass *app_class = G_APPLICATION_CLASS (klass);
|
||||
GtkApplicationClass *gtk_app_class = GTK_APPLICATION_CLASS (klass);
|
||||
|
||||
app_class->open = sysprof_application_open;
|
||||
app_class->startup = sysprof_application_startup;
|
||||
app_class->activate = sysprof_application_activate;
|
||||
|
||||
gtk_app_class->window_added = sysprof_application_window_added;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -206,8 +212,8 @@ sysprof_about (GSimpleAction *action,
|
||||
NULL);
|
||||
|
||||
g_signal_connect (dialog,
|
||||
"response",
|
||||
G_CALLBACK (gtk_widget_destroy),
|
||||
"close-request",
|
||||
G_CALLBACK (gtk_window_destroy),
|
||||
NULL);
|
||||
|
||||
gtk_window_present (dialog);
|
||||
@ -226,10 +232,7 @@ sysprof_help (GSimpleAction *action,
|
||||
|
||||
window = gtk_application_get_active_window (GTK_APPLICATION (self));
|
||||
|
||||
gtk_show_uri_on_window (window,
|
||||
"help:sysprof",
|
||||
gtk_get_current_event_time (),
|
||||
NULL);
|
||||
gtk_show_uri (window, "help:sysprof", GDK_CURRENT_TIME);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@ -18,13 +18,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <dazzle.h>
|
||||
#include <adwaita.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define SYSPROF_TYPE_APPLICATION (sysprof_application_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (SysprofApplication, sysprof_application, SYSPROF, APPLICATION, DzlApplication)
|
||||
G_DECLARE_FINAL_TYPE (SysprofApplication, sysprof_application, SYSPROF, APPLICATION, AdwApplication)
|
||||
|
||||
SysprofApplication *sysprof_application_new (void);
|
||||
|
||||
|
||||
@ -1,175 +0,0 @@
|
||||
/* sysprof-window-settings.c
|
||||
*
|
||||
* Copyright 2016 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sysprof-window.h"
|
||||
#include "sysprof-window-settings.h"
|
||||
|
||||
#define WINDOW_MIN_WIDTH 1200
|
||||
#define WINDOW_MIN_HEIGHT 700
|
||||
#define SAVE_TIMEOUT_SECS 1
|
||||
|
||||
static GSettings *settings;
|
||||
|
||||
static gboolean
|
||||
sysprof_window_settings__window_save_settings_cb (gpointer data)
|
||||
{
|
||||
GtkWindow *window = data;
|
||||
GdkRectangle geom;
|
||||
gboolean maximized;
|
||||
|
||||
g_assert (GTK_IS_WINDOW (window));
|
||||
g_assert (G_IS_SETTINGS (settings));
|
||||
|
||||
g_object_set_data (G_OBJECT (window), "SETTINGS_HANDLER_ID", NULL);
|
||||
|
||||
gtk_window_get_size (window, &geom.width, &geom.height);
|
||||
gtk_window_get_position (window, &geom.x, &geom.y);
|
||||
maximized = gtk_window_is_maximized (window);
|
||||
|
||||
g_settings_set (settings, "window-size", "(ii)", geom.width, geom.height);
|
||||
g_settings_set (settings, "window-position", "(ii)", geom.x, geom.y);
|
||||
g_settings_set_boolean (settings, "window-maximized", maximized);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sysprof_window_settings__window_configure_event (GtkWindow *window,
|
||||
GdkEventConfigure *event)
|
||||
{
|
||||
guint handler;
|
||||
|
||||
g_assert (GTK_IS_WINDOW (window));
|
||||
g_assert (event != NULL);
|
||||
g_assert (G_IS_SETTINGS (settings));
|
||||
|
||||
handler = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "SETTINGS_HANDLER_ID"));
|
||||
|
||||
if (handler == 0)
|
||||
{
|
||||
handler = g_timeout_add_seconds (SAVE_TIMEOUT_SECS,
|
||||
sysprof_window_settings__window_save_settings_cb,
|
||||
window);
|
||||
g_object_set_data (G_OBJECT (window), "SETTINGS_HANDLER_ID", GINT_TO_POINTER (handler));
|
||||
}
|
||||
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_window_settings__window_realize (GtkWindow *window)
|
||||
{
|
||||
GtkApplication *app;
|
||||
GdkRectangle geom = { 0 };
|
||||
gboolean maximized = FALSE;
|
||||
GList *list;
|
||||
guint count = 0;
|
||||
|
||||
g_assert (GTK_IS_WINDOW (window));
|
||||
g_assert (G_IS_SETTINGS (settings));
|
||||
|
||||
g_settings_get (settings, "window-position", "(ii)", &geom.x, &geom.y);
|
||||
g_settings_get (settings, "window-size", "(ii)", &geom.width, &geom.height);
|
||||
g_settings_get (settings, "window-maximized", "b", &maximized);
|
||||
|
||||
geom.width = MAX (geom.width, WINDOW_MIN_WIDTH);
|
||||
geom.height = MAX (geom.height, WINDOW_MIN_HEIGHT);
|
||||
gtk_window_set_default_size (window, geom.width, geom.height);
|
||||
|
||||
/*
|
||||
* If there are other windows currently visible other than this one,
|
||||
* then ignore positioning and let the window manager decide.
|
||||
*/
|
||||
count = 0;
|
||||
app = GTK_APPLICATION (g_application_get_default ());
|
||||
list = gtk_application_get_windows (app);
|
||||
for (; list != NULL; list = list->next)
|
||||
{
|
||||
GtkWindow *ele = list->data;
|
||||
|
||||
if (SYSPROF_IS_WINDOW (ele) && (ele != window) &&
|
||||
gtk_widget_get_visible (GTK_WIDGET (window)))
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
gtk_window_move (window, geom.x, geom.y);
|
||||
|
||||
if (maximized)
|
||||
gtk_window_maximize (window);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_window_settings__window_destroy (GtkWindow *window)
|
||||
{
|
||||
guint handler;
|
||||
|
||||
g_assert (GTK_IS_WINDOW (window));
|
||||
g_assert (G_IS_SETTINGS (settings));
|
||||
|
||||
handler = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "SETTINGS_HANDLER_ID"));
|
||||
|
||||
if (handler != 0)
|
||||
{
|
||||
g_source_remove (handler);
|
||||
g_object_set_data (G_OBJECT (window), "SETTINGS_HANDLER_ID", NULL);
|
||||
}
|
||||
|
||||
g_signal_handlers_disconnect_by_func (window,
|
||||
G_CALLBACK (sysprof_window_settings__window_configure_event),
|
||||
NULL);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (window,
|
||||
G_CALLBACK (sysprof_window_settings__window_destroy),
|
||||
NULL);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (window,
|
||||
G_CALLBACK (sysprof_window_settings__window_realize),
|
||||
NULL);
|
||||
|
||||
g_object_unref (settings);
|
||||
}
|
||||
|
||||
void
|
||||
sysprof_window_settings_register (GtkWindow *window)
|
||||
{
|
||||
if (settings == NULL)
|
||||
{
|
||||
settings = g_settings_new ("org.gnome.sysprof3");
|
||||
g_object_add_weak_pointer (G_OBJECT (settings), (gpointer *)&settings);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_object_ref (settings);
|
||||
}
|
||||
|
||||
g_signal_connect (window,
|
||||
"configure-event",
|
||||
G_CALLBACK (sysprof_window_settings__window_configure_event),
|
||||
NULL);
|
||||
|
||||
g_signal_connect (window,
|
||||
"destroy",
|
||||
G_CALLBACK (sysprof_window_settings__window_destroy),
|
||||
NULL);
|
||||
|
||||
g_signal_connect (window,
|
||||
"realize",
|
||||
G_CALLBACK (sysprof_window_settings__window_realize),
|
||||
NULL);
|
||||
}
|
||||
@ -25,20 +25,22 @@
|
||||
#include <glib/gi18n.h>
|
||||
#include <sysprof-ui.h>
|
||||
|
||||
#include "egg-binding-group.h"
|
||||
|
||||
#include "sysprof-window.h"
|
||||
|
||||
struct _SysprofWindow
|
||||
{
|
||||
DzlApplicationWindow parent_instance;
|
||||
AdwApplicationWindow parent_instance;
|
||||
|
||||
DzlBindingGroup *bindings;
|
||||
EggBindingGroup *bindings;
|
||||
|
||||
SysprofNotebook *notebook;
|
||||
GtkButton *open_button;
|
||||
GtkMenuButton *menu_button;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (SysprofWindow, sysprof_window, DZL_TYPE_APPLICATION_WINDOW)
|
||||
G_DEFINE_TYPE (SysprofWindow, sysprof_window, ADW_TYPE_APPLICATION_WINDOW)
|
||||
|
||||
/**
|
||||
* sysprof_window_new:
|
||||
@ -63,9 +65,11 @@ sysprof_window_notify_can_replay_cb (SysprofWindow *self,
|
||||
g_assert (SYSPROF_IS_WINDOW (self));
|
||||
g_assert (SYSPROF_IS_NOTEBOOK (notebook));
|
||||
|
||||
#if 0
|
||||
dzl_gtk_widget_action_set (GTK_WIDGET (self), "win", "replay-capture",
|
||||
"enabled", sysprof_notebook_get_can_replay (notebook),
|
||||
NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@ -76,9 +80,11 @@ sysprof_window_notify_can_save_cb (SysprofWindow *self,
|
||||
g_assert (SYSPROF_IS_WINDOW (self));
|
||||
g_assert (SYSPROF_IS_NOTEBOOK (notebook));
|
||||
|
||||
#if 0
|
||||
dzl_gtk_widget_action_set (GTK_WIDGET (self), "win", "save-capture",
|
||||
"enabled", sysprof_notebook_get_can_save (notebook),
|
||||
NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@ -105,7 +111,7 @@ switch_tab_cb (GSimpleAction *action,
|
||||
g_return_if_fail (g_variant_is_of_type (param, G_VARIANT_TYPE_INT32));
|
||||
|
||||
page = g_variant_get_int32 (param);
|
||||
gtk_notebook_set_current_page (GTK_NOTEBOOK (self->notebook), page - 1);
|
||||
sysprof_notebook_set_current_page (self->notebook, page - 1);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -114,20 +120,17 @@ close_tab_cb (GSimpleAction *action,
|
||||
gpointer user_data)
|
||||
{
|
||||
SysprofWindow *self = user_data;
|
||||
GtkNotebook *notebook;
|
||||
|
||||
g_return_if_fail (SYSPROF_IS_WINDOW (self));
|
||||
|
||||
notebook = GTK_NOTEBOOK (self->notebook);
|
||||
|
||||
if (gtk_notebook_get_n_pages (notebook) == 1)
|
||||
if (sysprof_notebook_get_n_pages (self->notebook) == 1)
|
||||
{
|
||||
GtkWidget *child = gtk_notebook_get_nth_page (notebook, 0);
|
||||
SysprofDisplay *child = sysprof_notebook_get_nth_page (self->notebook, 0);
|
||||
|
||||
if (SYSPROF_IS_DISPLAY (child) &&
|
||||
sysprof_display_is_empty (SYSPROF_DISPLAY (child)))
|
||||
{
|
||||
gtk_widget_destroy (GTK_WIDGET (self));
|
||||
gtk_window_destroy (GTK_WINDOW (self));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -175,7 +178,7 @@ sysprof_window_finalize (GObject *object)
|
||||
{
|
||||
SysprofWindow *self = (SysprofWindow *)object;
|
||||
|
||||
dzl_binding_group_set_source (self->bindings, NULL);
|
||||
egg_binding_group_set_source (self->bindings, NULL);
|
||||
g_clear_object (&self->bindings);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_window_parent_class)->finalize (object);
|
||||
@ -194,6 +197,17 @@ sysprof_window_class_init (SysprofWindowClass *klass)
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofWindow, open_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofWindow, notebook);
|
||||
|
||||
#if 0
|
||||
/* Switch to GtkShortcutController class bindings */
|
||||
DzlShortcutController *controller;
|
||||
controller = dzl_shortcut_controller_find (GTK_WIDGET (self));
|
||||
dzl_shortcut_controller_add_command_action (controller,
|
||||
"org.gnome.sysprof3.stop-recording",
|
||||
"Escape",
|
||||
DZL_SHORTCUT_PHASE_BUBBLE,
|
||||
"win.stop-recording");
|
||||
#endif
|
||||
|
||||
g_type_ensure (SYSPROF_TYPE_NOTEBOOK);
|
||||
g_type_ensure (SYSPROF_TYPE_DISPLAY);
|
||||
}
|
||||
@ -201,7 +215,6 @@ sysprof_window_class_init (SysprofWindowClass *klass)
|
||||
static void
|
||||
sysprof_window_init (SysprofWindow *self)
|
||||
{
|
||||
DzlShortcutController *controller;
|
||||
static GActionEntry actions[] = {
|
||||
{ "close-tab", close_tab_cb },
|
||||
{ "new-tab", new_tab_cb },
|
||||
@ -210,9 +223,13 @@ sysprof_window_init (SysprofWindow *self)
|
||||
{ "save-capture", save_capture_cb },
|
||||
{ "stop-recording", stop_recording_cb },
|
||||
};
|
||||
GMenu *menu;
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
menu = gtk_application_get_menu_by_id (GTK_APPLICATION (g_application_get_default ()), "win-menu");
|
||||
gtk_menu_button_set_menu_model (self->menu_button, G_MENU_MODEL (menu));
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (self),
|
||||
actions,
|
||||
G_N_ELEMENTS (actions),
|
||||
@ -230,24 +247,20 @@ sysprof_window_init (SysprofWindow *self)
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
self->bindings = dzl_binding_group_new ();
|
||||
dzl_binding_group_bind (self->bindings, "title", self, "title", G_BINDING_SYNC_CREATE);
|
||||
self->bindings = egg_binding_group_new ();
|
||||
egg_binding_group_bind (self->bindings, "title", self, "title", G_BINDING_SYNC_CREATE);
|
||||
g_object_bind_property (self->notebook, "current", self->bindings, "source",
|
||||
G_BINDING_SYNC_CREATE);
|
||||
|
||||
controller = dzl_shortcut_controller_find (GTK_WIDGET (self));
|
||||
dzl_shortcut_controller_add_command_action (controller,
|
||||
"org.gnome.sysprof3.stop-recording",
|
||||
"Escape",
|
||||
DZL_SHORTCUT_PHASE_BUBBLE,
|
||||
"win.stop-recording");
|
||||
|
||||
#if 0
|
||||
/* Switch to using gtk_widget_action_set_enabled() */
|
||||
dzl_gtk_widget_action_set (GTK_WIDGET (self), "win", "save-capture",
|
||||
"enabled", FALSE,
|
||||
NULL);
|
||||
dzl_gtk_widget_action_set (GTK_WIDGET (self), "win", "replay-capture",
|
||||
"enabled", FALSE,
|
||||
NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -260,12 +273,30 @@ sysprof_window_open (SysprofWindow *self,
|
||||
sysprof_notebook_open (self->notebook, file);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_window_open_from_dialog_cb (SysprofWindow *self,
|
||||
int response,
|
||||
GtkFileChooserNative *dialog)
|
||||
{
|
||||
g_assert (SYSPROF_IS_WINDOW (self));
|
||||
g_assert (GTK_IS_FILE_CHOOSER_NATIVE (dialog));
|
||||
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
g_autoptr(GFile) file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
||||
|
||||
if (g_file_is_native (file))
|
||||
sysprof_window_open (self, file);
|
||||
}
|
||||
|
||||
gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (dialog));
|
||||
}
|
||||
|
||||
void
|
||||
sysprof_window_open_from_dialog (SysprofWindow *self)
|
||||
{
|
||||
GtkFileChooserNative *dialog;
|
||||
GtkFileFilter *filter;
|
||||
gint response;
|
||||
|
||||
g_return_if_fail (SYSPROF_IS_WINDOW (self));
|
||||
|
||||
@ -278,8 +309,6 @@ sysprof_window_open_from_dialog (SysprofWindow *self)
|
||||
/* Translators: This is a button. */
|
||||
_("Cancel"));
|
||||
|
||||
gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), TRUE);
|
||||
|
||||
filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_set_name (filter, _("Sysprof Captures"));
|
||||
gtk_file_filter_add_pattern (filter, "*.syscap");
|
||||
@ -290,17 +319,13 @@ sysprof_window_open_from_dialog (SysprofWindow *self)
|
||||
gtk_file_filter_add_pattern (filter, "*");
|
||||
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
|
||||
|
||||
response = gtk_native_dialog_run (GTK_NATIVE_DIALOG (dialog));
|
||||
g_signal_connect_object (dialog,
|
||||
"response",
|
||||
G_CALLBACK (sysprof_window_open_from_dialog_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
g_autoptr(GFile) file = NULL;
|
||||
|
||||
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
||||
sysprof_window_open (self, file);
|
||||
}
|
||||
|
||||
gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (dialog));
|
||||
gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog));
|
||||
}
|
||||
|
||||
void
|
||||
@ -312,8 +337,6 @@ sysprof_window_new_tab (SysprofWindow *self)
|
||||
g_return_if_fail (SYSPROF_IS_WINDOW (self));
|
||||
|
||||
display = sysprof_display_new ();
|
||||
page = gtk_notebook_insert_page (GTK_NOTEBOOK (self->notebook), display, NULL, -1);
|
||||
gtk_widget_show (display);
|
||||
|
||||
gtk_notebook_set_current_page (GTK_NOTEBOOK (self->notebook), page);
|
||||
page = sysprof_notebook_append (self->notebook, SYSPROF_DISPLAY (display));
|
||||
sysprof_notebook_set_current_page (self->notebook, page);
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <dazzle.h>
|
||||
#include <adwaita.h>
|
||||
|
||||
#include "sysprof-application.h"
|
||||
|
||||
@ -28,7 +28,7 @@ G_BEGIN_DECLS
|
||||
|
||||
#define SYSPROF_TYPE_WINDOW (sysprof_window_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (SysprofWindow, sysprof_window, SYSPROF, WINDOW, DzlApplicationWindow)
|
||||
G_DECLARE_FINAL_TYPE (SysprofWindow, sysprof_window, SYSPROF, WINDOW, AdwApplicationWindow)
|
||||
|
||||
GtkWidget *sysprof_window_new (SysprofApplication *application);
|
||||
void sysprof_window_new_tab (SysprofWindow *self);
|
||||
|
||||
64
src/sysprof/sysprof-window.ui
Normal file
64
src/sysprof/sysprof-window.ui
Normal file
@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<interface>
|
||||
<template class="SysprofWindow" parent="AdwApplicationWindow">
|
||||
<style>
|
||||
<class name="org-gnome-Sysprof"/>
|
||||
</style>
|
||||
<property name="default-height">750</property>
|
||||
<property name="icon-name">org.gnome.Sysprof-symbolic</property>
|
||||
<property name="title" translatable="yes">Sysprof</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="show-title-buttons">true</property>
|
||||
<property name="visible">true</property>
|
||||
<child type="end">
|
||||
<object class="GtkMenuButton" id="menu_button">
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="icon-name">open-menu-symbolic</property>
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="image-button"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child type="start">
|
||||
<object class="GtkButton" id="open_button">
|
||||
<property name="label" translatable="yes">_Open</property>
|
||||
<property name="action-name">app.open-capture</property>
|
||||
<property name="use-underline">true</property>
|
||||
<property name="tooltip-text" translatable="yes">Open Recording… (Ctrl+O)</property>
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkLabel" id="stat_label">
|
||||
<property name="margin-end">12</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="SysprofNotebook" id="notebook">
|
||||
<property name="vexpand">true</property>
|
||||
<child>
|
||||
<object class="SysprofDisplay">
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@ -7,9 +7,9 @@
|
||||
|
||||
<!-- Theme overrides -->
|
||||
<file compressed="true">theme/shared.css</file>
|
||||
<file compressed="true">theme/Adwaita-shared.css</file>
|
||||
</gresource>
|
||||
|
||||
<!-- UI Files -->
|
||||
<file preprocess="xml-stripblanks">ui/sysprof-window.ui</file>
|
||||
<gresource prefix="/org/gnome/sysprof/ui">
|
||||
<file preprocess="xml-stripblanks">sysprof-window.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
/* development styles */
|
||||
window.development-version headerbar {
|
||||
background: transparent -gtk-icontheme("system-run-symbolic") 80% 0/128px 128px no-repeat,
|
||||
linear-gradient(to left,
|
||||
mix(@theme_fg_color, @theme_bg_color, 0.5) 0%,
|
||||
@theme_bg_color 25%);
|
||||
color: alpha(@theme_fg_color, 0.2);
|
||||
}
|
||||
|
||||
window.development-version headerbar box label {
|
||||
color: @theme_fg_color;
|
||||
}
|
||||
|
||||
button.sysprofprofilermenubutton.popup.suggested-action:checked {
|
||||
background: shade(@theme_selected_bg_color,0.9);
|
||||
border: 1px solid shade(@theme_selected_bg_color, 0.8);
|
||||
color: alpha(@theme_selected_fg_color,0.9);
|
||||
}
|
||||
@ -1,16 +1,3 @@
|
||||
popover list row {
|
||||
padding: 6px 10px 6px 10px;
|
||||
border-bottom: 1px solid alpha(@borders, 0.2);
|
||||
}
|
||||
|
||||
popover list row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
popover scrolledwindow {
|
||||
border-top: 1px solid alpha(@borders, 0.75);
|
||||
}
|
||||
|
||||
visualizers list {
|
||||
background: @theme_bg_color;
|
||||
}
|
||||
|
||||
@ -1,64 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<interface>
|
||||
<template class="SysprofWindow" parent="DzlApplicationWindow">
|
||||
<property name="default-height">750</property>
|
||||
<property name="icon-name">org.gnome.Sysprof-symbolic</property>
|
||||
<property name="show-menubar">false</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="show-close-button">true</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="title" translatable="yes">Sysprof</property>
|
||||
<child>
|
||||
<object class="DzlMenuButton" id="menu_button">
|
||||
<property name="icon-name">open-menu-symbolic</property>
|
||||
<property name="show-accels">true</property>
|
||||
<property name="menu-id">win-menu</property>
|
||||
<property name="visible">true</property>
|
||||
<style>
|
||||
<class name="image-button"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="open_button">
|
||||
<property name="label" translatable="yes">_Open</property>
|
||||
<property name="action-name">app.open-capture</property>
|
||||
<property name="use-underline">true</property>
|
||||
<property name="tooltip-text" translatable="yes">Open Recording… (Ctrl+O)</property>
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">start</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="stat_label">
|
||||
<property name="margin-end">12</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="SysprofNotebook" id="notebook">
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="SysprofDisplay">
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@ -122,8 +122,7 @@ if get_option('enable_gtk')
|
||||
test_ui_deps = [
|
||||
libsysprof_dep,
|
||||
libsysprof_ui_dep,
|
||||
dependency('gtk+-3.0', version: gtk_req_version),
|
||||
dependency('libdazzle-1.0', version: dazzle_req_version, fallback: ['libdazzle', 'libdazzle_dep']),
|
||||
dependency('gtk4', version: gtk_req_version),
|
||||
dependency('pangoft2', required: false),
|
||||
]
|
||||
|
||||
|
||||
@ -28,8 +28,9 @@ main (gint argc,
|
||||
SysprofDisplay *view;
|
||||
SysprofCaptureReader *reader;
|
||||
g_autoptr(GError) error = NULL;
|
||||
GMainLoop *main_loop;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
gtk_init ();
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
@ -43,6 +44,8 @@ main (gint argc,
|
||||
return 1;
|
||||
}
|
||||
|
||||
main_loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
window = g_object_new (GTK_TYPE_WINDOW,
|
||||
"title", "SysprofDisplay",
|
||||
"default-width", 800,
|
||||
@ -51,13 +54,13 @@ main (gint argc,
|
||||
view = g_object_new (SYSPROF_TYPE_DISPLAY,
|
||||
"visible", TRUE,
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (view));
|
||||
gtk_window_set_child (GTK_WINDOW (window), GTK_WIDGET (view));
|
||||
|
||||
sysprof_display_load_async (view, reader, NULL, NULL, NULL);
|
||||
|
||||
g_signal_connect (window, "delete-event", gtk_main_quit, NULL);
|
||||
g_signal_connect_swapped (window, "close-request", G_CALLBACK (g_main_loop_quit), main_loop);
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
gtk_main ();
|
||||
g_main_loop_run (main_loop);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -18,11 +18,11 @@ filter_cb (GObject *object,
|
||||
const gchar *needle = user_data;
|
||||
const gchar *command = sysprof_process_model_item_get_command_line (SYSPROF_PROCESS_MODEL_ITEM (object));
|
||||
|
||||
return !!strstr (command, needle);
|
||||
return needle == NULL || needle[0] == 0 || strstr (command, needle) != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
on_entry_changed (GtkEntry *entry,
|
||||
on_entry_changed (GtkEntry *entry,
|
||||
SysprofModelFilter *filter)
|
||||
{
|
||||
const gchar *text;
|
||||
@ -30,10 +30,10 @@ on_entry_changed (GtkEntry *entry,
|
||||
g_assert (GTK_IS_ENTRY (entry));
|
||||
g_assert (SYSPROF_IS_MODEL_FILTER (filter));
|
||||
|
||||
text = gtk_entry_get_text (entry);
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (entry));
|
||||
sysprof_model_filter_set_filter_func (filter, filter_cb, g_strdup (text), g_free);
|
||||
|
||||
//gtk_list_box_bind_model (GTK_LIST_BOX (list), G_LIST_MODEL (filter), create_row, NULL, NULL);
|
||||
gtk_list_box_bind_model (GTK_LIST_BOX (list), G_LIST_MODEL (filter), create_row, NULL, NULL);
|
||||
}
|
||||
|
||||
gint
|
||||
@ -46,8 +46,11 @@ main (gint argc,
|
||||
GtkWidget *box;
|
||||
GtkWidget *scroller;
|
||||
GtkWidget *entry;
|
||||
GMainLoop *main_loop;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
gtk_init ();
|
||||
|
||||
main_loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
window = g_object_new (GTK_TYPE_WINDOW,
|
||||
"title", "Sysprof Process List",
|
||||
@ -59,23 +62,24 @@ main (gint argc,
|
||||
"orientation", GTK_ORIENTATION_VERTICAL,
|
||||
"visible", TRUE,
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
|
||||
entry = g_object_new (GTK_TYPE_ENTRY,
|
||||
"visible", TRUE,
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (box), entry);
|
||||
gtk_box_append (GTK_BOX (box), entry);
|
||||
|
||||
scroller = g_object_new (GTK_TYPE_SCROLLED_WINDOW,
|
||||
"visible", TRUE,
|
||||
"expand", TRUE,
|
||||
"vexpand", TRUE,
|
||||
"hexpand", TRUE,
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (box), scroller);
|
||||
gtk_box_append (GTK_BOX (box), scroller);
|
||||
|
||||
list = g_object_new (GTK_TYPE_LIST_BOX,
|
||||
"visible", TRUE,
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (scroller), list);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scroller), list);
|
||||
|
||||
model = sysprof_process_model_new ();
|
||||
sysprof_process_model_set_no_proxy (model, TRUE);
|
||||
@ -87,9 +91,9 @@ main (gint argc,
|
||||
G_CALLBACK (on_entry_changed),
|
||||
filter);
|
||||
|
||||
g_signal_connect_swapped (window, "close-request", G_CALLBACK (g_main_loop_quit), main_loop);
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
g_signal_connect (window, "delete-event", gtk_main_quit, NULL);
|
||||
gtk_main ();
|
||||
g_main_loop_run (main_loop);
|
||||
|
||||
g_object_unref (model);
|
||||
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
[wrap-file]
|
||||
directory=libdazzle-3.35.3
|
||||
source_url=https://download.gnome.org/sources/libdazzle/3.35/libdazzle-3.35.3.tar.xz
|
||||
source_filename=libdazzle-3.35.3.tar.xz
|
||||
source_hash=df67f7a68096e4b33a70ee0bad14cd8a6778425deb087879b5cd8fef8f671304
|
||||
Reference in New Issue
Block a user