Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Gnome/demos/gtk-demo/   (Gnome Linux Desktop Version 4.23.2©)  Datei vom 30.5.2026 mit Größe 9 kB image not shown  

Quelle  image_scaling.c

  Sprache: C
 

/* Image Scaling
 * #Keywords: zoom, scale, filter, action, menu
 *
 * The custom widget we create here is similar to a GtkPicture,
 * but allows setting a zoom level and filtering mode for the
 * displayed paintable.
 *
 * It also demonstrates how to add a context menu to a custom
 * widget and connect it with widget actions.
 *
 * The context menu has items to change the zoom level.
 */


#include <gtk/gtk.h>
#include "imageview.h"


static GtkWidget *window = NULL;
static GCancellable *cancellable = NULL;

static void
load_texture (GTask        *task,
              gpointer      source_object,
              gpointer      task_data,
              GCancellable *cable)
{
  GFile *file = task_data;
  GdkTexture *texture;
  GError *error = NULL;

  texture = gdk_texture_new_from_file (file, &error);

  if (texture)
    g_task_return_pointer (task, texture, g_object_unref);
  else
    g_task_return_error (task, error);
}

static void
set_wait_cursor (GtkWidget *widget)
{
  gtk_widget_set_cursor_from_name (GTK_WIDGET (gtk_widget_get_root (widget)), "wait");
}

static void
unset_wait_cursor (GtkWidget *widget)
{
  gtk_widget_set_cursor (GTK_WIDGET (gtk_widget_get_root (widget)), NULL);
}

static void
texture_loaded (GObject      *source,
                GAsyncResult *result,
                gpointer      data)
{
  GdkTexture *texture;
  GError *error = NULL;

  texture = g_task_propagate_pointer (G_TASK (result), &error);

  if (!texture)
    {
      g_print ("%s\n", error->message);
      g_error_free (error);
      return;
    }

  if (!window)
    {
      g_object_unref (texture);
      return;
    }

  unset_wait_cursor (GTK_WIDGET (data));

  g_object_set (G_OBJECT (data), "texture", texture, NULL);
}

static void
open_file_async (GFile     *file,
                 GtkWidget *demo)
{
  GTask *task;

  set_wait_cursor (demo);

  task = g_task_new (demo, cancellable, texture_loaded, demo);
  g_task_set_source_tag (task, open_file_async);
  g_task_set_task_data (task, g_object_ref (file), g_object_unref);
  g_task_run_in_thread (task, load_texture);
  g_object_unref (task);
}

static void
open_portland_rose (GtkWidget *button,
                    GtkWidget *demo)
{
  GFile *file;

  file = g_file_new_for_uri ("resource:///transparent/portland-rose.jpg");
  open_file_async (file, demo);
  g_object_unref (file);
}

static void
open_large_image (GtkWidget *button,
                  GtkWidget *demo)
{
  GFile *file;

  file = g_file_new_for_uri ("resource:///org/gtk/Demo4/large-image.png");
  open_file_async (file, demo);
  g_object_unref (file);
}

static void
file_opened (GObject      *source,
             GAsyncResult *result,
             void         *data)
{
  GFile *file;
  GError *error = NULL;

  file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);

  if (!file)
    {
      g_print ("%s\n", error->message);
      g_error_free (error);
      return;
    }

  open_file_async (file, data);

  g_object_unref (file);
}

static void
open_file (GtkWidget *picker,
           GtkWidget *demo)
{
  GtkWindow *parent = GTK_WINDOW (gtk_widget_get_root (picker));
  GtkFileDialog *dialog;
  GtkFileFilter *filter;
  GListStore *filters;

  dialog = gtk_file_dialog_new ();

  filter = gtk_file_filter_new ();
  gtk_file_filter_set_name (filter, "Images");
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  gtk_file_filter_add_pixbuf_formats (filter);
G_GNUC_END_IGNORE_DEPRECATIONS
  filters = g_list_store_new (GTK_TYPE_FILE_FILTER);
  g_list_store_append (filters, filter);
  g_object_unref (filter);

  gtk_file_dialog_set_filters (dialog, G_LIST_MODEL (filters));
  g_object_unref (filters);

  gtk_file_dialog_open (dialog, parent, NULL, file_opened, demo);

  g_object_unref (dialog);
}

static void
rotate (GtkWidget *button,
        GtkWidget *demo)
{
  float angle;

  g_object_get (demo, "angle", &angle, NULL);

  angle = fmodf (angle + 90.f, 360.f);

  g_object_set (demo, "angle", angle, NULL);
}

static gboolean
transform_to (GBinding     *binding,
              const GValue *src,
              GValue       *dest,
              gpointer      user_data)
{
  double from;
  float to;

  from = g_value_get_double (src);
  to = (float) pow (2., from);
  g_value_set_float (dest, to);

  return TRUE;
}

static gboolean
transform_from (GBinding     *binding,
                const GValue *src,
                GValue       *dest,
                gpointer      user_data)
{
  float to;
  double from;

  to = g_value_get_float (src);
  from = log2 (to);
  g_value_set_double (dest, from);

  return TRUE;
}

static void
free_cancellable (gpointer data)
{
  g_cancellable_cancel (cancellable);
  g_clear_object (&cancellable);
}

static gboolean
cancel_load (GtkWidget *widget,
             GVariant  *args,
             gpointer   data)
{
  unset_wait_cursor (widget);
  g_cancellable_cancel (G_CANCELLABLE (data));
  return TRUE;
}

GtkWidget *
do_image_scaling (GtkWidget *do_widget)
{
  if (!window)
    {
      GtkWidget *box;
      GtkWidget *box2;
      GtkWidget *sw;
      GtkWidget *vp;
      GtkWidget *widget;
      GtkWidget *scale;
      GtkWidget *dropdown;
      GtkWidget *button;
      GtkEventController *controller;

      window = gtk_window_new ();
      gtk_window_set_title (GTK_WINDOW (window), "Image Scaling");
      gtk_window_set_default_size (GTK_WINDOW (window), 600400);
      gtk_window_set_display (GTK_WINDOW (window),
                              gtk_widget_get_display (do_widget));
      g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);

      cancellable = g_cancellable_new ();
      g_object_set_data_full (G_OBJECT (window), "cancellable",
                              cancellable, free_cancellable);

      controller = gtk_shortcut_controller_new ();
      gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
                                            gtk_shortcut_new (
                                                gtk_keyval_trigger_new (GDK_KEY_Escape, 0),
                                                gtk_callback_action_new (cancel_load, cancellable, NULL)
                                                ));
      gtk_shortcut_controller_set_scope (GTK_SHORTCUT_CONTROLLER (controller),
                                         GTK_SHORTCUT_SCOPE_GLOBAL);
      gtk_widget_add_controller (window, controller);

      box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
      gtk_window_set_child (GTK_WINDOW (window), box);

      sw = gtk_scrolled_window_new ();
      gtk_widget_set_vexpand (sw, TRUE);
      gtk_box_append (GTK_BOX (box), sw);

      widget = image_view_new ("/transparent/portland-rose.jpg");
      vp = gtk_viewport_new (NULL, NULL);
      gtk_viewport_set_scroll_to_focus (GTK_VIEWPORT (vp), FALSE);

      gtk_viewport_set_child (GTK_VIEWPORT (vp), widget);
      gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), vp);

      box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
      gtk_box_append (GTK_BOX (box), box2);

      button = gtk_button_new_from_icon_name ("document-open-symbolic");
      gtk_widget_set_tooltip_text (button, "Open File");
      g_signal_connect (button, "clicked", G_CALLBACK (open_file), widget);
      gtk_box_append (GTK_BOX (box2), button);

      button = gtk_button_new ();
      gtk_button_set_child (GTK_BUTTON (button),
                            gtk_image_new_from_resource ("/org/gtk/Demo4/portland-rose-thumbnail.png"));
      gtk_widget_add_css_class (button, "image-button");
      gtk_widget_set_tooltip_text (button, "Portland Rose");
      g_signal_connect (button, "clicked", G_CALLBACK (open_portland_rose), widget);
      gtk_box_append (GTK_BOX (box2), button);

      button = gtk_button_new ();
      gtk_button_set_child (GTK_BUTTON (button),
                            gtk_image_new_from_resource ("/org/gtk/Demo4/large-image-thumbnail.png"));
      gtk_widget_add_css_class (button, "image-button");
      gtk_widget_set_tooltip_text (button, "Large image");
      g_signal_connect (button, "clicked", G_CALLBACK (open_large_image), widget);
      gtk_box_append (GTK_BOX (box2), button);

      button = gtk_button_new_from_icon_name ("object-rotate-right-symbolic");
      gtk_widget_set_tooltip_text (button, "Rotate");
      g_signal_connect (button, "clicked", G_CALLBACK (rotate), widget);
      gtk_box_append (GTK_BOX (box2), button);

      scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, -10., 10., 0.1);
      gtk_scale_add_mark (GTK_SCALE (scale), 0., GTK_POS_TOP, NULL);
      gtk_widget_set_tooltip_text (scale, "Zoom");
      gtk_accessible_update_property (GTK_ACCESSIBLE (scale),
                                      GTK_ACCESSIBLE_PROPERTY_LABEL, "Zoom",
                                      -1);
      gtk_range_set_value (GTK_RANGE (scale), 0.);
      gtk_widget_set_hexpand (scale, TRUE);
      gtk_box_append (GTK_BOX (box2), scale);

      dropdown = gtk_drop_down_new (G_LIST_MODEL (gtk_string_list_new ((const char *[]){ "Linear""Nearest""Trilinear", NULL })), NULL);
      gtk_widget_set_tooltip_text (dropdown, "Filter");
      gtk_accessible_update_property (GTK_ACCESSIBLE (dropdown),
                                      GTK_ACCESSIBLE_PROPERTY_LABEL, "Filter",
                                      -1);
      gtk_box_append (GTK_BOX (box2), dropdown);

      g_object_bind_property (dropdown, "selected", widget, "filter", G_BINDING_DEFAULT);

      g_object_bind_property_full (gtk_range_get_adjustment (GTK_RANGE (scale)), "value",
                                   widget, "scale",
                                   G_BINDING_BIDIRECTIONAL,
                                   transform_to,
                                   transform_from,
                                   NULL, NULL);
    }

  if (!gtk_widget_get_visible (window))
    gtk_widget_set_visible (window, TRUE);
  else
    {
      gtk_window_destroy (GTK_WINDOW (window));
    }

  return window;
}

Messung V0.5 in Prozent
C=98 H=95 G=96

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet am  2026-07-02) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.