Compare commits

...

3 Commits

Author SHA1 Message Date
Timm Bäder
c4d4c16b12 WIP: Add GtkImageView 2019-11-01 14:05:17 +01:00
Timm Bäder
dda089871b popover: Use a bin layout for the contents gizmo 2019-10-25 10:36:29 +02:00
Timm Bäder
b7864a347a testpopover: Plug two GtkBuilder leaks 2019-10-25 10:35:53 +02:00
17 changed files with 3103 additions and 39 deletions

View File

@@ -186,6 +186,7 @@
<file>iconview.c</file>
<file>iconview_edit.c</file>
<file>images.c</file>
<file>image_view.c</file>
<file>infobar.c</file>
<file>links.c</file>
<file>listbox.c</file>
@@ -229,6 +230,9 @@
<file>textmask.c</file>
<file>video_player.c</file>
</gresource>
<gresource prefix="/imageview">
<file>image_view.ui</file>
</gresource>
<gresource prefix="/textview">
<file>floppybuddy.gif</file>
</gresource>

258
demos/gtk-demo/image_view.c Normal file
View File

@@ -0,0 +1,258 @@
/* Image View
*/
#include <gtk/gtk.h>
#include "paintable.h"
GtkWidget *image_view;
GtkWidget *uri_entry;
void
reset_view_button_clicked_cb ()
{
gtk_image_view_set_scale (GTK_IMAGE_VIEW (image_view), 1.0);
gtk_image_view_set_angle (GTK_IMAGE_VIEW (image_view), 0.0);
}
void
load_from_file_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
GError *error = NULL;
gtk_image_view_load_from_file_finish (GTK_IMAGE_VIEW (image_view),
result,
&error);
if (error != NULL)
{
g_warning ("load_from_file_async error: %s", error->message);
}
}
void
file_set_cb (GtkFileChooserButton *widget,
gpointer user_data)
{
char *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
GFile *file = g_file_new_for_path (filename);
gtk_image_view_load_from_file_async (GTK_IMAGE_VIEW (image_view),
file,
NULL,
load_from_file_cb,
NULL);
g_free (filename);
g_object_unref (file);
}
static void
image_loaded_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
GtkImageView *image_view = GTK_IMAGE_VIEW (source_object);
GError *error = NULL;
gtk_image_view_load_from_file_finish (image_view,
result,
&error);
if (error)
{
g_message ("Error: %s", error->message);
return;
}
}
void
load_button_cb ()
{
const char *uri = gtk_editable_get_text (GTK_EDITABLE (uri_entry));
GFile *file = g_file_new_for_uri (uri);
g_message (__FUNCTION__);
gtk_image_view_load_from_file_async (GTK_IMAGE_VIEW (image_view),
file,
NULL,
image_loaded_cb,
NULL);
g_object_unref (file);
}
void
angle_changed_cb (GtkRange *range,
gpointer user_data)
{
double value = gtk_range_get_value (range);
gtk_image_view_set_angle (GTK_IMAGE_VIEW (image_view), value);
}
void
scale_changed_cb (GtkRange *range,
gpointer user_data)
{
double value = gtk_range_get_value (range);
gtk_image_view_set_scale (GTK_IMAGE_VIEW (image_view), value);
}
void
rotate_left_clicked_cb ()
{
double current_angle = gtk_image_view_get_angle (GTK_IMAGE_VIEW (image_view));
gtk_image_view_set_angle (GTK_IMAGE_VIEW (image_view), current_angle - 90);
}
void
rotate_right_clicked_cb ()
{
double current_angle = gtk_image_view_get_angle (GTK_IMAGE_VIEW (image_view));
gtk_image_view_set_angle (GTK_IMAGE_VIEW (image_view), current_angle + 90);
}
void
scrolled_switch_active_cb (GObject *source)
{
GtkWidget *parent = gtk_widget_get_parent (image_view);
if (GTK_IS_SCROLLED_WINDOW (parent))
{
GtkWidget *grandparent = gtk_widget_get_parent (parent);
g_assert (grandparent != NULL);
g_object_ref (G_OBJECT (image_view));
gtk_container_remove (GTK_CONTAINER (parent), image_view);
gtk_container_remove (GTK_CONTAINER (grandparent), parent);
gtk_container_add (GTK_CONTAINER (grandparent), image_view);
gtk_widget_show (image_view);
g_object_unref (G_OBJECT (image_view));
}
else
{
GtkWidget *scroller = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroller),
GTK_POLICY_ALWAYS,
GTK_POLICY_ALWAYS);
g_object_ref (image_view);
gtk_container_remove (GTK_CONTAINER (parent), image_view);
gtk_container_add (GTK_CONTAINER (scroller), image_view);
gtk_container_add (GTK_CONTAINER (parent), scroller);
gtk_widget_show (scroller);
g_object_unref (image_view);
}
}
gchar *
angle_scale_format_value_cb (GtkScale *scale,
double value,
gpointer user_data)
{
return g_strdup_printf ("%.2f°", value);
}
gchar *
scale_scale_format_value_cb (GtkScale *scale,
double value,
gpointer user_data)
{
return g_strdup_printf ("%.2f", value);
}
void
load_pixbuf_button_clicked_cb ()
{
GdkPixbuf *pixbuf;
GdkTexture *texture;
pixbuf = gdk_pixbuf_new_from_file ("/usr/share/backgrounds/gnome/AndICallItBoke.jpg", NULL);
texture = gdk_texture_new_for_pixbuf (pixbuf);
g_object_unref (pixbuf);
gtk_image_view_set_paintable (GTK_IMAGE_VIEW (image_view),
GDK_PAINTABLE (texture));
g_object_unref (texture);
}
void
load_hidpi_pixbuf_button_clicked_cb ()
{
GdkPaintable *p;
p = gtk_nuclear_animation_new ();
gtk_image_view_set_paintable (GTK_IMAGE_VIEW (image_view), p);
g_object_unref (p);
}
void
clear_button_clicked_cb ()
{
gtk_image_view_set_paintable (GTK_IMAGE_VIEW (image_view), NULL);
}
GtkWidget *
do_image_view (GtkWidget *do_widget)
{
GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
GtkBuilder *builder = gtk_builder_new_from_resource ("/imageview/image_view.ui");
GtkWidget *box = GTK_WIDGET (gtk_builder_get_object (builder, "box"));
GtkWidget *snap_angle_switch = GTK_WIDGET (gtk_builder_get_object (builder, "snap_angle_switch"));
GtkWidget *fit_allocation_switch = GTK_WIDGET (gtk_builder_get_object (builder, "fit_allocation_switch"));
GtkWidget *rotate_gesture_switch = GTK_WIDGET (gtk_builder_get_object (builder, "rotate_gesture_switch"));
GtkWidget *zoom_gesture_switch = GTK_WIDGET (gtk_builder_get_object (builder, "zoom_gesture_switch"));
GtkWidget *transitions_switch = GTK_WIDGET (gtk_builder_get_object (builder, "transitions_switch"));
GtkAdjustment *scale_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "scale_adjustment"));
GtkAdjustment *angle_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "angle_adjustment"));
image_view = GTK_WIDGET (gtk_builder_get_object (builder, "image_view"));
uri_entry = GTK_WIDGET (gtk_builder_get_object (builder, "uri_entry"));
g_object_bind_property (scale_adjustment, "value", image_view, "scale",
G_BINDING_BIDIRECTIONAL);
g_object_bind_property (angle_adjustment, "value", image_view, "angle",
G_BINDING_SYNC_CREATE);
g_object_bind_property (image_view, "angle", angle_adjustment, "value",
G_BINDING_SYNC_CREATE);
g_object_bind_property (image_view, "snap-angle", snap_angle_switch, "active",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
g_object_bind_property (image_view, "fit-allocation", fit_allocation_switch, "active",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
g_object_bind_property (image_view, "rotatable",
rotate_gesture_switch, "active",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
g_object_bind_property (image_view, "zoomable",
zoom_gesture_switch, "active",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
g_object_bind_property (image_view, "transitions-enabled",
transitions_switch, "active",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
gtk_container_add (GTK_CONTAINER (window), box);
gtk_builder_connect_signals (builder, NULL);
gtk_window_resize (GTK_WINDOW (window), 800, 600);
gtk_widget_show (window);
g_object_unref (builder);
return window;
}

View File

@@ -0,0 +1,313 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkAdjustment" id="scale_adjustment">
<property name="upper">5</property>
<property name="lower">0.05</property>
<property name="value">1.0</property>
<property name="step-increment">0.01</property>
<property name="page-increment">0.01</property>
</object>
<object class="GtkAdjustment" id="angle_adjustment">
<property name="upper">360</property>
<property name="step_increment">0.1</property>
<property name="page-increment">1</property>
</object>
<object class="GtkBox" id="box">
<child>
<object class="GtkGrid" id="grid">
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<property name="margin">6</property>
<child>
<object class="GtkEntry" id="uri_entry">
<property name="placeholder_text">URI</property>
</object>
</child>
<child>
<object class="GtkButton" id="load_button">
<property name="label" translatable="yes">Load</property>
<signal name="clicked" handler="load_button_cb"/>
<layout>
<property name="left_attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkFileChooserButton">
<property name="valign">baseline</property>
<signal name="file-set" handler="file_set_cb"/>
<layout>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Load Pixbuf</property>
<signal name="clicked" handler="load_pixbuf_button_clicked_cb" object="image_view"/>
<layout>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Load HiDPI Pixbuf</property>
<signal name="clicked" handler="load_hidpi_pixbuf_button_clicked_cb" object="image_view"/>
<layout>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Clear</property>
<signal name="clicked" handler="clear_button_clicked_cb"/>
<layout>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Fit Allocation</property>
<property name="halign">start</property>
<layout>
<property name="left_attach">0</property>
<property name="top_attach">6</property>
</layout>
</object>
</child>
<child>
<object class="GtkSwitch" id="fit_allocation_switch">
<property name="halign">end</property>
<layout>
<property name="left_attach">1</property>
<property name="top_attach">6</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">In ScrolledWindow</property>
<property name="halign">start</property>
<layout>
<property name="left_attach">0</property>
<property name="top_attach">7</property>
</layout>
</object>
</child>
<child>
<object class="GtkSwitch" id="scrolled_switch">
<property name="halign">end</property>
<property name="active">1</property>
<signal name="notify::active" handler="scrolled_switch_active_cb"/>
<layout>
<property name="left_attach">1</property>
<property name="top_attach">7</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Zoomable</property>
<property name="halign">start</property>
<layout>
<property name="left_attach">0</property>
<property name="top_attach">8</property>
</layout>
</object>
</child>
<child>
<object class="GtkSwitch" id="zoom_gesture_switch">
<property name="halign">end</property>
<property name="active">1</property>
<layout>
<property name="left_attach">1</property>
<property name="top_attach">8</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Rotatable</property>
<property name="halign">start</property>
<layout>
<property name="left_attach">0</property>
<property name="top_attach">9</property>
</layout>
</object>
</child>
<child>
<object class="GtkSwitch" id="rotate_gesture_switch">
<property name="halign">end</property>
<property name="active">1</property>
<layout>
<property name="left_attach">1</property>
<property name="top_attach">9</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Snap Angle</property>
<property name="halign">start</property>
<layout>
<property name="left_attach">0</property>
<property name="top_attach">10</property>
</layout>
</object>
</child>
<child>
<object class="GtkSwitch" id="snap_angle_switch">
<property name="halign">end</property>
<layout>
<property name="left_attach">1</property>
<property name="top_attach">10</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Transitions</property>
<property name="halign">start</property>
<layout>
<property name="left_attach">0</property>
<property name="top_attach">11</property>
</layout>
</object>
</child>
<child>
<object class="GtkSwitch" id="transitions_switch">
<property name="halign">end</property>
<layout>
<property name="left_attach">1</property>
<property name="top_attach">11</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Angle</property>
<property name="margin_top">12</property>
<property name="halign">start</property>
<attributes>
<attribute name="weight" value="bold"></attribute>
</attributes>
<layout>
<property name="left_attach">0</property>
<property name="top_attach">12</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkScale" id="angle_spin_button">
<property name="draw-value">0</property>
<property name="digits">2</property>
<property name="draw-value">0</property>
<property name="adjustment">angle_adjustment</property>
<layout>
<property name="left_attach">0</property>
<property name="top_attach">13</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Scale</property>
<property name="halign">start</property>
<property name="xalign">0.0</property>
<attributes>
<attribute name="weight" value="bold"></attribute>
</attributes>
<layout>
<property name="left_attach">0</property>
<property name="top_attach">14</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkScale" id="scale_spin_button">
<property name="draw-value">0</property>
<property name="digits">2</property>
<property name="adjustment">scale_adjustment</property>
<layout>
<property name="left_attach">0</property>
<property name="top_attach">15</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkBox">
<property name="halign">center</property>
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkButton">
<signal name="clicked" handler="rotate_left_clicked_cb"/>
<child>
<object class="GtkImage">
<property name="icon-name">object-rotate-left-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton">
<signal name="clicked" handler="rotate_right_clicked_cb"/>
<child>
<object class="GtkImage">
<property name="icon-name">object-rotate-right-symbolic</property>
</object>
</child>
</object>
</child>
<layout>
<property name="left_attach">0</property>
<property name="top_attach">16</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton" id="reset_button">
<property name="label" translatable="true">Reset View</property>
<property name="valign">end</property>
<property name="vexpand">1</property>
<signal name="clicked" handler="reset_view_button_clicked_cb"/>
<layout>
<property name="left_attach">0</property>
<property name="top_attach">17</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<child>
<object class="GtkImageView" id="image_view">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="width_request">400</property>
<property name="height_request">400</property>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -38,6 +38,7 @@ demos = files([
'iconview.c',
'iconview_edit.c',
'images.c',
'image_view.c',
'infobar.c',
'links.c',
'listbox.c',

View File

@@ -120,6 +120,7 @@
<xi:include href="xml/gtklabel.xml" />
<xi:include href="xml/gtkimage.xml" />
<xi:include href="xml/gtkpicture.xml" />
<xi:include href="xml/gtkimageview.xml" />
<xi:include href="xml/gtkspinner.xml" />
<xi:include href="xml/gtkinfobar.xml" />
<xi:include href="xml/gtkprogressbar.xml" />

View File

@@ -1638,6 +1638,45 @@ GtkImageIconNameData
GtkImageGIconData
</SECTION>
<SECTION>
<FILE>gtkimageview</FILE>
<TITLE>GtkImageView</TITLE>
GtkImageView
gtk_image_view_new
gtk_image_view_set_pixbuf
gtk_image_view_set_surface
gtk_image_view_set_animation
gtk_image_view_load_from_file_async
gtk_image_view_load_from_file_finish
gtk_image_view_load_from_stream_async
gtk_image_view_load_from_stream_finish
gtk_image_view_set_scale
gtk_image_view_get_scale
gtk_image_view_set_angle
gtk_image_view_get_angle
gtk_image_view_set_snap_angle
gtk_image_view_get_snap_angle
gtk_image_view_set_fit_allocation
gtk_image_view_get_fit_allocation
gtk_image_view_set_rotatable
gtk_image_view_get_rotatable
gtk_image_view_set_zoomable
gtk_image_view_get_zoomable
gtk_image_view_get_scale_set
gtk_image_view_set_transitions_enabled
gtk_image_view_get_transitions_enabled
<SUBSECTION Standard>
GTK_IMAGE_VIEW
GTK_IS_IMAGE_VIEW
GTK_TYPE_IMAGE_VIEW
GTK_IMAGE__VIEW_CLASS
GTK_IS_IMAGE_VIEW_CLASS
GTK_IMAGE_VIEW_GET_CLASS
<SUBSECTION Private>
GtkImageViewPrivate
gtk_image_view_get_type
</SECTION>
<SECTION>
<FILE>gtkimcontext</FILE>
<TITLE>GtkIMContext</TITLE>

View File

@@ -99,6 +99,7 @@ gtk_header_bar_get_type
gtk_icon_theme_get_type
gtk_icon_view_get_type
gtk_image_get_type
gtk_image_view_get_type
gtk_im_context_get_type
gtk_im_context_simple_get_type
gtk_im_multicontext_get_type

View File

@@ -33,6 +33,9 @@
<link linkend="GtkImage">
<inlinegraphic fileref="image.png" format="PNG"></inlinegraphic>
</link>
<link linkend="GtkImageView">
<inlinegraphic fileref="image.png" format="PNG"></inlinegraphic>
</link>
<link linkend="GtkSeparator">
<inlinegraphic fileref="separator.png" format="PNG"></inlinegraphic>
</link>

View File

@@ -93,7 +93,7 @@ struct _GdkPaintableInterface
double height);
/* get the current contents in an immutable form (optional) */
GdkPaintable * (* get_current_image) (GdkPaintable *paintable);
/* get flags for potential optimizations (optional) */
GdkPaintableFlags (* get_flags) (GdkPaintable *paintable);
/* preferred width of paintable or 0 if it has no width (optional) */

View File

@@ -138,6 +138,7 @@
#include <gtk/gtkicontheme.h>
#include <gtk/gtkiconview.h>
#include <gtk/gtkimage.h>
#include <gtk/gtkimageview.h>
#include <gtk/gtkimcontext.h>
#include <gtk/gtkimcontextsimple.h>
#include <gtk/gtkimmulticontext.h>

2179
gtk/gtkimageview.c Normal file

File diff suppressed because it is too large Load Diff

116
gtk/gtkimageview.h Normal file
View File

@@ -0,0 +1,116 @@
/* Copyright 2018 Timm Bäder
*
* GTK+ is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* GLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with GTK+; see the file COPYING. If not,
* see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_IMAGE_VIEW_H__
#define __GTK_IMAGE_VIEW_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkwidget.h>
G_BEGIN_DECLS
#define GTK_TYPE_IMAGE_VIEW (gtk_image_view_get_type ())
#define GTK_IMAGE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_IMAGE_VIEW, GtkImageView))
#define GTK_IMAGE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_IMAGE_VIEW, GtkImageViewClass))
#define GTK_IS_IMAGE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_IMAGE_VIEW))
#define GTK_IS_IMAGE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_IMAGE_VIEW))
#define GTK_IMAGE_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_IMAGE_VIEW, GtkImageViewClass))
typedef struct _GtkImageView GtkImageView;
typedef struct _GtkImageViewClass GtkImageViewClass;
struct _GtkImageView
{
GtkWidget parent_instance;
};
struct _GtkImageViewClass
{
GtkWidgetClass parent_class;
};
GDK_AVAILABLE_IN_ALL
GType gtk_image_view_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkWidget * gtk_image_view_new (void);
GDK_AVAILABLE_IN_ALL
void gtk_image_view_load_from_file_async (GtkImageView *self,
GFile *file,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GDK_AVAILABLE_IN_ALL
gboolean gtk_image_view_load_from_file_finish (GtkImageView *self,
GAsyncResult *result,
GError **error);
GDK_AVAILABLE_IN_ALL
void gtk_image_view_load_from_stream_async (GtkImageView *self,
GInputStream *input_stream,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GDK_AVAILABLE_IN_ALL
gboolean gtk_image_view_load_from_stream_finish (GtkImageView *self,
GAsyncResult *result,
GError **error);
GDK_AVAILABLE_IN_ALL
void gtk_image_view_set_scale (GtkImageView *self,
double scale);
GDK_AVAILABLE_IN_ALL
double gtk_image_view_get_scale (GtkImageView *self);
GDK_AVAILABLE_IN_ALL
void gtk_image_view_set_angle (GtkImageView *self,
double angle);
GDK_AVAILABLE_IN_ALL
double gtk_image_view_get_angle (GtkImageView *self);
GDK_AVAILABLE_IN_ALL
void gtk_image_view_set_snap_angle (GtkImageView *self,
gboolean snap_angle);
GDK_AVAILABLE_IN_ALL
gboolean gtk_image_view_get_snap_angle (GtkImageView *self);
GDK_AVAILABLE_IN_ALL
void gtk_image_view_set_fit_allocation (GtkImageView *self,
gboolean fit_allocation);
GDK_AVAILABLE_IN_ALL
gboolean gtk_image_view_get_fit_allocation (GtkImageView *self);
GDK_AVAILABLE_IN_ALL
void gtk_image_view_set_rotatable (GtkImageView *self,
gboolean rotatable);
GDK_AVAILABLE_IN_ALL
gboolean gtk_image_view_get_rotatable (GtkImageView *self);
GDK_AVAILABLE_IN_ALL
void gtk_image_view_set_zoomable (GtkImageView *self,
gboolean zoomable);
GDK_AVAILABLE_IN_ALL
gboolean gtk_image_view_get_zoomable (GtkImageView *self);
GDK_AVAILABLE_IN_ALL
gboolean gtk_image_view_get_scale_set (GtkImageView *self);
GDK_AVAILABLE_IN_ALL
void gtk_image_view_set_transitions_enabled (GtkImageView *self,
gboolean transitions_enabled);
GDK_AVAILABLE_IN_ALL
gboolean gtk_image_view_get_transitions_enabled (GtkImageView *self);
GDK_AVAILABLE_IN_ALL
void gtk_image_view_set_paintable (GtkImageView *self,
GdkPaintable *paintable);
G_END_DECLS
#endif

View File

@@ -113,6 +113,7 @@
#include "gtkeventcontrollerkey.h"
#include "gtkcssnodeprivate.h"
#include "gtkbindings.h"
#include "gtkbinlayout.h"
#include "gtkenums.h"
#include "gtktypebuiltins.h"
#include "gtkmnemonichash.h"
@@ -504,39 +505,6 @@ surface_moved_to_rect (GdkSurface *surface,
}
}
static void
measure_contents (GtkGizmo *gizmo,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkPopover *popover = GTK_POPOVER (gtk_widget_get_parent (GTK_WIDGET (gizmo)));
GtkWidget *child = gtk_bin_get_child (GTK_BIN (popover));
if (child)
gtk_widget_measure (child, orientation, for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
static void
allocate_contents (GtkGizmo *gizmo,
int width,
int height,
int baseline)
{
GtkPopover *popover = GTK_POPOVER (gtk_widget_get_parent (GTK_WIDGET (gizmo)));
GtkWidget *child = gtk_bin_get_child (GTK_BIN (popover));
if (child)
gtk_widget_size_allocate (child,
&(GtkAllocation) { 0, 0, width, height
}, -1);
}
static void
gtk_popover_activate_default (GtkPopover *popover)
{
@@ -622,11 +590,8 @@ gtk_popover_init (GtkPopover *popover)
G_CALLBACK (node_style_changed_cb), popover, 0);
g_object_unref (priv->arrow_node);
priv->contents_widget = gtk_gizmo_new ("contents",
measure_contents,
allocate_contents,
NULL,
NULL);
priv->contents_widget = gtk_gizmo_new ("contents", NULL, NULL, NULL, NULL);
gtk_widget_set_layout_manager (priv->contents_widget, gtk_bin_layout_new ());
gtk_widget_set_parent (priv->contents_widget, GTK_WIDGET (popover));
context = gtk_widget_get_style_context (GTK_WIDGET (popover));

View File

@@ -263,6 +263,7 @@ gtk_public_sources = files([
'gtkiconview.c',
'gtkimage.c',
'gtkimagedefinition.c',
'gtkimageview.c',
'gtkimcontext.c',
'gtkimcontextsimple.c',
'gtkimmodule.c',
@@ -527,6 +528,7 @@ gtk_public_headers = files([
'gtkiconview.h',
'gtkimage.h',
'gtkimcontext.h',
'gtkimageview.h',
'gtkimcontextsimple.h',
'gtkimmodule.h',
'gtkimmulticontext.h',

View File

@@ -107,6 +107,7 @@ main (int argc, char *argv[])
popover1 = gtk_popover_menu_new_from_model_full (NULL, model, GTK_POPOVER_MENU_NESTED);
gtk_menu_button_set_popover (GTK_MENU_BUTTON (button1), popover1);
g_object_unref (builder);
builder = gtk_builder_new_from_file ("popover2.ui");
popover2 = (GtkWidget *)gtk_builder_get_object (builder, "popover");
gtk_menu_button_set_popover (GTK_MENU_BUTTON (button2), popover2);
@@ -164,6 +165,7 @@ main (int argc, char *argv[])
g_object_bind_property (combo, "active", box, "valign", G_BINDING_SYNC_CREATE);
gtk_grid_attach (GTK_GRID (grid), label , 1, 5, 1, 1);
gtk_grid_attach (GTK_GRID (grid), combo, 2, 5, 1, 1);
g_object_unref (builder);
g_signal_connect (win, "destroy", G_CALLBACK (gtk_main_quit), NULL);

View File

@@ -0,0 +1,178 @@
#include <gtk/gtk.h>
void
empty ()
{
int min, nat;
GtkWidget *iv = gtk_image_view_new ();
gtk_widget_show (iv);
gtk_widget_measure (iv, GTK_ORIENTATION_HORIZONTAL, -1, &min, &nat, NULL, NULL);
g_assert_cmpint (min, ==, 0);
g_assert_cmpint (nat, ==, 0);
gtk_widget_measure (iv, GTK_ORIENTATION_VERTICAL, -1, &min, &nat, NULL, NULL);
g_assert_cmpint (min, ==, 0);
g_assert_cmpint (nat, ==, 0);
}
void
image_fit_allocation ()
{
int min, nat;
GtkWidget *iv;
GdkPixbuf *pic;
GdkTexture *texture;
iv = gtk_image_view_new ();
pic = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 100, 200);
texture = gdk_texture_new_for_pixbuf (pic);
gtk_image_view_set_paintable (GTK_IMAGE_VIEW (iv), GDK_PAINTABLE (texture));
gtk_image_view_set_fit_allocation (GTK_IMAGE_VIEW (iv), TRUE);
gtk_widget_measure (iv, GTK_ORIENTATION_HORIZONTAL, -1, &min, &nat, NULL, NULL);
g_assert_cmpint (min, ==, 0);
g_assert_cmpint (nat, ==, gdk_pixbuf_get_width (pic));
gtk_widget_measure (iv, GTK_ORIENTATION_VERTICAL, -1, &min, &nat, NULL, NULL);
g_assert_cmpint (min, ==, 0);
g_assert_cmpint (nat, ==, gdk_pixbuf_get_height (pic));
}
void
image_no_fit_allocation ()
{
int min, nat;
GtkWidget *iv;
GdkPixbuf *pic;
GdkTexture *texture;
iv = gtk_image_view_new ();
pic = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 100, 200);
texture = gdk_texture_new_for_pixbuf (pic);
gtk_image_view_set_paintable (GTK_IMAGE_VIEW (iv), GDK_PAINTABLE (texture));
gtk_widget_measure (iv, GTK_ORIENTATION_HORIZONTAL, -1, &min, &nat, NULL, NULL);
g_assert_cmpint (min, ==, gdk_pixbuf_get_width (pic));
g_assert_cmpint (nat, ==, gdk_pixbuf_get_width (pic));
gtk_widget_measure (iv, GTK_ORIENTATION_VERTICAL, -1, &min, &nat, NULL, NULL);
g_assert_cmpint (min, ==, gdk_pixbuf_get_height (pic));
g_assert_cmpint (nat, ==, gdk_pixbuf_get_height (pic));
}
void
image_scaled ()
{
int min, nat;
GtkWidget *iv;
GdkPixbuf *pic;
GdkTexture *texture;
iv = gtk_image_view_new ();
pic = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 100, 200);
texture = gdk_texture_new_for_pixbuf (pic);
gtk_image_view_set_paintable (GTK_IMAGE_VIEW (iv), GDK_PAINTABLE (texture));
gtk_widget_measure (iv, GTK_ORIENTATION_HORIZONTAL, -1, &min, &nat, NULL, NULL);
g_assert_cmpint (min, ==, gdk_pixbuf_get_width (pic));
g_assert_cmpint (nat, ==, gdk_pixbuf_get_width (pic));
gtk_widget_measure (iv, GTK_ORIENTATION_VERTICAL, -1, &min, &nat, NULL, NULL);
g_assert_cmpint (min, ==, gdk_pixbuf_get_height (pic));
g_assert_cmpint (nat, ==, gdk_pixbuf_get_height (pic));
gtk_image_view_set_scale (GTK_IMAGE_VIEW (iv), 2.0);
gtk_widget_measure (iv, GTK_ORIENTATION_HORIZONTAL, -1, &min, &nat, NULL, NULL);
g_assert_cmpint (min, ==, gdk_pixbuf_get_width (pic) * 2.0);
g_assert_cmpint (nat, ==, gdk_pixbuf_get_width (pic) * 2.0);
gtk_widget_measure (iv, GTK_ORIENTATION_VERTICAL, -1, &min, &nat, NULL, NULL);
g_assert_cmpint (min, ==, gdk_pixbuf_get_height (pic) * 2.0);
g_assert_cmpint (nat, ==, gdk_pixbuf_get_height (pic) * 2.0);
gtk_image_view_set_scale (GTK_IMAGE_VIEW (iv), 0.5);
gtk_widget_measure (iv, GTK_ORIENTATION_HORIZONTAL, -1, &min, &nat, NULL, NULL);
g_assert_cmpint (min, ==, gdk_pixbuf_get_width (pic) * 0.5);
g_assert_cmpint (nat, ==, gdk_pixbuf_get_width (pic) * 0.5);
gtk_widget_measure (iv, GTK_ORIENTATION_VERTICAL, -1, &min, &nat, NULL, NULL);
g_assert_cmpint (min, ==, gdk_pixbuf_get_height (pic) * 0.5);
g_assert_cmpint (nat, ==, gdk_pixbuf_get_height (pic) * 0.5);
}
void
image_rotated ()
{
int min, nat;
GtkWidget *iv;
GdkPixbuf *pic;
GdkTexture *texture;
iv = gtk_image_view_new ();
pic = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 100, 200);
texture = gdk_texture_new_for_pixbuf (pic);
gtk_image_view_set_paintable (GTK_IMAGE_VIEW (iv), GDK_PAINTABLE (texture));
gtk_image_view_set_angle (GTK_IMAGE_VIEW (iv), 90.0);
gtk_widget_measure (iv, GTK_ORIENTATION_HORIZONTAL, -1, &min, &nat, NULL, NULL);
g_assert_cmpint (min, ==, gdk_pixbuf_get_height (pic));
g_assert_cmpint (nat, ==, gdk_pixbuf_get_height (pic));
gtk_widget_measure (iv, GTK_ORIENTATION_VERTICAL, -1, &min, &nat, NULL, NULL);
g_assert_cmpint (min, ==, gdk_pixbuf_get_width (pic));
g_assert_cmpint (nat, ==, gdk_pixbuf_get_width (pic));
}
void
image_rotated_scaled ()
{
int min, nat;
GtkWidget *iv;
GdkPixbuf *pic;
GdkTexture *texture;
iv = gtk_image_view_new ();
pic = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 100, 200);
texture = gdk_texture_new_for_pixbuf (pic);
gtk_image_view_set_paintable (GTK_IMAGE_VIEW (iv), GDK_PAINTABLE (texture));
gtk_image_view_set_angle (GTK_IMAGE_VIEW (iv), 90.0);
gtk_widget_measure (iv, GTK_ORIENTATION_HORIZONTAL, -1, &min, &nat, NULL, NULL);
g_assert_cmpint (min, ==, gdk_pixbuf_get_height (pic));
g_assert_cmpint (nat, ==, gdk_pixbuf_get_height (pic));
gtk_widget_measure (iv, GTK_ORIENTATION_VERTICAL, -1, &min, &nat, NULL, NULL);
g_assert_cmpint (min, ==, gdk_pixbuf_get_width (pic));
g_assert_cmpint (nat, ==, gdk_pixbuf_get_width (pic));
gtk_image_view_set_scale (GTK_IMAGE_VIEW (iv), 0.5);
gtk_widget_measure (iv, GTK_ORIENTATION_HORIZONTAL, -1, &min, &nat, NULL, NULL);
g_assert_cmpint (min, ==, gdk_pixbuf_get_height (pic) * 0.5);
g_assert_cmpint (nat, ==, gdk_pixbuf_get_height (pic) * 0.5);
gtk_widget_measure (iv, GTK_ORIENTATION_VERTICAL, -1, &min, &nat, NULL, NULL);
g_assert_cmpint (min, ==, gdk_pixbuf_get_width (pic) * 0.5);
g_assert_cmpint (nat, ==, gdk_pixbuf_get_width (pic) * 0.5);
}
int
main (int argc, char **argv)
{
gtk_init ();
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/sizing/imageview/empty", empty);
g_test_add_func ("/sizing/imageview/image-fit-allocation", image_fit_allocation);
g_test_add_func ("/sizing/imageview/image-no-fit-allocation", image_no_fit_allocation);
g_test_add_func ("/sizing/imageview/image-scaled", image_scaled);
g_test_add_func ("/sizing/imageview/image-rotated", image_rotated);
g_test_add_func ("/sizing/imageview/image-rotated-scaled", image_rotated_scaled);
return g_test_run ();
}

View File

@@ -71,6 +71,7 @@ tests = [
['displayclose'],
['revealer-size'],
['widgetorder'],
['imageview-size'],
]
test_cargs = []