/* PIKA - Photo and Image Kooker Application * a rebranding of The GNU Image Manipulation Program (created with heckimp) * A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio * * Original copyright, applying to most contents (license remains unchanged): * Copyright (C) 1995 Spencer Kimball and Peter Mattis * * 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 . */ #include "config.h" #include #include "core-types.h" #include "core/pikasubprogress.h" #include "core/pikaprogress.h" enum { PROP_0, PROP_PROGRESS }; static void pika_sub_progress_iface_init (PikaProgressInterface *iface); static void pika_sub_progress_finalize (GObject *object); static void pika_sub_progress_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void pika_sub_progress_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static PikaProgress * pika_sub_progress_start (PikaProgress *progress, gboolean cancellable, const gchar *message); static void pika_sub_progress_end (PikaProgress *progress); static gboolean pika_sub_progress_is_active (PikaProgress *progress); static void pika_sub_progress_set_text (PikaProgress *progress, const gchar *message); static void pika_sub_progress_set_value (PikaProgress *progress, gdouble percentage); static gdouble pika_sub_progress_get_value (PikaProgress *progress); static void pika_sub_progress_pulse (PikaProgress *progress); static GBytes * pika_sub_progress_get_window_id (PikaProgress *progress); static gboolean pika_sub_progress_message (PikaProgress *progress, Pika *pika, PikaMessageSeverity severity, const gchar *domain, const gchar *message); G_DEFINE_TYPE_WITH_CODE (PikaSubProgress, pika_sub_progress, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (PIKA_TYPE_PROGRESS, pika_sub_progress_iface_init)) #define parent_class pika_sub_progress_parent_class static void pika_sub_progress_class_init (PikaSubProgressClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = pika_sub_progress_finalize; object_class->set_property = pika_sub_progress_set_property; object_class->get_property = pika_sub_progress_get_property; g_object_class_install_property (object_class, PROP_PROGRESS, g_param_spec_object ("progress", NULL, NULL, PIKA_TYPE_PROGRESS, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } static void pika_sub_progress_init (PikaSubProgress *sub) { sub->progress = NULL; sub->start = 0.0; sub->end = 1.0; } static void pika_sub_progress_finalize (GObject *object) { PikaSubProgress *sub = PIKA_SUB_PROGRESS (object); g_clear_object (&sub->progress); G_OBJECT_CLASS (parent_class)->finalize (object); } static void pika_sub_progress_iface_init (PikaProgressInterface *iface) { iface->start = pika_sub_progress_start; iface->end = pika_sub_progress_end; iface->is_active = pika_sub_progress_is_active; iface->set_text = pika_sub_progress_set_text; iface->set_value = pika_sub_progress_set_value; iface->get_value = pika_sub_progress_get_value; iface->pulse = pika_sub_progress_pulse; iface->get_window_id = pika_sub_progress_get_window_id; iface->message = pika_sub_progress_message; } static void pika_sub_progress_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { PikaSubProgress *sub = PIKA_SUB_PROGRESS (object); switch (property_id) { case PROP_PROGRESS: g_return_if_fail (sub->progress == NULL); sub->progress = g_value_dup_object (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void pika_sub_progress_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { PikaSubProgress *sub = PIKA_SUB_PROGRESS (object); switch (property_id) { case PROP_PROGRESS: g_value_set_object (value, sub->progress); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static PikaProgress * pika_sub_progress_start (PikaProgress *progress, gboolean cancellable, const gchar *message) { /* does nothing */ return NULL; } static void pika_sub_progress_end (PikaProgress *progress) { /* does nothing */ } static gboolean pika_sub_progress_is_active (PikaProgress *progress) { PikaSubProgress *sub = PIKA_SUB_PROGRESS (progress); if (sub->progress) return pika_progress_is_active (sub->progress); return FALSE; } static void pika_sub_progress_set_text (PikaProgress *progress, const gchar *message) { /* does nothing */ } static void pika_sub_progress_set_value (PikaProgress *progress, gdouble percentage) { PikaSubProgress *sub = PIKA_SUB_PROGRESS (progress); if (sub->progress) pika_progress_set_value (sub->progress, sub->start + percentage * (sub->end - sub->start)); } static gdouble pika_sub_progress_get_value (PikaProgress *progress) { PikaSubProgress *sub = PIKA_SUB_PROGRESS (progress); if (sub->progress) return pika_progress_get_value (sub->progress); return 0.0; } static void pika_sub_progress_pulse (PikaProgress *progress) { PikaSubProgress *sub = PIKA_SUB_PROGRESS (progress); if (sub->progress) pika_progress_pulse (sub->progress); } static GBytes * pika_sub_progress_get_window_id (PikaProgress *progress) { PikaSubProgress *sub = PIKA_SUB_PROGRESS (progress); if (sub->progress) return pika_progress_get_window_id (sub->progress); return NULL; } static gboolean pika_sub_progress_message (PikaProgress *progress, Pika *pika, PikaMessageSeverity severity, const gchar *domain, const gchar *message) { PikaSubProgress *sub = PIKA_SUB_PROGRESS (progress); if (sub->progress) return pika_progress_message (sub->progress, pika, severity, domain, message); return FALSE; } /** * pika_sub_progress_new: * @progress: parent progress or %NULL * * PikaSubProgress implements the PikaProgress interface and can be * used wherever a PikaProgress is needed. It maps progress * information to a sub-range of its parent @progress. This is useful * when an action breaks down into multiple sub-actions that itself * need a #PikaProgress pointer. See pika_image_scale() for an example. * * Returns: a new #PikaProgress object */ PikaProgress * pika_sub_progress_new (PikaProgress *progress) { PikaSubProgress *sub; g_return_val_if_fail (progress == NULL || PIKA_IS_PROGRESS (progress), NULL); sub = g_object_new (PIKA_TYPE_SUB_PROGRESS, "progress", progress, NULL); return PIKA_PROGRESS (sub); } /** * pika_sub_progress_set_range: * @start: start value of range on the parent process * @end: end value of range on the parent process * * Sets a range on the parent progress that this @progress should be * mapped to. */ void pika_sub_progress_set_range (PikaSubProgress *progress, gdouble start, gdouble end) { g_return_if_fail (PIKA_IS_SUB_PROGRESS (progress)); g_return_if_fail (start < end); progress->start = start; progress->end = end; } /** * pika_sub_progress_set_step: * @index: step index * @num_steps: number of steps * * A more convenient form of pika_sub_progress_set_range(). */ void pika_sub_progress_set_step (PikaSubProgress *progress, gint index, gint num_steps) { g_return_if_fail (PIKA_IS_SUB_PROGRESS (progress)); g_return_if_fail (index < num_steps && num_steps > 0); progress->start = (gdouble) index / num_steps; progress->end = (gdouble) (index + 1) / num_steps; }