Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quellcode-Bibliothek 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

¤ 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.0.11Bemerkung:  (vorverarbeitet am  2026-07-02) ¤

*Bot Zugriff






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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik