2006-12-10 05:33:38 +08:00
|
|
|
/* GIMP - The GNU Image Manipulation Program Copyright (C) 1995
|
2006-09-01 20:15:14 +08:00
|
|
|
* Spencer Kimball and Peter Mattis
|
2002-02-03 20:10:23 +08:00
|
|
|
*
|
2009-01-18 06:28:01 +08:00
|
|
|
* This program is free software: you can redistribute it and/or modify
|
2002-02-03 20:10:23 +08:00
|
|
|
* it under the terms of the GNU General Public License as published by
|
2009-01-18 06:28:01 +08:00
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
2002-02-03 20:10:23 +08:00
|
|
|
* (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
|
2018-07-12 05:27:07 +08:00
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2002-02-03 20:10:23 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2005-04-01 20:26:32 +08:00
|
|
|
#include <string.h>
|
|
|
|
|
2008-10-10 04:24:04 +08:00
|
|
|
#include <gegl.h>
|
2002-02-03 20:10:23 +08:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
2010-02-21 23:46:39 +08:00
|
|
|
#include "libgimpbase/gimpbase.h"
|
2022-08-08 12:05:53 +08:00
|
|
|
#include "libgimpcolor/gimpcolor.h"
|
2022-08-02 07:22:05 +08:00
|
|
|
#include "libgimpconfig/gimpconfig.h"
|
2007-03-09 21:00:01 +08:00
|
|
|
#include "libgimpmath/gimpmath.h"
|
2004-05-10 18:33:21 +08:00
|
|
|
#include "libgimpwidgets/gimpwidgets.h"
|
|
|
|
|
2002-02-03 20:10:23 +08:00
|
|
|
#include "display-types.h"
|
|
|
|
|
2008-03-19 05:22:21 +08:00
|
|
|
#include "config/gimpdisplayconfig.h"
|
|
|
|
|
2022-08-08 12:05:53 +08:00
|
|
|
#include "core/gimp.h"
|
|
|
|
#include "core/gimpcontext.h"
|
2002-02-03 20:10:23 +08:00
|
|
|
#include "core/gimpimage.h"
|
2022-08-02 07:22:05 +08:00
|
|
|
#include "core/gimpimage-color-profile.h"
|
2004-08-11 02:47:21 +08:00
|
|
|
#include "core/gimpprogress.h"
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2023-01-31 21:17:00 +08:00
|
|
|
#include "widgets/gimpaction.h"
|
2006-10-09 16:17:22 +08:00
|
|
|
#include "widgets/gimpwidgets-utils.h"
|
2004-05-08 06:16:15 +08:00
|
|
|
|
2002-02-03 20:10:23 +08:00
|
|
|
#include "gimpdisplay.h"
|
2002-06-27 06:16:59 +08:00
|
|
|
#include "gimpdisplayshell.h"
|
2004-05-10 18:33:21 +08:00
|
|
|
#include "gimpdisplayshell-scale.h"
|
2009-09-26 07:19:27 +08:00
|
|
|
#include "gimpimagewindow.h"
|
2004-05-10 18:33:21 +08:00
|
|
|
#include "gimpscalecombobox.h"
|
2002-02-03 20:10:23 +08:00
|
|
|
#include "gimpstatusbar.h"
|
|
|
|
|
2003-03-26 00:38:19 +08:00
|
|
|
#include "gimp-intl.h"
|
2002-02-03 20:10:23 +08:00
|
|
|
|
|
|
|
|
2018-05-14 02:36:22 +08:00
|
|
|
/* maximal width of the string holding the cursor-coordinates */
|
2018-04-07 23:46:58 +08:00
|
|
|
#define CURSOR_LEN 256
|
2008-04-14 19:57:23 +08:00
|
|
|
|
2018-05-14 02:36:22 +08:00
|
|
|
/* the spacing of the hbox */
|
2018-04-07 23:46:58 +08:00
|
|
|
#define HBOX_SPACING 1
|
2010-02-12 02:55:20 +08:00
|
|
|
|
2018-05-14 02:36:22 +08:00
|
|
|
/* spacing between the icon and the statusbar label */
|
2018-04-07 23:46:58 +08:00
|
|
|
#define ICON_SPACING 2
|
2007-01-08 23:41:47 +08:00
|
|
|
|
2018-05-14 02:36:22 +08:00
|
|
|
/* timeout (in milliseconds) for temporary statusbar messages */
|
2018-04-07 23:46:58 +08:00
|
|
|
#define MESSAGE_TIMEOUT 8000
|
|
|
|
|
|
|
|
/* minimal interval (in microseconds) between progress updates */
|
|
|
|
#define MIN_PROGRESS_UPDATE_INTERVAL 50000
|
2007-01-08 23:41:47 +08:00
|
|
|
|
|
|
|
|
2004-06-19 21:31:58 +08:00
|
|
|
typedef struct _GimpStatusbarMsg GimpStatusbarMsg;
|
|
|
|
|
|
|
|
struct _GimpStatusbarMsg
|
|
|
|
{
|
|
|
|
guint context_id;
|
2014-05-07 21:30:38 +08:00
|
|
|
gchar *icon_name;
|
2004-07-15 00:37:13 +08:00
|
|
|
gchar *text;
|
2004-06-19 21:31:58 +08:00
|
|
|
};
|
|
|
|
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2005-12-11 03:24:36 +08:00
|
|
|
static void gimp_statusbar_progress_iface_init (GimpProgressInterface *iface);
|
2004-08-11 02:47:21 +08:00
|
|
|
|
2010-09-27 04:35:49 +08:00
|
|
|
static void gimp_statusbar_dispose (GObject *object);
|
2006-09-01 20:15:14 +08:00
|
|
|
static void gimp_statusbar_finalize (GObject *object);
|
2004-08-11 02:47:21 +08:00
|
|
|
|
2014-05-31 01:38:17 +08:00
|
|
|
static void gimp_statusbar_screen_changed (GtkWidget *widget,
|
|
|
|
GdkScreen *previous);
|
2010-12-23 06:34:47 +08:00
|
|
|
static void gimp_statusbar_style_updated (GtkWidget *widget);
|
2014-05-31 01:38:17 +08:00
|
|
|
|
2004-08-11 02:47:21 +08:00
|
|
|
static GimpProgress *
|
2004-08-11 18:29:56 +08:00
|
|
|
gimp_statusbar_progress_start (GimpProgress *progress,
|
2014-07-13 05:45:20 +08:00
|
|
|
gboolean cancellable,
|
|
|
|
const gchar *message);
|
2004-08-11 18:29:56 +08:00
|
|
|
static void gimp_statusbar_progress_end (GimpProgress *progress);
|
|
|
|
static gboolean gimp_statusbar_progress_is_active (GimpProgress *progress);
|
|
|
|
static void gimp_statusbar_progress_set_text (GimpProgress *progress,
|
|
|
|
const gchar *message);
|
|
|
|
static void gimp_statusbar_progress_set_value (GimpProgress *progress,
|
|
|
|
gdouble percentage);
|
|
|
|
static gdouble gimp_statusbar_progress_get_value (GimpProgress *progress);
|
2005-02-12 22:18:12 +08:00
|
|
|
static void gimp_statusbar_progress_pulse (GimpProgress *progress);
|
2006-10-09 16:17:22 +08:00
|
|
|
static gboolean gimp_statusbar_progress_message (GimpProgress *progress,
|
|
|
|
Gimp *gimp,
|
|
|
|
GimpMessageSeverity severity,
|
|
|
|
const gchar *domain,
|
|
|
|
const gchar *message);
|
2004-08-11 18:29:56 +08:00
|
|
|
static void gimp_statusbar_progress_canceled (GtkWidget *button,
|
|
|
|
GimpStatusbar *statusbar);
|
2022-08-02 07:22:05 +08:00
|
|
|
static void gimp_statusbar_soft_proof_button_toggled
|
|
|
|
(GtkWidget *button,
|
|
|
|
GimpStatusbar *statusbar);
|
2022-08-08 12:05:53 +08:00
|
|
|
static void gimp_statusbar_soft_proof_profile_changed
|
|
|
|
(GtkComboBox *combo,
|
|
|
|
GimpStatusbar *statusbar);
|
|
|
|
static void gimp_statusbar_soft_proof_rendering_intent_changed
|
|
|
|
(GtkComboBox *combo,
|
|
|
|
GimpStatusbar *statusbar);
|
|
|
|
static void gimp_statusbar_soft_proof_bpc_toggled
|
|
|
|
(GtkWidget *button,
|
|
|
|
GimpStatusbar *statusbar);
|
|
|
|
static void gimp_statusbar_soft_proof_optimize_changed
|
|
|
|
(GtkWidget *button,
|
|
|
|
GimpStatusbar *statusbar);
|
|
|
|
static void gimp_statusbar_soft_proof_gamut_toggled
|
|
|
|
(GtkWidget *button,
|
|
|
|
GimpStatusbar *statusbar);
|
|
|
|
static gboolean gimp_statusbar_soft_proof_popover_shown
|
|
|
|
(GtkWidget *button,
|
|
|
|
GdkEventButton *bevent,
|
|
|
|
GimpStatusbar *statusbar);
|
2023-12-16 21:12:31 +08:00
|
|
|
static void gimp_statusbar_soft_proof_size_allocate
|
|
|
|
(GtkWidget *widget,
|
|
|
|
GtkAllocation *allocation,
|
|
|
|
GimpStatusbar *statusbar);
|
2004-08-11 18:29:56 +08:00
|
|
|
|
2010-10-20 02:26:16 +08:00
|
|
|
static gboolean gimp_statusbar_label_draw (GtkWidget *widget,
|
|
|
|
cairo_t *cr,
|
2006-09-23 00:44:47 +08:00
|
|
|
GimpStatusbar *statusbar);
|
|
|
|
|
2004-08-11 18:29:56 +08:00
|
|
|
static void gimp_statusbar_update (GimpStatusbar *statusbar);
|
|
|
|
static void gimp_statusbar_unit_changed (GimpUnitComboBox *combo,
|
|
|
|
GimpStatusbar *statusbar);
|
|
|
|
static void gimp_statusbar_scale_changed (GimpScaleComboBox *combo,
|
|
|
|
GimpStatusbar *statusbar);
|
2009-09-24 15:35:34 +08:00
|
|
|
static void gimp_statusbar_scale_activated (GimpScaleComboBox *combo,
|
|
|
|
GimpStatusbar *statusbar);
|
2022-08-08 12:05:53 +08:00
|
|
|
static void gimp_statusbar_shell_image_changed(GimpStatusbar *statusbar,
|
|
|
|
GimpImage *image,
|
|
|
|
GimpContext *context);
|
|
|
|
static void gimp_statusbar_shell_image_simulation_changed
|
2022-08-02 07:22:05 +08:00
|
|
|
(GimpImage *image,
|
|
|
|
GimpStatusbar *statusbar);
|
|
|
|
|
2017-11-16 02:56:33 +08:00
|
|
|
static gboolean gimp_statusbar_rotate_pressed (GtkWidget *event_box,
|
|
|
|
GdkEvent *event,
|
|
|
|
GimpStatusbar *statusbar);
|
|
|
|
static gboolean gimp_statusbar_horiz_flip_pressed (GtkWidget *event_box,
|
|
|
|
GdkEvent *event,
|
|
|
|
GimpStatusbar *statusbar);
|
|
|
|
static gboolean gimp_statusbar_vert_flip_pressed (GtkWidget *event_box,
|
|
|
|
GdkEvent *event,
|
|
|
|
GimpStatusbar *statusbar);
|
2004-08-11 18:29:56 +08:00
|
|
|
static void gimp_statusbar_shell_scaled (GimpDisplayShell *shell,
|
|
|
|
GimpStatusbar *statusbar);
|
2017-11-15 10:37:20 +08:00
|
|
|
static void gimp_statusbar_shell_rotated (GimpDisplayShell *shell,
|
|
|
|
GimpStatusbar *statusbar);
|
2009-10-04 21:31:38 +08:00
|
|
|
static void gimp_statusbar_shell_status_notify(GimpDisplayShell *shell,
|
|
|
|
const GParamSpec *pspec,
|
|
|
|
GimpStatusbar *statusbar);
|
2022-08-02 07:22:05 +08:00
|
|
|
static void gimp_statusbar_shell_color_config_notify
|
|
|
|
(GObject *config,
|
|
|
|
const GParamSpec *pspec,
|
|
|
|
GimpStatusbar *statusbar);
|
2022-08-08 12:05:53 +08:00
|
|
|
static void gimp_statusbar_shell_set_image (GimpStatusbar *statusbar,
|
|
|
|
GimpImage *image);
|
2022-08-02 07:22:05 +08:00
|
|
|
|
2004-08-11 18:29:56 +08:00
|
|
|
static guint gimp_statusbar_get_context_id (GimpStatusbar *statusbar,
|
|
|
|
const gchar *context);
|
2006-09-23 00:44:47 +08:00
|
|
|
static gboolean gimp_statusbar_temp_timeout (GimpStatusbar *statusbar);
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2020-06-18 18:05:47 +08:00
|
|
|
static void gimp_statusbar_add_size_widget (GimpStatusbar *statusbar,
|
|
|
|
GtkWidget *widget);
|
|
|
|
static void gimp_statusbar_update_size (GimpStatusbar *statusbar);
|
|
|
|
|
2016-04-20 16:25:14 +08:00
|
|
|
static void gimp_statusbar_add_message (GimpStatusbar *statusbar,
|
|
|
|
guint context_id,
|
|
|
|
const gchar *icon_name,
|
|
|
|
const gchar *format,
|
|
|
|
va_list args,
|
|
|
|
gboolean move_to_front) G_GNUC_PRINTF (4, 0);
|
|
|
|
static void gimp_statusbar_remove_message (GimpStatusbar *statusbar,
|
|
|
|
guint context_id);
|
2006-10-09 16:17:22 +08:00
|
|
|
static void gimp_statusbar_msg_free (GimpStatusbarMsg *msg);
|
|
|
|
|
2007-02-14 21:13:40 +08:00
|
|
|
static gchar * gimp_statusbar_vprintf (const gchar *format,
|
2013-11-29 07:33:05 +08:00
|
|
|
va_list args) G_GNUC_PRINTF (1, 0);
|
2007-02-14 21:13:40 +08:00
|
|
|
|
2014-05-31 01:38:17 +08:00
|
|
|
static GdkPixbuf * gimp_statusbar_load_icon (GimpStatusbar *statusbar,
|
|
|
|
const gchar *icon_name);
|
|
|
|
|
macos: Fix 7690 (slow drawing)
Gets drawing in the canvas speed on retina displays up to the speed
of FullHD displays on macOS, making 2.99 usable on macOS.
Generic change:
Changes the cursor_label to delay the drawing phase to the idle
queue, from immediate draw on all platforms.
Before the fix in 32049afd (using a deprecated function in Gtk3)
any draws on this label forced a full canvas redraw. This is due
to a quirk in how GtkLabel functions.
The redraw occurred because GtkLabels resize themselves and everything
around them by sending a resize message any time they receive new
text. These resizes then trigger the full canvas resize which triggers
a full canvas redraw that cannot be optimized by either Gtk or Big Sur.
MacOS changes:
Only redraws the cursor position label and each of the horizontal and
vertical rules (cursor tracking widgets) 3 times a second max for a
total of 9 redraws a second (ideally out of 60, though I don't believe
under any circumstances that GIMP achieves a 60fps).
Each of the cursor tracking widgets gets its own timeslice, and so
will not redraw when the other cursor tracking widgets are drawing.
This is required because Big Sur is merging all draw rects into
one large rect, dramatically slowing down draws.
This timeslicing ensures that draw rects are maintained at the smallest
possible size. So the typical redraw is a small rect around the
brush. However, 9 times a second, the rect will include one of the
3 cursor tracking widgets (rulers and cursor label).
Additionally, the code tries to minimize resizing the width of the
cursor label by checking if the widget is too small for the text,
then setting the char_width to a greater size so that resizes won't
be that common.
This improves the appearance of the widget as it no longer
constantly jumps about in size on each cursor move.
Here is a discussion of the issue:
https://gitlab.gnome.org/GNOME/gimp/-/merge_requests/572#note_1389445
Reviewer's (Jehan) notes:
* The whole issue about GtkLabel resizing is no more after 32049afd. It
is normal for a widget to request a resize when needed. We just don't
want the statusbar to resize and triggering canvas redraws.
* Changing cursor position text into an idle function generally makes
sense.
Also it reverts commit 6de9ea70223 which had a bug I hadn't realized
when I accepted it: when we test for time, we don't know yet if it
will be the last position change, hence we could "refuse" the last
update. Therefore displayed cursor position would end up outdated
on macOS. This new implementation doesn't have the problem (the last
idle update always happens after the last move).
* The change about giving 1/3 timeslices to side canvas components
(rulers and statusbar) is a complete hack to work around the fact that
macOs doesn't report properly each damaged rectangle. Instead it
returns a huge bounding box. The workaround here is to expose these
area separately.
We have not been able to find a proper solution yet. This is the only
reason why I accept this code, for macOS only, to at least have
something usable there.
See discussions in MRs gimp!572 and gimp-macos-build!86. With these 2
MRs, Lukas reported GIMP 2.99 to perform even better than GIMP 2.10 on
Monterey, though it could not be tested on Big Sur unfortunately.
* Lastly the set_width_chars() thing is also an ugly hack which I will
try later to revisit (see !581). I only accepted it (with mandatory
macOS-only macro) to have an acceptable state for release after seeing
a screencast where the label size indeed "jumps around" on macOS.
2022-02-19 09:25:51 +08:00
|
|
|
static gboolean gimp_statusbar_queue_pos_redraw (gpointer data);
|
|
|
|
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2018-05-14 02:36:22 +08:00
|
|
|
G_DEFINE_TYPE_WITH_CODE (GimpStatusbar, gimp_statusbar, GTK_TYPE_FRAME,
|
2005-12-11 03:24:36 +08:00
|
|
|
G_IMPLEMENT_INTERFACE (GIMP_TYPE_PROGRESS,
|
2006-05-15 17:46:31 +08:00
|
|
|
gimp_statusbar_progress_iface_init))
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2005-12-11 03:24:36 +08:00
|
|
|
#define parent_class gimp_statusbar_parent_class
|
2002-02-03 20:10:23 +08:00
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_statusbar_class_init (GimpStatusbarClass *klass)
|
|
|
|
{
|
2014-05-31 01:38:17 +08:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
|
|
|
|
|
|
|
object_class->dispose = gimp_statusbar_dispose;
|
|
|
|
object_class->finalize = gimp_statusbar_finalize;
|
2006-10-02 16:56:12 +08:00
|
|
|
|
2014-05-31 01:38:17 +08:00
|
|
|
widget_class->screen_changed = gimp_statusbar_screen_changed;
|
2010-12-23 06:34:47 +08:00
|
|
|
widget_class->style_updated = gimp_statusbar_style_updated;
|
2018-05-14 02:36:22 +08:00
|
|
|
|
|
|
|
gtk_widget_class_set_css_name (widget_class, "statusbar");
|
2002-02-03 20:10:23 +08:00
|
|
|
}
|
|
|
|
|
2006-09-23 00:44:47 +08:00
|
|
|
static void
|
|
|
|
gimp_statusbar_progress_iface_init (GimpProgressInterface *iface)
|
|
|
|
{
|
|
|
|
iface->start = gimp_statusbar_progress_start;
|
|
|
|
iface->end = gimp_statusbar_progress_end;
|
|
|
|
iface->is_active = gimp_statusbar_progress_is_active;
|
|
|
|
iface->set_text = gimp_statusbar_progress_set_text;
|
|
|
|
iface->set_value = gimp_statusbar_progress_set_value;
|
|
|
|
iface->get_value = gimp_statusbar_progress_get_value;
|
|
|
|
iface->pulse = gimp_statusbar_progress_pulse;
|
2006-10-09 16:17:22 +08:00
|
|
|
iface->message = gimp_statusbar_progress_message;
|
2006-09-23 00:44:47 +08:00
|
|
|
}
|
|
|
|
|
2002-02-03 20:10:23 +08:00
|
|
|
static void
|
|
|
|
gimp_statusbar_init (GimpStatusbar *statusbar)
|
|
|
|
{
|
2008-03-27 18:43:55 +08:00
|
|
|
GtkWidget *hbox;
|
2013-03-18 08:26:44 +08:00
|
|
|
GtkWidget *hbox2;
|
2008-03-27 20:17:45 +08:00
|
|
|
GtkWidget *image;
|
2018-06-04 21:13:23 +08:00
|
|
|
GtkWidget *label;
|
2022-08-08 12:05:53 +08:00
|
|
|
GtkWidget *grid;
|
|
|
|
GtkWidget *separator;
|
2022-08-18 22:42:39 +08:00
|
|
|
GtkWidget *profile_chooser;
|
2004-05-08 06:16:15 +08:00
|
|
|
GimpUnitStore *store;
|
2022-08-08 12:05:53 +08:00
|
|
|
gchar *text;
|
|
|
|
GFile *file;
|
|
|
|
GtkListStore *combo_store;
|
|
|
|
gint row;
|
2018-05-14 02:36:22 +08:00
|
|
|
|
|
|
|
gtk_frame_set_shadow_type (GTK_FRAME (statusbar), GTK_SHADOW_IN);
|
|
|
|
|
|
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, HBOX_SPACING);
|
|
|
|
gtk_container_add (GTK_CONTAINER (statusbar), hbox);
|
|
|
|
gtk_widget_show (hbox);
|
2002-02-03 20:10:23 +08:00
|
|
|
|
app: don't propagate resize requests from statusbar to display shell.
See discussion in !572, #7840 and #7690. Note that this was reported on
macOS where the consequences were pretty dire, but it actually also
happens on other platforms, at least on Linux too (as confirmed in X11
with the GTK Inspector set to show graphics updates; on Wayland this
debug option doesn't work, but I assume it is the same).
I am not perfectly happy with this change either, because it is based on
part of the API which has various deprecated parts (hence doesn't exist
anymore on the main dev tree, i.e. it might have to be reviewed in GTK4;
of course, it's unsure, maybe the whole resize propagation to parent
containers is just better handled there and the problem won't exist
anymore).
In any case, it is cleaner than the proposition for this part of the
problem in !572 which is problematic (patching GtkLabel with a new API
which won't trigger resize even when actually needed, hence which likely
won't ever get accepted upstream because it's not right).
2022-02-13 19:55:52 +08:00
|
|
|
/* When changing the text of the cursor_label, it requests a resize
|
|
|
|
* bubbling up to containers, up to the display shell. If the resizing
|
|
|
|
* actually happens (even when the size is the same), a full "draw"
|
|
|
|
* signal is triggered on the whole canvas, which is not a good thing
|
|
|
|
* as a general rule (and very bad on some platforms such as macOS).
|
|
|
|
* It's too late to do anything when processing the "draw" signal
|
|
|
|
* because then we can't know if some part of the invalidated
|
|
|
|
* rectangle really needs to be redrawn. What we do is not propagate
|
|
|
|
* the size request back to container parents. Instead we queue the
|
|
|
|
* resize directly on the widget.
|
|
|
|
*
|
|
|
|
* Note that the "resize-mode" property seems to be unrecommended now
|
|
|
|
* (though only the public functions are deprecated, we get no
|
|
|
|
* deprecation setting as a property) but it's still here in GTK3 and
|
|
|
|
* still seems like the proper way to avoid propagating useless
|
|
|
|
* no-actual-size-change resizes to container widgets.
|
|
|
|
* XXX On GTK4, we will likely have to test again and if it's still a
|
|
|
|
* problem, make a different fix.
|
|
|
|
*
|
|
|
|
* See discussion in MR !572.
|
|
|
|
*/
|
|
|
|
g_object_set (statusbar,
|
|
|
|
"resize-mode", GTK_RESIZE_QUEUE,
|
|
|
|
NULL);
|
|
|
|
|
2006-09-23 00:44:47 +08:00
|
|
|
statusbar->shell = NULL;
|
|
|
|
statusbar->messages = NULL;
|
|
|
|
statusbar->context_ids = g_hash_table_new_full (g_str_hash, g_str_equal,
|
|
|
|
g_free, NULL);
|
|
|
|
statusbar->seq_context_id = 1;
|
|
|
|
|
|
|
|
statusbar->temp_context_id =
|
|
|
|
gimp_statusbar_get_context_id (statusbar, "gimp-statusbar-temp");
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2008-08-21 00:22:09 +08:00
|
|
|
statusbar->cursor_format_str[0] = '\0';
|
|
|
|
statusbar->cursor_format_str_f[0] = '\0';
|
|
|
|
statusbar->length_format_str[0] = '\0';
|
2006-09-23 00:44:47 +08:00
|
|
|
|
2004-11-10 09:17:40 +08:00
|
|
|
statusbar->progress_active = FALSE;
|
2007-05-29 01:42:55 +08:00
|
|
|
statusbar->progress_shown = FALSE;
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2008-03-27 19:38:45 +08:00
|
|
|
statusbar->cursor_label = gtk_label_new ("8888, 8888");
|
2020-06-18 18:05:47 +08:00
|
|
|
gimp_statusbar_add_size_widget (statusbar, statusbar->cursor_label);
|
2018-05-14 02:36:22 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), statusbar->cursor_label,
|
|
|
|
FALSE, FALSE, 0);
|
2002-02-03 20:10:23 +08:00
|
|
|
gtk_widget_show (statusbar->cursor_label);
|
|
|
|
|
2004-05-08 06:16:15 +08:00
|
|
|
store = gimp_unit_store_new (2);
|
2004-05-08 07:31:01 +08:00
|
|
|
statusbar->unit_combo = gimp_unit_combo_box_new_with_model (store);
|
2004-05-08 06:16:15 +08:00
|
|
|
g_object_unref (store);
|
|
|
|
|
2019-03-28 04:50:57 +08:00
|
|
|
/* see issue #2642 */
|
|
|
|
gtk_combo_box_set_wrap_width (GTK_COMBO_BOX (statusbar->unit_combo), 1);
|
|
|
|
|
2009-10-18 01:51:33 +08:00
|
|
|
gtk_widget_set_can_focus (statusbar->unit_combo, FALSE);
|
2005-02-19 05:41:57 +08:00
|
|
|
g_object_set (statusbar->unit_combo, "focus-on-click", FALSE, NULL);
|
2020-06-18 18:05:47 +08:00
|
|
|
gimp_statusbar_add_size_widget (statusbar, statusbar->unit_combo);
|
2018-05-14 02:36:22 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), statusbar->unit_combo,
|
|
|
|
FALSE, FALSE, 0);
|
2004-05-08 07:31:01 +08:00
|
|
|
gtk_widget_show (statusbar->unit_combo);
|
2004-05-08 06:16:15 +08:00
|
|
|
|
2004-05-08 07:31:01 +08:00
|
|
|
g_signal_connect (statusbar->unit_combo, "changed",
|
2004-05-08 06:16:15 +08:00
|
|
|
G_CALLBACK (gimp_statusbar_unit_changed),
|
|
|
|
statusbar);
|
|
|
|
|
2004-05-10 18:33:21 +08:00
|
|
|
statusbar->scale_combo = gimp_scale_combo_box_new ();
|
2009-10-18 01:51:33 +08:00
|
|
|
gtk_widget_set_can_focus (statusbar->scale_combo, FALSE);
|
2005-02-19 05:41:57 +08:00
|
|
|
g_object_set (statusbar->scale_combo, "focus-on-click", FALSE, NULL);
|
2020-06-18 18:05:47 +08:00
|
|
|
gimp_statusbar_add_size_widget (statusbar, statusbar->scale_combo);
|
2018-05-14 02:36:22 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), statusbar->scale_combo,
|
|
|
|
FALSE, FALSE, 0);
|
2004-05-10 18:33:21 +08:00
|
|
|
gtk_widget_show (statusbar->scale_combo);
|
|
|
|
|
|
|
|
g_signal_connect (statusbar->scale_combo, "changed",
|
|
|
|
G_CALLBACK (gimp_statusbar_scale_changed),
|
|
|
|
statusbar);
|
|
|
|
|
2009-09-24 15:35:34 +08:00
|
|
|
g_signal_connect (statusbar->scale_combo, "entry-activated",
|
|
|
|
G_CALLBACK (gimp_statusbar_scale_activated),
|
|
|
|
statusbar);
|
|
|
|
|
2017-11-16 02:56:33 +08:00
|
|
|
/* Shell transform status */
|
2018-06-04 21:13:23 +08:00
|
|
|
statusbar->rotate_widget = gtk_event_box_new ();
|
2020-06-18 18:05:47 +08:00
|
|
|
gimp_statusbar_add_size_widget (statusbar, statusbar->rotate_widget);
|
2018-06-04 21:13:23 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), statusbar->rotate_widget,
|
|
|
|
FALSE, FALSE, 1);
|
|
|
|
gtk_widget_show (statusbar->rotate_widget);
|
|
|
|
|
2017-11-15 10:37:20 +08:00
|
|
|
statusbar->rotate_label = gtk_label_new (NULL);
|
2018-06-04 21:13:23 +08:00
|
|
|
gtk_container_add (GTK_CONTAINER (statusbar->rotate_widget),
|
|
|
|
statusbar->rotate_label);
|
2017-11-15 10:37:20 +08:00
|
|
|
gtk_widget_show (statusbar->rotate_label);
|
|
|
|
|
2018-06-04 21:13:23 +08:00
|
|
|
g_signal_connect (statusbar->rotate_widget, "button-press-event",
|
|
|
|
G_CALLBACK (gimp_statusbar_rotate_pressed),
|
|
|
|
statusbar);
|
2018-05-14 02:36:22 +08:00
|
|
|
|
2018-06-04 21:13:23 +08:00
|
|
|
statusbar->horizontal_flip_icon = gtk_event_box_new ();
|
2020-06-18 18:05:47 +08:00
|
|
|
gimp_statusbar_add_size_widget (statusbar, statusbar->horizontal_flip_icon);
|
2018-06-04 21:13:23 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), statusbar->horizontal_flip_icon,
|
|
|
|
FALSE, FALSE, 1);
|
2018-05-14 02:36:22 +08:00
|
|
|
gtk_widget_show (statusbar->horizontal_flip_icon);
|
|
|
|
|
2018-07-28 01:47:10 +08:00
|
|
|
image = gtk_image_new_from_icon_name ("object-flip-horizontal",
|
2018-06-04 21:13:23 +08:00
|
|
|
GTK_ICON_SIZE_MENU);
|
|
|
|
gtk_container_add (GTK_CONTAINER (statusbar->horizontal_flip_icon), image);
|
|
|
|
gtk_widget_show (image);
|
|
|
|
|
|
|
|
g_signal_connect (statusbar->horizontal_flip_icon, "button-press-event",
|
2017-11-16 02:56:33 +08:00
|
|
|
G_CALLBACK (gimp_statusbar_horiz_flip_pressed),
|
|
|
|
statusbar);
|
|
|
|
|
2018-06-04 21:13:23 +08:00
|
|
|
statusbar->vertical_flip_icon = gtk_event_box_new ();
|
2020-06-18 18:05:47 +08:00
|
|
|
gimp_statusbar_add_size_widget (statusbar, statusbar->vertical_flip_icon);
|
2018-06-04 21:13:23 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), statusbar->vertical_flip_icon,
|
|
|
|
FALSE, FALSE, 1);
|
2018-05-14 02:36:22 +08:00
|
|
|
gtk_widget_show (statusbar->vertical_flip_icon);
|
|
|
|
|
2018-07-28 01:47:10 +08:00
|
|
|
image = gtk_image_new_from_icon_name ("object-flip-vertical",
|
2018-06-04 21:13:23 +08:00
|
|
|
GTK_ICON_SIZE_MENU);
|
|
|
|
gtk_container_add (GTK_CONTAINER (statusbar->vertical_flip_icon), image);
|
|
|
|
gtk_widget_show (image);
|
|
|
|
|
|
|
|
g_signal_connect (statusbar->vertical_flip_icon, "button-press-event",
|
2017-11-16 02:56:33 +08:00
|
|
|
G_CALLBACK (gimp_statusbar_vert_flip_pressed),
|
|
|
|
statusbar);
|
|
|
|
|
2018-05-14 02:36:22 +08:00
|
|
|
statusbar->label = gtk_label_new ("");
|
|
|
|
gtk_label_set_ellipsize (GTK_LABEL (statusbar->label), PANGO_ELLIPSIZE_END);
|
2019-01-03 00:49:53 +08:00
|
|
|
gtk_label_set_justify (GTK_LABEL (statusbar->label), GTK_JUSTIFY_LEFT);
|
|
|
|
gtk_widget_set_halign (statusbar->label, GTK_ALIGN_START);
|
2020-06-18 18:05:47 +08:00
|
|
|
gimp_statusbar_add_size_widget (statusbar, statusbar->label);
|
2010-04-20 15:56:59 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), statusbar->label, TRUE, TRUE, 1);
|
2018-05-14 02:36:22 +08:00
|
|
|
gtk_widget_show (statusbar->label);
|
2008-03-27 18:43:55 +08:00
|
|
|
|
2010-10-20 02:26:16 +08:00
|
|
|
g_signal_connect_after (statusbar->label, "draw",
|
|
|
|
G_CALLBACK (gimp_statusbar_label_draw),
|
2006-09-23 00:44:47 +08:00
|
|
|
statusbar);
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2008-04-06 17:54:30 +08:00
|
|
|
statusbar->progressbar = g_object_new (GTK_TYPE_PROGRESS_BAR,
|
2012-02-18 21:55:57 +08:00
|
|
|
"show-text", TRUE,
|
|
|
|
"ellipsize", PANGO_ELLIPSIZE_END,
|
2008-04-06 17:54:30 +08:00
|
|
|
NULL);
|
2020-06-18 18:05:47 +08:00
|
|
|
gimp_statusbar_add_size_widget (statusbar, statusbar->progressbar);
|
2018-05-14 02:36:22 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), statusbar->progressbar,
|
|
|
|
TRUE, TRUE, 0);
|
2008-04-06 17:54:30 +08:00
|
|
|
/* don't show the progress bar */
|
|
|
|
|
2013-03-18 08:26:44 +08:00
|
|
|
/* construct the cancel button's contents manually because we
|
|
|
|
* always want image and label regardless of settings, and we want
|
|
|
|
* a menu size image.
|
|
|
|
*/
|
2008-03-27 20:17:45 +08:00
|
|
|
statusbar->cancel_button = gtk_button_new ();
|
2009-10-18 01:51:33 +08:00
|
|
|
gtk_widget_set_can_focus (statusbar->cancel_button, FALSE);
|
2008-03-27 20:17:45 +08:00
|
|
|
gtk_button_set_relief (GTK_BUTTON (statusbar->cancel_button),
|
|
|
|
GTK_RELIEF_NONE);
|
2004-08-11 02:47:21 +08:00
|
|
|
gtk_widget_set_sensitive (statusbar->cancel_button, FALSE);
|
2020-06-18 18:05:47 +08:00
|
|
|
gimp_statusbar_add_size_widget (statusbar, statusbar->cancel_button);
|
2018-05-14 02:36:22 +08:00
|
|
|
gtk_box_pack_end (GTK_BOX (hbox), statusbar->cancel_button,
|
|
|
|
FALSE, FALSE, 0);
|
2008-03-27 18:43:55 +08:00
|
|
|
/* don't show the cancel button */
|
2004-08-11 02:47:21 +08:00
|
|
|
|
2013-03-18 08:26:44 +08:00
|
|
|
hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
|
|
gtk_container_add (GTK_CONTAINER (statusbar->cancel_button), hbox2);
|
|
|
|
gtk_widget_show (hbox2);
|
|
|
|
|
2016-09-03 21:28:22 +08:00
|
|
|
image = gtk_image_new_from_icon_name ("gtk-cancel", GTK_ICON_SIZE_MENU);
|
2013-03-18 08:26:44 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox2), image, FALSE, FALSE, 2);
|
2008-03-27 20:17:45 +08:00
|
|
|
gtk_widget_show (image);
|
|
|
|
|
2022-08-08 12:05:53 +08:00
|
|
|
label = gtk_label_new (_("Cancel"));
|
2018-06-04 21:13:23 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 2);
|
|
|
|
gtk_widget_show (label);
|
2013-03-18 08:26:44 +08:00
|
|
|
|
2004-08-11 02:47:21 +08:00
|
|
|
g_signal_connect (statusbar->cancel_button, "clicked",
|
|
|
|
G_CALLBACK (gimp_statusbar_progress_canceled),
|
|
|
|
statusbar);
|
2020-06-18 18:05:47 +08:00
|
|
|
|
2022-08-02 07:22:05 +08:00
|
|
|
/* soft proofing button */
|
|
|
|
statusbar->soft_proof_button = gtk_toggle_button_new();
|
|
|
|
gtk_widget_set_can_focus (statusbar->soft_proof_button, FALSE);
|
|
|
|
gtk_button_set_relief (GTK_BUTTON (statusbar->soft_proof_button),
|
|
|
|
GTK_RELIEF_NONE);
|
|
|
|
image = gtk_image_new_from_icon_name (GIMP_ICON_DISPLAY_FILTER_PROOF,
|
|
|
|
GTK_ICON_SIZE_MENU);
|
|
|
|
gtk_container_add (GTK_CONTAINER (statusbar->soft_proof_button), image);
|
|
|
|
gtk_widget_show (image);
|
2022-08-08 12:05:53 +08:00
|
|
|
|
2022-08-02 07:22:05 +08:00
|
|
|
gtk_widget_show (statusbar->soft_proof_button);
|
2022-08-08 12:05:53 +08:00
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (statusbar->soft_proof_button),
|
|
|
|
FALSE);
|
2022-08-02 07:22:05 +08:00
|
|
|
|
2022-08-08 12:05:53 +08:00
|
|
|
/* The soft-proof toggle button is placed in a GtkEventBox
|
|
|
|
* so it can be disabled while still allowing users to right-click
|
|
|
|
* and access the soft-proofing menu
|
|
|
|
*/
|
|
|
|
statusbar->soft_proof_container = gtk_event_box_new ();
|
2023-12-16 21:12:31 +08:00
|
|
|
g_signal_connect_after (statusbar->soft_proof_container, "size-allocate",
|
|
|
|
G_CALLBACK (gimp_statusbar_soft_proof_size_allocate),
|
|
|
|
statusbar);
|
2022-08-08 12:05:53 +08:00
|
|
|
gtk_container_add (GTK_CONTAINER (statusbar->soft_proof_container),
|
|
|
|
statusbar->soft_proof_button);
|
|
|
|
gtk_box_pack_end (GTK_BOX (hbox), statusbar->soft_proof_container,
|
|
|
|
FALSE, FALSE, 0);
|
|
|
|
gimp_statusbar_add_size_widget (statusbar, statusbar->soft_proof_container);
|
|
|
|
gtk_widget_show (statusbar->soft_proof_container);
|
|
|
|
gimp_help_set_help_data (statusbar->soft_proof_container,
|
|
|
|
_("Toggle soft-proofing view when "
|
2023-12-16 21:12:31 +08:00
|
|
|
"a soft-proofing profile is set\n"
|
|
|
|
"Right-click to show the soft-proofing "
|
|
|
|
"options"),
|
2022-08-08 12:05:53 +08:00
|
|
|
NULL);
|
|
|
|
gtk_widget_set_events (statusbar->soft_proof_container, GDK_BUTTON_PRESS_MASK);
|
|
|
|
g_signal_connect (statusbar->soft_proof_container, "button-press-event",
|
|
|
|
G_CALLBACK (gimp_statusbar_soft_proof_popover_shown),
|
|
|
|
statusbar);
|
2023-12-16 21:12:31 +08:00
|
|
|
gtk_event_box_set_above_child (GTK_EVENT_BOX (statusbar->soft_proof_container), FALSE);
|
2022-08-08 12:05:53 +08:00
|
|
|
|
|
|
|
/* soft proofing popover */
|
|
|
|
row = 0;
|
|
|
|
|
|
|
|
statusbar->soft_proof_popover = gtk_popover_new (statusbar->soft_proof_container);
|
|
|
|
gtk_popover_set_modal (GTK_POPOVER (statusbar->soft_proof_popover), TRUE);
|
|
|
|
|
|
|
|
grid = gtk_grid_new ();
|
|
|
|
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
|
|
|
|
|
|
|
|
label = gtk_label_new (NULL);
|
|
|
|
text = g_strdup_printf ("<b>%s</b>",
|
|
|
|
_("Soft-Proofing"));
|
|
|
|
gtk_label_set_markup (GTK_LABEL (label), text);
|
|
|
|
g_free (text);
|
|
|
|
gtk_grid_attach (GTK_GRID (grid),
|
|
|
|
label,
|
|
|
|
0, row++, 2, 1);
|
|
|
|
gtk_widget_show (label);
|
|
|
|
|
|
|
|
statusbar->proof_colors_toggle =
|
|
|
|
gtk_check_button_new_with_mnemonic (_("_Proof Colors"));
|
|
|
|
gtk_grid_attach (GTK_GRID (grid),
|
|
|
|
statusbar->proof_colors_toggle,
|
|
|
|
0, row++, 1, 1);
|
|
|
|
g_signal_connect (statusbar->proof_colors_toggle, "clicked",
|
2022-08-02 07:22:05 +08:00
|
|
|
G_CALLBACK (gimp_statusbar_soft_proof_button_toggled),
|
|
|
|
statusbar);
|
2022-08-08 12:05:53 +08:00
|
|
|
gtk_widget_show (statusbar->proof_colors_toggle);
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (statusbar->proof_colors_toggle),
|
2022-08-02 07:22:05 +08:00
|
|
|
FALSE);
|
|
|
|
|
2022-08-08 12:05:53 +08:00
|
|
|
statusbar->profile_label = gtk_label_new (NULL);
|
|
|
|
text = g_strdup_printf ("<b>%s</b>: %s",
|
|
|
|
_("Current Soft-Proofing Profile"),
|
|
|
|
_("None"));
|
|
|
|
gtk_label_set_markup (GTK_LABEL (statusbar->profile_label), text);
|
|
|
|
g_free (text);
|
|
|
|
gtk_grid_attach (GTK_GRID (grid),
|
|
|
|
statusbar->profile_label,
|
|
|
|
0, row++, 2, 1);
|
|
|
|
gtk_widget_show (statusbar->profile_label);
|
|
|
|
|
|
|
|
file = gimp_directory_file ("profilerc", NULL);
|
|
|
|
combo_store = gimp_color_profile_store_new (file);
|
|
|
|
g_object_unref (file);
|
|
|
|
gimp_color_profile_store_add_file (GIMP_COLOR_PROFILE_STORE (combo_store),
|
|
|
|
NULL, NULL);
|
2022-08-18 22:42:39 +08:00
|
|
|
profile_chooser = gimp_color_profile_chooser_dialog_new (_("Soft-Proofing Profile"), NULL,
|
|
|
|
GTK_FILE_CHOOSER_ACTION_OPEN);
|
|
|
|
statusbar->profile_combo = gimp_color_profile_combo_box_new_with_model (profile_chooser,
|
|
|
|
GTK_TREE_MODEL (combo_store));
|
2022-08-08 12:05:53 +08:00
|
|
|
|
|
|
|
gimp_color_profile_combo_box_set_active_file (GIMP_COLOR_PROFILE_COMBO_BOX (statusbar->profile_combo),
|
|
|
|
NULL, NULL);
|
|
|
|
|
|
|
|
gimp_grid_attach_aligned (GTK_GRID (grid), 0, row++,
|
|
|
|
_("_Soft-proofing Profile: "),
|
|
|
|
0.0, 0.5,
|
|
|
|
statusbar->profile_combo, 1);
|
|
|
|
gtk_widget_show (statusbar->profile_combo);
|
|
|
|
g_signal_connect (statusbar->profile_combo, "changed",
|
|
|
|
G_CALLBACK (gimp_statusbar_soft_proof_profile_changed),
|
|
|
|
statusbar);
|
|
|
|
|
|
|
|
combo_store =
|
|
|
|
gimp_int_store_new ("Perceptual", GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
|
|
|
|
"Relative Colorimetric", GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC,
|
|
|
|
"Saturation", GIMP_COLOR_RENDERING_INTENT_SATURATION,
|
|
|
|
"Absolute Colorimetric", GIMP_COLOR_RENDERING_INTENT_ABSOLUTE_COLORIMETRIC,
|
|
|
|
NULL);
|
|
|
|
statusbar->rendering_intent_combo = g_object_new (GIMP_TYPE_INT_COMBO_BOX,
|
|
|
|
"model", combo_store,
|
|
|
|
"visible", TRUE,
|
|
|
|
NULL);
|
|
|
|
gimp_grid_attach_aligned (GTK_GRID (grid), 0, row++,
|
|
|
|
_("_Rendering Intent: "),
|
|
|
|
0.0, 0.5,
|
|
|
|
statusbar->rendering_intent_combo, 1);
|
|
|
|
gtk_widget_show (statusbar->rendering_intent_combo);
|
|
|
|
g_signal_connect (statusbar->rendering_intent_combo, "changed",
|
|
|
|
G_CALLBACK (gimp_statusbar_soft_proof_rendering_intent_changed),
|
|
|
|
statusbar);
|
|
|
|
|
|
|
|
statusbar->bpc_toggle =
|
|
|
|
gtk_check_button_new_with_mnemonic (_("Use _Black Point Compensation"));
|
|
|
|
gtk_grid_attach (GTK_GRID (grid),
|
|
|
|
statusbar->bpc_toggle,
|
|
|
|
0, row++, 1, 1);
|
|
|
|
gtk_widget_show (statusbar->bpc_toggle);
|
|
|
|
g_signal_connect (statusbar->bpc_toggle, "clicked",
|
|
|
|
G_CALLBACK (gimp_statusbar_soft_proof_bpc_toggled),
|
|
|
|
statusbar);
|
|
|
|
|
|
|
|
separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
|
|
|
|
gtk_grid_attach (GTK_GRID (grid),separator,
|
|
|
|
0, row++, 1, 1);
|
|
|
|
gtk_widget_show (separator);
|
|
|
|
|
|
|
|
statusbar->optimize_combo =
|
|
|
|
gimp_int_combo_box_new (_("Speed"), TRUE,
|
|
|
|
_("Precision / Color Fidelity"), FALSE,
|
|
|
|
NULL);
|
|
|
|
gimp_grid_attach_aligned (GTK_GRID (grid), 0, row++,
|
|
|
|
_("O_ptimize soft-proofing for: "),
|
|
|
|
0.0, 0.5,
|
|
|
|
statusbar->optimize_combo, 1);
|
|
|
|
gtk_widget_show (statusbar->optimize_combo);
|
|
|
|
g_signal_connect (statusbar->optimize_combo, "changed",
|
|
|
|
G_CALLBACK (gimp_statusbar_soft_proof_optimize_changed),
|
|
|
|
statusbar);
|
|
|
|
|
|
|
|
statusbar->out_of_gamut_toggle =
|
|
|
|
gtk_check_button_new_with_mnemonic (_("_Mark Out of Gamut Colors"));
|
|
|
|
gtk_grid_attach (GTK_GRID (grid),
|
|
|
|
statusbar->out_of_gamut_toggle,
|
|
|
|
0, row++, 1, 1);
|
|
|
|
gtk_widget_show (statusbar->out_of_gamut_toggle);
|
|
|
|
g_signal_connect (statusbar->out_of_gamut_toggle, "clicked",
|
|
|
|
G_CALLBACK (gimp_statusbar_soft_proof_gamut_toggled),
|
|
|
|
statusbar);
|
|
|
|
|
|
|
|
gtk_container_add (GTK_CONTAINER (statusbar->soft_proof_popover), grid);
|
|
|
|
gtk_widget_show (grid);
|
|
|
|
|
2020-06-18 18:05:47 +08:00
|
|
|
gimp_statusbar_update_size (statusbar);
|
2004-08-11 02:47:21 +08:00
|
|
|
}
|
|
|
|
|
2010-09-27 04:35:49 +08:00
|
|
|
static void
|
|
|
|
gimp_statusbar_dispose (GObject *object)
|
|
|
|
{
|
|
|
|
GimpStatusbar *statusbar = GIMP_STATUSBAR (object);
|
|
|
|
|
2022-08-08 12:05:53 +08:00
|
|
|
if (statusbar->gimp)
|
|
|
|
{
|
|
|
|
g_signal_handlers_disconnect_by_func (gimp_get_user_context (statusbar->gimp),
|
|
|
|
gimp_statusbar_shell_image_changed,
|
|
|
|
statusbar);
|
|
|
|
statusbar->gimp = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
gimp_statusbar_shell_set_image (statusbar, NULL);
|
|
|
|
|
2010-09-27 04:35:49 +08:00
|
|
|
if (statusbar->temp_timeout_id)
|
|
|
|
{
|
|
|
|
g_source_remove (statusbar->temp_timeout_id);
|
|
|
|
statusbar->temp_timeout_id = 0;
|
|
|
|
}
|
|
|
|
|
macos: Fix 7690 (slow drawing)
Gets drawing in the canvas speed on retina displays up to the speed
of FullHD displays on macOS, making 2.99 usable on macOS.
Generic change:
Changes the cursor_label to delay the drawing phase to the idle
queue, from immediate draw on all platforms.
Before the fix in 32049afd (using a deprecated function in Gtk3)
any draws on this label forced a full canvas redraw. This is due
to a quirk in how GtkLabel functions.
The redraw occurred because GtkLabels resize themselves and everything
around them by sending a resize message any time they receive new
text. These resizes then trigger the full canvas resize which triggers
a full canvas redraw that cannot be optimized by either Gtk or Big Sur.
MacOS changes:
Only redraws the cursor position label and each of the horizontal and
vertical rules (cursor tracking widgets) 3 times a second max for a
total of 9 redraws a second (ideally out of 60, though I don't believe
under any circumstances that GIMP achieves a 60fps).
Each of the cursor tracking widgets gets its own timeslice, and so
will not redraw when the other cursor tracking widgets are drawing.
This is required because Big Sur is merging all draw rects into
one large rect, dramatically slowing down draws.
This timeslicing ensures that draw rects are maintained at the smallest
possible size. So the typical redraw is a small rect around the
brush. However, 9 times a second, the rect will include one of the
3 cursor tracking widgets (rulers and cursor label).
Additionally, the code tries to minimize resizing the width of the
cursor label by checking if the widget is too small for the text,
then setting the char_width to a greater size so that resizes won't
be that common.
This improves the appearance of the widget as it no longer
constantly jumps about in size on each cursor move.
Here is a discussion of the issue:
https://gitlab.gnome.org/GNOME/gimp/-/merge_requests/572#note_1389445
Reviewer's (Jehan) notes:
* The whole issue about GtkLabel resizing is no more after 32049afd. It
is normal for a widget to request a resize when needed. We just don't
want the statusbar to resize and triggering canvas redraws.
* Changing cursor position text into an idle function generally makes
sense.
Also it reverts commit 6de9ea70223 which had a bug I hadn't realized
when I accepted it: when we test for time, we don't know yet if it
will be the last position change, hence we could "refuse" the last
update. Therefore displayed cursor position would end up outdated
on macOS. This new implementation doesn't have the problem (the last
idle update always happens after the last move).
* The change about giving 1/3 timeslices to side canvas components
(rulers and statusbar) is a complete hack to work around the fact that
macOs doesn't report properly each damaged rectangle. Instead it
returns a huge bounding box. The workaround here is to expose these
area separately.
We have not been able to find a proper solution yet. This is the only
reason why I accept this code, for macOS only, to at least have
something usable there.
See discussions in MRs gimp!572 and gimp-macos-build!86. With these 2
MRs, Lukas reported GIMP 2.99 to perform even better than GIMP 2.10 on
Monterey, though it could not be tested on Big Sur unfortunately.
* Lastly the set_width_chars() thing is also an ugly hack which I will
try later to revisit (see !581). I only accepted it (with mandatory
macOS-only macro) to have an acceptable state for release after seeing
a screencast where the label size indeed "jumps around" on macOS.
2022-02-19 09:25:51 +08:00
|
|
|
if (statusbar->statusbar_pos_redraw_idle_id)
|
|
|
|
{
|
|
|
|
g_source_remove (statusbar->statusbar_pos_redraw_idle_id);
|
|
|
|
statusbar->statusbar_pos_redraw_idle_id = 0;
|
|
|
|
}
|
|
|
|
|
2020-06-18 18:05:47 +08:00
|
|
|
g_clear_pointer (&statusbar->size_widgets, g_slist_free);
|
|
|
|
|
2010-09-27 04:35:49 +08:00
|
|
|
G_OBJECT_CLASS (parent_class)->dispose (object);
|
|
|
|
}
|
|
|
|
|
2002-02-03 20:10:23 +08:00
|
|
|
static void
|
2006-09-01 20:15:14 +08:00
|
|
|
gimp_statusbar_finalize (GObject *object)
|
2002-02-03 20:10:23 +08:00
|
|
|
{
|
2004-07-15 00:37:13 +08:00
|
|
|
GimpStatusbar *statusbar = GIMP_STATUSBAR (object);
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2017-07-16 00:38:01 +08:00
|
|
|
g_clear_object (&statusbar->icon);
|
|
|
|
g_clear_pointer (&statusbar->icon_hash, g_hash_table_unref);
|
2023-05-23 06:11:23 +08:00
|
|
|
g_clear_pointer (&statusbar->cursor_string_last, g_free);
|
|
|
|
g_clear_pointer (&statusbar->cursor_string_todraw, g_free);
|
2014-05-31 01:38:17 +08:00
|
|
|
|
2011-03-08 00:10:18 +08:00
|
|
|
g_slist_free_full (statusbar->messages,
|
|
|
|
(GDestroyNotify) gimp_statusbar_msg_free);
|
2004-06-19 21:31:58 +08:00
|
|
|
statusbar->messages = NULL;
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2017-07-16 00:38:01 +08:00
|
|
|
g_clear_pointer (&statusbar->context_ids, g_hash_table_destroy);
|
2006-09-23 00:44:47 +08:00
|
|
|
|
2006-09-01 20:15:14 +08:00
|
|
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
2004-06-19 21:31:58 +08:00
|
|
|
}
|
|
|
|
|
2014-05-31 01:38:17 +08:00
|
|
|
static void
|
|
|
|
gimp_statusbar_screen_changed (GtkWidget *widget,
|
|
|
|
GdkScreen *previous)
|
|
|
|
{
|
|
|
|
GimpStatusbar *statusbar = GIMP_STATUSBAR (widget);
|
|
|
|
|
|
|
|
if (GTK_WIDGET_CLASS (parent_class)->screen_changed)
|
|
|
|
GTK_WIDGET_CLASS (parent_class)->screen_changed (widget, previous);
|
|
|
|
|
2017-07-16 00:38:01 +08:00
|
|
|
g_clear_pointer (&statusbar->icon_hash, g_hash_table_unref);
|
2014-05-31 01:38:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2010-12-23 06:34:47 +08:00
|
|
|
gimp_statusbar_style_updated (GtkWidget *widget)
|
2014-05-31 01:38:17 +08:00
|
|
|
{
|
|
|
|
GimpStatusbar *statusbar = GIMP_STATUSBAR (widget);
|
2019-01-03 00:49:53 +08:00
|
|
|
PangoLayout *layout;
|
|
|
|
|
|
|
|
GTK_WIDGET_CLASS (parent_class)->style_updated (widget);
|
2014-05-31 01:38:17 +08:00
|
|
|
|
2017-07-16 00:38:01 +08:00
|
|
|
g_clear_pointer (&statusbar->icon_hash, g_hash_table_unref);
|
2010-12-29 22:22:09 +08:00
|
|
|
|
2019-01-03 00:49:53 +08:00
|
|
|
layout = gtk_widget_create_pango_layout (widget, " ");
|
|
|
|
pango_layout_get_pixel_size (layout, &statusbar->icon_space_width, NULL);
|
|
|
|
g_object_unref (layout);
|
2020-06-18 18:05:47 +08:00
|
|
|
|
|
|
|
gimp_statusbar_update_size (statusbar);
|
2008-03-24 00:10:03 +08:00
|
|
|
}
|
|
|
|
|
2004-08-11 02:47:21 +08:00
|
|
|
static GimpProgress *
|
|
|
|
gimp_statusbar_progress_start (GimpProgress *progress,
|
2014-07-13 05:45:20 +08:00
|
|
|
gboolean cancellable,
|
|
|
|
const gchar *message)
|
2004-08-11 02:47:21 +08:00
|
|
|
{
|
|
|
|
GimpStatusbar *statusbar = GIMP_STATUSBAR (progress);
|
|
|
|
|
|
|
|
if (! statusbar->progress_active)
|
|
|
|
{
|
2018-07-04 05:25:24 +08:00
|
|
|
GtkWidget *bar = statusbar->progressbar;
|
2004-08-11 02:47:21 +08:00
|
|
|
|
2018-04-07 23:46:58 +08:00
|
|
|
statusbar->progress_active = TRUE;
|
|
|
|
statusbar->progress_value = 0.0;
|
|
|
|
statusbar->progress_last_update_time = g_get_monotonic_time ();
|
2008-03-27 18:43:55 +08:00
|
|
|
|
2008-04-14 15:39:23 +08:00
|
|
|
gimp_statusbar_push (statusbar, "progress", NULL, "%s", message);
|
2004-08-11 02:47:21 +08:00
|
|
|
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (bar), 0.0);
|
2014-07-13 05:45:20 +08:00
|
|
|
gtk_widget_set_sensitive (statusbar->cancel_button, cancellable);
|
2004-08-11 02:47:21 +08:00
|
|
|
|
2014-07-13 05:45:20 +08:00
|
|
|
if (cancellable)
|
2008-03-27 20:17:45 +08:00
|
|
|
{
|
|
|
|
if (message)
|
|
|
|
{
|
|
|
|
gchar *tooltip = g_strdup_printf (_("Cancel <i>%s</i>"), message);
|
|
|
|
|
|
|
|
gimp_help_set_help_data_with_markup (statusbar->cancel_button,
|
|
|
|
tooltip, NULL);
|
|
|
|
g_free (tooltip);
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_widget_show (statusbar->cancel_button);
|
|
|
|
}
|
2006-12-12 17:37:58 +08:00
|
|
|
|
2008-03-27 18:43:55 +08:00
|
|
|
gtk_widget_show (statusbar->progressbar);
|
2010-04-20 15:56:59 +08:00
|
|
|
gtk_widget_hide (statusbar->label);
|
2008-03-27 18:43:55 +08:00
|
|
|
|
2009-10-18 01:51:33 +08:00
|
|
|
if (! gtk_widget_get_visible (GTK_WIDGET (statusbar)))
|
2007-05-29 01:42:55 +08:00
|
|
|
{
|
|
|
|
gtk_widget_show (GTK_WIDGET (statusbar));
|
|
|
|
statusbar->progress_shown = TRUE;
|
|
|
|
}
|
|
|
|
|
2019-02-19 22:31:50 +08:00
|
|
|
gimp_widget_flush_expose ();
|
2004-08-11 08:34:34 +08:00
|
|
|
|
2009-09-26 01:35:03 +08:00
|
|
|
gimp_statusbar_override_window_title (statusbar);
|
|
|
|
|
2004-08-11 02:47:21 +08:00
|
|
|
return progress;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_statusbar_progress_end (GimpProgress *progress)
|
|
|
|
{
|
|
|
|
GimpStatusbar *statusbar = GIMP_STATUSBAR (progress);
|
|
|
|
|
|
|
|
if (statusbar->progress_active)
|
|
|
|
{
|
|
|
|
GtkWidget *bar = statusbar->progressbar;
|
|
|
|
|
2007-05-29 01:42:55 +08:00
|
|
|
if (statusbar->progress_shown)
|
|
|
|
{
|
|
|
|
gtk_widget_hide (GTK_WIDGET (statusbar));
|
|
|
|
statusbar->progress_shown = FALSE;
|
|
|
|
}
|
|
|
|
|
2007-03-11 06:10:56 +08:00
|
|
|
statusbar->progress_active = FALSE;
|
2007-12-31 01:25:58 +08:00
|
|
|
statusbar->progress_value = 0.0;
|
2007-03-11 06:10:56 +08:00
|
|
|
|
2008-03-27 18:43:55 +08:00
|
|
|
gtk_widget_hide (bar);
|
2010-04-20 15:56:59 +08:00
|
|
|
gtk_widget_show (statusbar->label);
|
2008-03-27 18:43:55 +08:00
|
|
|
|
2004-08-11 02:47:21 +08:00
|
|
|
gimp_statusbar_pop (statusbar, "progress");
|
2008-03-27 18:43:55 +08:00
|
|
|
|
2004-08-11 02:47:21 +08:00
|
|
|
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (bar), 0.0);
|
|
|
|
gtk_widget_set_sensitive (statusbar->cancel_button, FALSE);
|
2006-12-12 17:37:58 +08:00
|
|
|
gtk_widget_hide (statusbar->cancel_button);
|
2009-09-26 01:35:03 +08:00
|
|
|
|
|
|
|
gimp_statusbar_restore_window_title (statusbar);
|
2004-08-11 02:47:21 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-08-11 18:29:56 +08:00
|
|
|
static gboolean
|
|
|
|
gimp_statusbar_progress_is_active (GimpProgress *progress)
|
|
|
|
{
|
|
|
|
GimpStatusbar *statusbar = GIMP_STATUSBAR (progress);
|
|
|
|
|
|
|
|
return statusbar->progress_active;
|
|
|
|
}
|
|
|
|
|
2004-08-11 02:47:21 +08:00
|
|
|
static void
|
|
|
|
gimp_statusbar_progress_set_text (GimpProgress *progress,
|
|
|
|
const gchar *message)
|
|
|
|
{
|
|
|
|
GimpStatusbar *statusbar = GIMP_STATUSBAR (progress);
|
|
|
|
|
|
|
|
if (statusbar->progress_active)
|
|
|
|
{
|
2008-04-14 18:10:02 +08:00
|
|
|
gimp_statusbar_replace (statusbar, "progress", NULL, "%s", message);
|
2004-08-11 08:34:34 +08:00
|
|
|
|
2019-02-19 22:31:50 +08:00
|
|
|
gimp_widget_flush_expose ();
|
2009-09-26 01:35:03 +08:00
|
|
|
|
|
|
|
gimp_statusbar_override_window_title (statusbar);
|
2004-08-11 02:47:21 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_statusbar_progress_set_value (GimpProgress *progress,
|
|
|
|
gdouble percentage)
|
|
|
|
{
|
|
|
|
GimpStatusbar *statusbar = GIMP_STATUSBAR (progress);
|
|
|
|
|
|
|
|
if (statusbar->progress_active)
|
|
|
|
{
|
2018-04-07 23:46:58 +08:00
|
|
|
guint64 time = g_get_monotonic_time ();
|
|
|
|
|
|
|
|
if (time - statusbar->progress_last_update_time >=
|
|
|
|
MIN_PROGRESS_UPDATE_INTERVAL)
|
|
|
|
{
|
|
|
|
GtkWidget *bar = statusbar->progressbar;
|
|
|
|
GtkAllocation allocation;
|
|
|
|
gdouble diff;
|
2009-10-18 01:51:33 +08:00
|
|
|
|
2018-04-07 23:46:58 +08:00
|
|
|
gtk_widget_get_allocation (bar, &allocation);
|
2004-08-11 02:47:21 +08:00
|
|
|
|
2018-04-07 23:46:58 +08:00
|
|
|
statusbar->progress_value = percentage;
|
2004-08-11 02:47:21 +08:00
|
|
|
|
2018-04-07 23:46:58 +08:00
|
|
|
diff = fabs (percentage -
|
|
|
|
gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (bar)));
|
2007-12-31 01:25:58 +08:00
|
|
|
|
2018-04-07 23:46:58 +08:00
|
|
|
/* only update the progress bar if this causes a visible change */
|
|
|
|
if (allocation.width * diff >= 1.0)
|
|
|
|
{
|
|
|
|
statusbar->progress_last_update_time = time;
|
|
|
|
|
|
|
|
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (bar),
|
|
|
|
percentage);
|
|
|
|
|
2019-02-19 22:31:50 +08:00
|
|
|
gimp_widget_flush_expose ();
|
2018-04-07 23:46:58 +08:00
|
|
|
}
|
2007-12-31 01:25:58 +08:00
|
|
|
}
|
2004-08-11 02:47:21 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static gdouble
|
|
|
|
gimp_statusbar_progress_get_value (GimpProgress *progress)
|
|
|
|
{
|
|
|
|
GimpStatusbar *statusbar = GIMP_STATUSBAR (progress);
|
|
|
|
|
|
|
|
if (statusbar->progress_active)
|
2009-10-18 01:51:33 +08:00
|
|
|
return statusbar->progress_value;
|
2004-08-11 02:47:21 +08:00
|
|
|
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
|
2005-02-12 22:18:12 +08:00
|
|
|
static void
|
|
|
|
gimp_statusbar_progress_pulse (GimpProgress *progress)
|
|
|
|
{
|
|
|
|
GimpStatusbar *statusbar = GIMP_STATUSBAR (progress);
|
|
|
|
|
|
|
|
if (statusbar->progress_active)
|
|
|
|
{
|
2018-04-07 23:46:58 +08:00
|
|
|
guint64 time = g_get_monotonic_time ();
|
2005-02-12 22:18:12 +08:00
|
|
|
|
2018-04-07 23:46:58 +08:00
|
|
|
if (time - statusbar->progress_last_update_time >=
|
|
|
|
MIN_PROGRESS_UPDATE_INTERVAL)
|
|
|
|
{
|
|
|
|
GtkWidget *bar = statusbar->progressbar;
|
2005-02-12 22:18:12 +08:00
|
|
|
|
2018-04-07 23:46:58 +08:00
|
|
|
statusbar->progress_last_update_time = time;
|
|
|
|
|
|
|
|
gtk_progress_bar_pulse (GTK_PROGRESS_BAR (bar));
|
|
|
|
|
2019-02-19 22:31:50 +08:00
|
|
|
gimp_widget_flush_expose ();
|
2018-04-07 23:46:58 +08:00
|
|
|
}
|
2005-02-12 22:18:12 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-10-09 16:17:22 +08:00
|
|
|
static gboolean
|
|
|
|
gimp_statusbar_progress_message (GimpProgress *progress,
|
|
|
|
Gimp *gimp,
|
|
|
|
GimpMessageSeverity severity,
|
|
|
|
const gchar *domain,
|
|
|
|
const gchar *message)
|
|
|
|
{
|
2008-04-11 03:24:06 +08:00
|
|
|
GimpStatusbar *statusbar = GIMP_STATUSBAR (progress);
|
|
|
|
PangoLayout *layout;
|
2014-05-07 21:30:38 +08:00
|
|
|
const gchar *icon_name;
|
2008-04-11 03:24:06 +08:00
|
|
|
gboolean handle_msg = FALSE;
|
2006-10-09 16:17:22 +08:00
|
|
|
|
2008-08-16 00:32:09 +08:00
|
|
|
/* don't accept a message if we are already displaying a more severe one */
|
|
|
|
if (statusbar->temp_timeout_id && statusbar->temp_severity > severity)
|
2008-07-09 18:45:21 +08:00
|
|
|
return FALSE;
|
2008-04-11 03:24:06 +08:00
|
|
|
|
2008-07-09 18:45:21 +08:00
|
|
|
/* we can only handle short one-liners */
|
2010-04-20 15:56:59 +08:00
|
|
|
layout = gtk_widget_create_pango_layout (statusbar->label, message);
|
2008-04-11 03:24:06 +08:00
|
|
|
|
2014-05-07 21:30:38 +08:00
|
|
|
icon_name = gimp_get_message_icon_name (severity);
|
2008-07-09 18:45:21 +08:00
|
|
|
|
2008-04-11 03:24:06 +08:00
|
|
|
if (pango_layout_get_line_count (layout) == 1)
|
|
|
|
{
|
2021-02-09 23:02:29 +08:00
|
|
|
GtkWidget *label_box = gtk_widget_get_parent (statusbar->label);
|
|
|
|
GtkAllocation label_allocation;
|
|
|
|
gint text_width, max_label_width, x;
|
2009-10-18 01:51:33 +08:00
|
|
|
|
2021-02-09 23:02:29 +08:00
|
|
|
gtk_widget_get_allocation (label_box, &label_allocation);
|
|
|
|
if (gtk_widget_translate_coordinates (statusbar->label, label_box, 0, 0,
|
|
|
|
&x, NULL))
|
2008-04-11 03:24:06 +08:00
|
|
|
{
|
2021-02-09 23:02:29 +08:00
|
|
|
max_label_width = label_allocation.width - x;
|
|
|
|
pango_layout_get_pixel_size (layout, &text_width, NULL);
|
|
|
|
|
|
|
|
if (text_width < max_label_width)
|
2008-04-14 18:10:02 +08:00
|
|
|
{
|
2021-02-09 23:02:29 +08:00
|
|
|
if (icon_name)
|
|
|
|
{
|
|
|
|
GdkPixbuf *pixbuf;
|
|
|
|
gint scale_factor;
|
2008-04-14 18:10:02 +08:00
|
|
|
|
2021-02-09 23:02:29 +08:00
|
|
|
pixbuf = gimp_statusbar_load_icon (statusbar, icon_name);
|
2008-04-14 18:10:02 +08:00
|
|
|
|
2021-02-09 23:02:29 +08:00
|
|
|
scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (statusbar));
|
|
|
|
text_width += ICON_SPACING + gdk_pixbuf_get_width (pixbuf) / scale_factor;
|
2008-04-14 18:10:02 +08:00
|
|
|
|
2021-02-09 23:02:29 +08:00
|
|
|
g_object_unref (pixbuf);
|
2008-04-14 19:57:23 +08:00
|
|
|
|
2021-02-09 23:02:29 +08:00
|
|
|
handle_msg = (text_width < max_label_width);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
handle_msg = TRUE;
|
|
|
|
}
|
2008-04-14 18:10:02 +08:00
|
|
|
}
|
2008-04-11 03:24:06 +08:00
|
|
|
}
|
|
|
|
}
|
2006-10-09 16:17:22 +08:00
|
|
|
|
2008-04-11 03:24:06 +08:00
|
|
|
g_object_unref (layout);
|
|
|
|
|
|
|
|
if (handle_msg)
|
2014-05-07 21:30:38 +08:00
|
|
|
gimp_statusbar_push_temp (statusbar, severity, icon_name, "%s", message);
|
2008-04-11 03:24:06 +08:00
|
|
|
|
|
|
|
return handle_msg;
|
2006-10-09 16:17:22 +08:00
|
|
|
}
|
|
|
|
|
2004-08-11 02:47:21 +08:00
|
|
|
static void
|
|
|
|
gimp_statusbar_progress_canceled (GtkWidget *button,
|
|
|
|
GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
if (statusbar->progress_active)
|
|
|
|
gimp_progress_cancel (GIMP_PROGRESS (statusbar));
|
|
|
|
}
|
|
|
|
|
2022-08-02 07:22:05 +08:00
|
|
|
static void
|
|
|
|
gimp_statusbar_soft_proof_button_toggled (GtkWidget *button,
|
|
|
|
GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
GimpColorConfig *color_config;
|
|
|
|
GimpColorManagementMode mode;
|
|
|
|
gboolean active;
|
|
|
|
|
|
|
|
color_config = gimp_display_shell_get_color_config (statusbar->shell);
|
|
|
|
mode = gimp_color_config_get_mode (color_config);
|
2022-08-08 12:05:53 +08:00
|
|
|
active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
|
2022-08-02 07:22:05 +08:00
|
|
|
|
|
|
|
if (active)
|
|
|
|
{
|
|
|
|
mode = GIMP_COLOR_MANAGEMENT_SOFTPROOF;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (mode != GIMP_COLOR_MANAGEMENT_OFF)
|
|
|
|
mode = GIMP_COLOR_MANAGEMENT_DISPLAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode != gimp_color_config_get_mode (color_config))
|
|
|
|
{
|
|
|
|
g_object_set (color_config,
|
|
|
|
"mode", mode,
|
|
|
|
NULL);
|
|
|
|
statusbar->shell->color_config_set = TRUE;
|
|
|
|
}
|
|
|
|
|
2022-08-08 12:05:53 +08:00
|
|
|
/* Updates soft-proofing buttons */
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (statusbar->soft_proof_button),
|
|
|
|
active);
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (statusbar->proof_colors_toggle),
|
|
|
|
active);
|
|
|
|
|
|
|
|
gimp_statusbar_shell_color_config_notify (G_OBJECT (color_config), NULL,
|
|
|
|
statusbar);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_statusbar_soft_proof_profile_changed (GtkComboBox *combo,
|
|
|
|
GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
GimpImage *image;
|
|
|
|
GimpColorConfig *color_config;
|
|
|
|
GFile *file;
|
|
|
|
GimpColorProfile *simulation_profile = NULL;
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
|
|
|
|
|
|
|
image = statusbar->image;
|
|
|
|
color_config = gimp_display_shell_get_color_config (statusbar->shell);
|
|
|
|
file =
|
|
|
|
gimp_color_profile_combo_box_get_active_file (GIMP_COLOR_PROFILE_COMBO_BOX (combo));
|
|
|
|
|
|
|
|
if (file)
|
|
|
|
{
|
|
|
|
simulation_profile = gimp_color_profile_new_from_file (file, NULL);
|
|
|
|
g_object_unref (file);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (image)
|
|
|
|
gimp_image_set_simulation_profile (image, simulation_profile);
|
|
|
|
|
|
|
|
gimp_statusbar_shell_color_config_notify (G_OBJECT (color_config), NULL,
|
|
|
|
statusbar);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_statusbar_soft_proof_rendering_intent_changed (GtkComboBox *combo,
|
|
|
|
GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
GimpImage *image;
|
|
|
|
GimpColorConfig *color_config;
|
|
|
|
GimpColorRenderingIntent intent;
|
|
|
|
GimpColorRenderingIntent active;
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
|
|
|
|
|
|
|
image = statusbar->image;
|
|
|
|
color_config = gimp_display_shell_get_color_config (statusbar->shell);
|
|
|
|
|
|
|
|
if (image)
|
|
|
|
{
|
|
|
|
intent = gimp_image_get_simulation_intent (image);
|
|
|
|
active =
|
|
|
|
(GimpColorRenderingIntent) gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
|
|
|
|
|
|
|
|
if (active != intent)
|
|
|
|
{
|
|
|
|
gimp_image_set_simulation_intent (image, active);
|
|
|
|
gimp_image_flush (image);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-02 07:22:05 +08:00
|
|
|
gimp_statusbar_shell_color_config_notify (G_OBJECT (color_config), NULL,
|
|
|
|
statusbar);
|
|
|
|
}
|
|
|
|
|
2022-08-08 12:05:53 +08:00
|
|
|
static void
|
|
|
|
gimp_statusbar_soft_proof_bpc_toggled (GtkWidget *button,
|
|
|
|
GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
GimpImage *image;
|
|
|
|
GimpColorConfig *color_config;
|
|
|
|
gboolean bpc_enabled;
|
|
|
|
gboolean active;
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
|
|
|
|
|
|
|
image = statusbar->image;
|
|
|
|
color_config = gimp_display_shell_get_color_config (statusbar->shell);
|
|
|
|
|
|
|
|
if (image)
|
|
|
|
{
|
|
|
|
bpc_enabled = gimp_image_get_simulation_bpc (image);
|
|
|
|
active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
|
|
|
|
|
|
|
|
if (active != bpc_enabled)
|
|
|
|
{
|
|
|
|
gimp_image_set_simulation_bpc (image, active);
|
|
|
|
gimp_image_flush (image);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gimp_statusbar_shell_color_config_notify (G_OBJECT (color_config), NULL,
|
|
|
|
statusbar);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_statusbar_soft_proof_optimize_changed (GtkWidget *combo,
|
|
|
|
GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
GimpColorConfig *color_config;
|
|
|
|
gint optimize;
|
|
|
|
gint active;
|
|
|
|
|
|
|
|
color_config = gimp_display_shell_get_color_config (statusbar->shell);
|
|
|
|
optimize = gimp_color_config_get_simulation_optimize (color_config);
|
|
|
|
gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (combo), &active);
|
|
|
|
|
|
|
|
if (active != optimize)
|
|
|
|
{
|
|
|
|
g_object_set (color_config,
|
|
|
|
"simulation-optimize", active,
|
|
|
|
NULL);
|
|
|
|
statusbar->shell->color_config_set = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
gimp_statusbar_shell_color_config_notify (G_OBJECT (color_config), NULL,
|
|
|
|
statusbar);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_statusbar_soft_proof_gamut_toggled (GtkWidget *button,
|
|
|
|
GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
GimpColorConfig *color_config;
|
|
|
|
gboolean out_of_gamut;
|
|
|
|
gboolean active;
|
|
|
|
|
|
|
|
color_config = gimp_display_shell_get_color_config (statusbar->shell);
|
|
|
|
out_of_gamut = gimp_color_config_get_simulation_gamut_check (color_config);
|
|
|
|
active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
|
|
|
|
|
|
|
|
if (active != out_of_gamut)
|
|
|
|
{
|
|
|
|
g_object_set (color_config,
|
|
|
|
"simulation-gamut-check", active,
|
|
|
|
NULL);
|
|
|
|
statusbar->shell->color_config_set = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
gimp_statusbar_shell_color_config_notify (G_OBJECT (color_config), NULL,
|
|
|
|
statusbar);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_statusbar_soft_proof_popover_shown (GtkWidget *button,
|
|
|
|
GdkEventButton *bevent,
|
|
|
|
GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
if (bevent->type == GDK_BUTTON_PRESS)
|
|
|
|
{
|
|
|
|
if (bevent->button == 3)
|
|
|
|
gtk_widget_show (statusbar->soft_proof_popover);
|
|
|
|
|
|
|
|
if (bevent->button == 1 &&
|
|
|
|
gtk_widget_get_sensitive (statusbar->soft_proof_button))
|
|
|
|
{
|
|
|
|
/* Since a GtkEventBox now covers the toggle so we can't click it,
|
|
|
|
* directly, we have to flip the toggle ourselves before we call
|
|
|
|
* the soft-proof button so it produces the right result
|
|
|
|
*/
|
|
|
|
gboolean active =
|
|
|
|
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (statusbar->soft_proof_button));
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (statusbar->soft_proof_button),
|
|
|
|
! active);
|
|
|
|
|
|
|
|
gimp_statusbar_soft_proof_button_toggled (statusbar->soft_proof_button,
|
|
|
|
statusbar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2023-12-16 21:12:31 +08:00
|
|
|
static void
|
|
|
|
gimp_statusbar_soft_proof_size_allocate (GtkWidget *widget,
|
|
|
|
GtkAllocation *allocation,
|
|
|
|
GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
/* This is an ugly hack for what looks a bug in GtkEventBox. In some cases,
|
|
|
|
* button events were not reaching the box at all, even though the event box
|
|
|
|
* was above the inactive child. Yet when setting it back down and up, it
|
|
|
|
* works. I have not figured out the exact bug cause yet, so we settle with
|
|
|
|
* this workaround for the time being. I'm setting it on the size-allocate
|
|
|
|
* signal, because when trying on "show" or "map-event", it was not working
|
|
|
|
* either. I guess it doesn't work when done before the widget is actually
|
|
|
|
* drawn. FIXME.
|
|
|
|
*/
|
|
|
|
gtk_event_box_set_above_child (GTK_EVENT_BOX (statusbar->soft_proof_container), FALSE);
|
|
|
|
gtk_event_box_set_above_child (GTK_EVENT_BOX (statusbar->soft_proof_container), TRUE);
|
|
|
|
}
|
|
|
|
|
2008-03-27 18:43:55 +08:00
|
|
|
static void
|
|
|
|
gimp_statusbar_set_text (GimpStatusbar *statusbar,
|
2014-05-07 21:30:38 +08:00
|
|
|
const gchar *icon_name,
|
2008-03-27 18:43:55 +08:00
|
|
|
const gchar *text)
|
|
|
|
{
|
|
|
|
if (statusbar->progress_active)
|
2008-04-14 18:10:02 +08:00
|
|
|
{
|
|
|
|
gtk_progress_bar_set_text (GTK_PROGRESS_BAR (statusbar->progressbar),
|
|
|
|
text);
|
|
|
|
}
|
2008-03-27 18:43:55 +08:00
|
|
|
else
|
2008-04-14 18:10:02 +08:00
|
|
|
{
|
2017-07-16 00:38:01 +08:00
|
|
|
g_clear_object (&statusbar->icon);
|
2008-04-14 18:10:02 +08:00
|
|
|
|
2014-05-07 21:30:38 +08:00
|
|
|
if (icon_name)
|
2014-05-31 01:38:17 +08:00
|
|
|
statusbar->icon = gimp_statusbar_load_icon (statusbar, icon_name);
|
2008-04-14 18:10:02 +08:00
|
|
|
|
|
|
|
if (statusbar->icon)
|
|
|
|
{
|
2019-01-03 00:49:53 +08:00
|
|
|
gchar *tmp;
|
|
|
|
gint scale_factor;
|
|
|
|
gint n_spaces;
|
|
|
|
gchar spaces[] = " ";
|
2008-04-14 18:10:02 +08:00
|
|
|
|
2019-01-01 02:12:00 +08:00
|
|
|
scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (statusbar));
|
|
|
|
|
2019-02-14 03:49:49 +08:00
|
|
|
/* Make sure icon_space_width has been initialized to avoid a
|
|
|
|
* division by zero.
|
|
|
|
*/
|
|
|
|
if (statusbar->icon_space_width == 0)
|
|
|
|
gimp_statusbar_style_updated (GTK_WIDGET (statusbar));
|
|
|
|
g_return_if_fail (statusbar->icon_space_width != 0);
|
|
|
|
|
2019-01-03 00:49:53 +08:00
|
|
|
/* prepend enough spaces for the icon plus one space */
|
|
|
|
n_spaces = (gdk_pixbuf_get_width (statusbar->icon) / scale_factor +
|
|
|
|
ICON_SPACING) / statusbar->icon_space_width;
|
|
|
|
n_spaces++;
|
2008-04-14 18:10:02 +08:00
|
|
|
|
2019-01-03 00:49:53 +08:00
|
|
|
tmp = g_strconcat (spaces + strlen (spaces) - n_spaces, text, NULL);
|
|
|
|
gtk_label_set_text (GTK_LABEL (statusbar->label), tmp);
|
|
|
|
g_free (tmp);
|
2008-04-14 18:10:02 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-04-20 15:56:59 +08:00
|
|
|
gtk_label_set_text (GTK_LABEL (statusbar->label), text);
|
2008-04-14 18:10:02 +08:00
|
|
|
}
|
|
|
|
}
|
2008-03-27 18:43:55 +08:00
|
|
|
}
|
|
|
|
|
2004-06-19 21:31:58 +08:00
|
|
|
static void
|
2004-07-15 00:37:13 +08:00
|
|
|
gimp_statusbar_update (GimpStatusbar *statusbar)
|
2004-06-19 21:31:58 +08:00
|
|
|
{
|
2008-04-14 14:28:43 +08:00
|
|
|
GimpStatusbarMsg *msg = NULL;
|
2004-07-15 00:37:13 +08:00
|
|
|
|
|
|
|
if (statusbar->messages)
|
2016-04-20 16:48:17 +08:00
|
|
|
msg = statusbar->messages->data;
|
2004-07-15 00:37:13 +08:00
|
|
|
|
2008-04-14 18:10:02 +08:00
|
|
|
if (msg && msg->text)
|
2006-09-23 00:44:47 +08:00
|
|
|
{
|
2014-05-07 21:30:38 +08:00
|
|
|
gimp_statusbar_set_text (statusbar, msg->icon_name, msg->text);
|
2006-09-23 00:44:47 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-04-14 18:10:02 +08:00
|
|
|
gimp_statusbar_set_text (statusbar, NULL, "");
|
2006-09-23 00:44:47 +08:00
|
|
|
}
|
2002-02-03 20:10:23 +08:00
|
|
|
}
|
|
|
|
|
2006-09-23 00:44:47 +08:00
|
|
|
|
|
|
|
/* public functions */
|
|
|
|
|
2003-10-02 01:32:14 +08:00
|
|
|
GtkWidget *
|
2009-09-24 15:40:32 +08:00
|
|
|
gimp_statusbar_new (void)
|
2002-02-03 20:10:23 +08:00
|
|
|
{
|
2009-09-24 15:40:32 +08:00
|
|
|
return g_object_new (GIMP_TYPE_STATUSBAR, NULL);
|
2009-09-24 15:35:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_statusbar_set_shell (GimpStatusbar *statusbar,
|
|
|
|
GimpDisplayShell *shell)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
|
|
|
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
|
|
|
|
|
|
|
if (shell == statusbar->shell)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (statusbar->shell)
|
|
|
|
{
|
|
|
|
g_signal_handlers_disconnect_by_func (statusbar->shell,
|
|
|
|
gimp_statusbar_shell_scaled,
|
|
|
|
statusbar);
|
2017-11-15 10:37:20 +08:00
|
|
|
g_signal_handlers_disconnect_by_func (statusbar->shell,
|
|
|
|
gimp_statusbar_shell_rotated,
|
|
|
|
statusbar);
|
2009-10-04 21:31:38 +08:00
|
|
|
g_signal_handlers_disconnect_by_func (statusbar->shell,
|
|
|
|
gimp_statusbar_shell_status_notify,
|
|
|
|
statusbar);
|
2022-08-02 07:22:05 +08:00
|
|
|
if (statusbar->shell->color_config)
|
|
|
|
g_signal_handlers_disconnect_by_func (statusbar->shell->color_config,
|
|
|
|
gimp_statusbar_shell_color_config_notify,
|
|
|
|
statusbar);
|
2009-09-24 15:35:34 +08:00
|
|
|
}
|
|
|
|
|
2022-08-08 12:05:53 +08:00
|
|
|
if (statusbar->gimp)
|
|
|
|
{
|
|
|
|
GimpContext *context;
|
|
|
|
|
|
|
|
context = gimp_get_user_context (statusbar->gimp);
|
|
|
|
|
|
|
|
g_signal_handlers_disconnect_by_func (context,
|
|
|
|
gimp_statusbar_shell_image_changed,
|
|
|
|
statusbar);
|
|
|
|
gimp_statusbar_shell_set_image (statusbar, NULL);
|
|
|
|
}
|
|
|
|
|
2002-06-27 06:16:59 +08:00
|
|
|
statusbar->shell = shell;
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2009-09-24 15:35:34 +08:00
|
|
|
g_signal_connect_object (statusbar->shell, "scaled",
|
2004-05-10 18:33:21 +08:00
|
|
|
G_CALLBACK (gimp_statusbar_shell_scaled),
|
|
|
|
statusbar, 0);
|
2017-11-15 10:37:20 +08:00
|
|
|
g_signal_connect_object (statusbar->shell, "rotated",
|
|
|
|
G_CALLBACK (gimp_statusbar_shell_rotated),
|
|
|
|
statusbar, 0);
|
2009-10-04 21:31:38 +08:00
|
|
|
g_signal_connect_object (statusbar->shell, "notify::status",
|
|
|
|
G_CALLBACK (gimp_statusbar_shell_status_notify),
|
|
|
|
statusbar, 0);
|
2022-08-02 07:22:05 +08:00
|
|
|
|
|
|
|
if (statusbar->shell->color_config)
|
|
|
|
g_signal_connect (statusbar->shell->color_config, "notify",
|
|
|
|
G_CALLBACK (gimp_statusbar_shell_color_config_notify),
|
|
|
|
statusbar);
|
|
|
|
|
2022-08-08 12:05:53 +08:00
|
|
|
statusbar->gimp = gimp_display_get_gimp (statusbar->shell->display);
|
|
|
|
if (statusbar->gimp)
|
|
|
|
{
|
|
|
|
GimpContext *context;
|
|
|
|
GimpImage *image;
|
|
|
|
|
|
|
|
context = gimp_get_user_context (statusbar->gimp);
|
|
|
|
image = gimp_context_get_image (context);
|
|
|
|
|
|
|
|
g_signal_connect_swapped (context, "image-changed",
|
|
|
|
G_CALLBACK (gimp_statusbar_shell_image_changed),
|
|
|
|
statusbar);
|
|
|
|
gimp_statusbar_shell_image_changed (statusbar, image, context);
|
|
|
|
}
|
|
|
|
|
2017-11-15 10:37:20 +08:00
|
|
|
gimp_statusbar_shell_rotated (shell, statusbar);
|
2002-02-03 20:10:23 +08:00
|
|
|
}
|
|
|
|
|
2007-05-29 01:42:55 +08:00
|
|
|
gboolean
|
|
|
|
gimp_statusbar_get_visible (GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_STATUSBAR (statusbar), FALSE);
|
|
|
|
|
|
|
|
if (statusbar->progress_shown)
|
|
|
|
return FALSE;
|
|
|
|
|
2009-10-18 01:51:33 +08:00
|
|
|
return gtk_widget_get_visible (GTK_WIDGET (statusbar));
|
2007-05-29 01:42:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_statusbar_set_visible (GimpStatusbar *statusbar,
|
|
|
|
gboolean visible)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
|
|
|
|
|
|
|
if (statusbar->progress_shown)
|
|
|
|
{
|
|
|
|
if (visible)
|
|
|
|
{
|
|
|
|
statusbar->progress_shown = FALSE;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-17 20:56:28 +08:00
|
|
|
gtk_widget_set_visible (GTK_WIDGET (statusbar), visible);
|
2007-05-29 01:42:55 +08:00
|
|
|
}
|
|
|
|
|
2008-03-20 00:54:01 +08:00
|
|
|
void
|
|
|
|
gimp_statusbar_empty (GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
|
|
|
|
2008-03-27 18:43:55 +08:00
|
|
|
gtk_widget_hide (statusbar->cursor_label);
|
2008-03-20 00:54:01 +08:00
|
|
|
gtk_widget_hide (statusbar->unit_combo);
|
|
|
|
gtk_widget_hide (statusbar->scale_combo);
|
2018-06-04 21:13:23 +08:00
|
|
|
gtk_widget_hide (statusbar->rotate_widget);
|
2017-11-16 02:56:33 +08:00
|
|
|
gtk_widget_hide (statusbar->horizontal_flip_icon);
|
|
|
|
gtk_widget_hide (statusbar->vertical_flip_icon);
|
2022-08-02 07:22:05 +08:00
|
|
|
gtk_widget_hide (statusbar->soft_proof_button);
|
2008-03-20 00:54:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_statusbar_fill (GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
|
|
|
|
2008-03-27 18:43:55 +08:00
|
|
|
gtk_widget_show (statusbar->cursor_label);
|
2008-03-20 00:54:01 +08:00
|
|
|
gtk_widget_show (statusbar->unit_combo);
|
|
|
|
gtk_widget_show (statusbar->scale_combo);
|
2018-06-04 21:13:23 +08:00
|
|
|
gtk_widget_show (statusbar->rotate_widget);
|
2022-08-02 07:22:05 +08:00
|
|
|
gtk_widget_show (statusbar->soft_proof_button);
|
2017-11-15 10:37:20 +08:00
|
|
|
gimp_statusbar_shell_rotated (statusbar->shell, statusbar);
|
2008-03-20 00:54:01 +08:00
|
|
|
}
|
|
|
|
|
2009-09-26 01:35:03 +08:00
|
|
|
void
|
|
|
|
gimp_statusbar_override_window_title (GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
GtkWidget *toplevel;
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
|
|
|
|
|
|
|
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (statusbar));
|
|
|
|
|
|
|
|
if (gimp_image_window_is_iconified (GIMP_IMAGE_WINDOW (toplevel)))
|
|
|
|
{
|
|
|
|
const gchar *message = gimp_statusbar_peek (statusbar, "progress");
|
|
|
|
|
|
|
|
if (message)
|
|
|
|
gtk_window_set_title (GTK_WINDOW (toplevel), message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_statusbar_restore_window_title (GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
GtkWidget *toplevel;
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
|
|
|
|
|
|
|
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (statusbar));
|
|
|
|
|
|
|
|
if (gimp_image_window_is_iconified (GIMP_IMAGE_WINDOW (toplevel)))
|
|
|
|
{
|
2009-09-30 04:20:12 +08:00
|
|
|
g_object_notify (G_OBJECT (statusbar->shell), "title");
|
2009-09-26 01:35:03 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-07-15 00:37:13 +08:00
|
|
|
void
|
2002-02-03 20:10:23 +08:00
|
|
|
gimp_statusbar_push (GimpStatusbar *statusbar,
|
2004-06-19 21:31:58 +08:00
|
|
|
const gchar *context,
|
2014-05-07 21:30:38 +08:00
|
|
|
const gchar *icon_name,
|
2006-09-23 00:44:47 +08:00
|
|
|
const gchar *format,
|
|
|
|
...)
|
2006-09-28 19:07:55 +08:00
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
|
|
|
g_return_if_fail (context != NULL);
|
|
|
|
g_return_if_fail (format != NULL);
|
|
|
|
|
|
|
|
va_start (args, format);
|
2014-05-07 21:30:38 +08:00
|
|
|
gimp_statusbar_push_valist (statusbar, context, icon_name, format, args);
|
2006-09-28 19:07:55 +08:00
|
|
|
va_end (args);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_statusbar_push_valist (GimpStatusbar *statusbar,
|
|
|
|
const gchar *context,
|
2014-05-07 21:30:38 +08:00
|
|
|
const gchar *icon_name,
|
2006-09-28 19:07:55 +08:00
|
|
|
const gchar *format,
|
|
|
|
va_list args)
|
2002-02-03 20:10:23 +08:00
|
|
|
{
|
2016-04-20 16:25:14 +08:00
|
|
|
guint context_id;
|
2004-05-10 18:33:21 +08:00
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
2006-09-01 20:15:14 +08:00
|
|
|
g_return_if_fail (context != NULL);
|
2006-09-23 00:44:47 +08:00
|
|
|
g_return_if_fail (format != NULL);
|
|
|
|
|
2004-06-19 21:31:58 +08:00
|
|
|
context_id = gimp_statusbar_get_context_id (statusbar, context);
|
|
|
|
|
2016-04-20 16:25:14 +08:00
|
|
|
gimp_statusbar_add_message (statusbar,
|
|
|
|
context_id,
|
|
|
|
icon_name, format, args,
|
|
|
|
/* move_to_front = */ TRUE);
|
2004-06-19 21:31:58 +08:00
|
|
|
}
|
|
|
|
|
2004-07-15 00:37:13 +08:00
|
|
|
void
|
2008-08-21 00:22:09 +08:00
|
|
|
gimp_statusbar_push_coords (GimpStatusbar *statusbar,
|
|
|
|
const gchar *context,
|
2014-05-07 21:30:38 +08:00
|
|
|
const gchar *icon_name,
|
2008-08-21 00:22:09 +08:00
|
|
|
GimpCursorPrecision precision,
|
|
|
|
const gchar *title,
|
|
|
|
gdouble x,
|
|
|
|
const gchar *separator,
|
|
|
|
gdouble y,
|
|
|
|
const gchar *help)
|
2002-02-03 20:10:23 +08:00
|
|
|
{
|
2004-06-02 06:04:20 +08:00
|
|
|
GimpDisplayShell *shell;
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2004-11-10 09:17:40 +08:00
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
2004-07-15 00:37:13 +08:00
|
|
|
g_return_if_fail (title != NULL);
|
|
|
|
g_return_if_fail (separator != NULL);
|
2007-12-27 01:33:41 +08:00
|
|
|
|
2007-01-21 09:24:51 +08:00
|
|
|
if (help == NULL)
|
2007-12-27 01:33:41 +08:00
|
|
|
help = "";
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2004-06-02 06:04:20 +08:00
|
|
|
shell = statusbar->shell;
|
2004-05-07 23:45:56 +08:00
|
|
|
|
2008-08-21 00:22:09 +08:00
|
|
|
switch (precision)
|
|
|
|
{
|
|
|
|
case GIMP_CURSOR_PRECISION_PIXEL_CENTER:
|
2009-02-21 00:57:26 +08:00
|
|
|
x = (gint) x;
|
|
|
|
y = (gint) y;
|
2008-08-21 00:22:09 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case GIMP_CURSOR_PRECISION_PIXEL_BORDER:
|
|
|
|
x = RINT (x);
|
|
|
|
y = RINT (y);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GIMP_CURSOR_PRECISION_SUBPIXEL:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2004-06-02 06:04:20 +08:00
|
|
|
if (shell->unit == GIMP_UNIT_PIXEL)
|
2002-02-03 20:10:23 +08:00
|
|
|
{
|
2008-08-21 00:22:09 +08:00
|
|
|
if (precision == GIMP_CURSOR_PRECISION_SUBPIXEL)
|
|
|
|
{
|
|
|
|
gimp_statusbar_push (statusbar, context,
|
2014-05-07 21:30:38 +08:00
|
|
|
icon_name,
|
2008-08-21 00:22:09 +08:00
|
|
|
statusbar->cursor_format_str_f,
|
|
|
|
title,
|
|
|
|
x,
|
|
|
|
separator,
|
|
|
|
y,
|
|
|
|
help);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gimp_statusbar_push (statusbar, context,
|
2014-05-07 21:30:38 +08:00
|
|
|
icon_name,
|
2008-08-21 00:22:09 +08:00
|
|
|
statusbar->cursor_format_str,
|
|
|
|
title,
|
|
|
|
(gint) RINT (x),
|
|
|
|
separator,
|
|
|
|
(gint) RINT (y),
|
|
|
|
help);
|
|
|
|
}
|
2002-02-03 20:10:23 +08:00
|
|
|
}
|
|
|
|
else /* show real world units */
|
|
|
|
{
|
2008-03-19 05:22:21 +08:00
|
|
|
gdouble xres;
|
|
|
|
gdouble yres;
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2009-10-07 01:20:44 +08:00
|
|
|
gimp_image_get_resolution (gimp_display_get_image (shell->display),
|
|
|
|
&xres, &yres);
|
2007-12-27 01:33:41 +08:00
|
|
|
|
2006-09-23 00:44:47 +08:00
|
|
|
gimp_statusbar_push (statusbar, context,
|
2014-05-07 21:30:38 +08:00
|
|
|
icon_name,
|
2006-09-23 00:44:47 +08:00
|
|
|
statusbar->cursor_format_str,
|
|
|
|
title,
|
2010-02-21 23:46:39 +08:00
|
|
|
gimp_pixels_to_units (x, shell->unit, xres),
|
2006-09-23 00:44:47 +08:00
|
|
|
separator,
|
2010-02-21 23:46:39 +08:00
|
|
|
gimp_pixels_to_units (y, shell->unit, yres),
|
2007-01-21 09:24:51 +08:00
|
|
|
help);
|
2002-02-03 20:10:23 +08:00
|
|
|
}
|
2004-07-15 00:37:13 +08:00
|
|
|
}
|
|
|
|
|
2004-11-10 09:17:40 +08:00
|
|
|
void
|
|
|
|
gimp_statusbar_push_length (GimpStatusbar *statusbar,
|
|
|
|
const gchar *context,
|
2014-05-07 21:30:38 +08:00
|
|
|
const gchar *icon_name,
|
2004-11-10 09:17:40 +08:00
|
|
|
const gchar *title,
|
|
|
|
GimpOrientationType axis,
|
2007-01-21 09:24:51 +08:00
|
|
|
gdouble value,
|
|
|
|
const gchar *help)
|
2004-11-10 09:17:40 +08:00
|
|
|
{
|
|
|
|
GimpDisplayShell *shell;
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
|
|
|
g_return_if_fail (title != NULL);
|
2007-12-27 01:33:41 +08:00
|
|
|
|
2007-01-21 09:24:51 +08:00
|
|
|
if (help == NULL)
|
2007-12-27 01:33:41 +08:00
|
|
|
help = "";
|
2004-11-10 09:17:40 +08:00
|
|
|
|
|
|
|
shell = statusbar->shell;
|
|
|
|
|
|
|
|
if (shell->unit == GIMP_UNIT_PIXEL)
|
|
|
|
{
|
2006-09-23 00:44:47 +08:00
|
|
|
gimp_statusbar_push (statusbar, context,
|
2014-05-07 21:30:38 +08:00
|
|
|
icon_name,
|
2006-09-23 00:44:47 +08:00
|
|
|
statusbar->length_format_str,
|
|
|
|
title,
|
2007-01-21 09:24:51 +08:00
|
|
|
(gint) RINT (value),
|
|
|
|
help);
|
2004-11-10 09:17:40 +08:00
|
|
|
}
|
|
|
|
else /* show real world units */
|
|
|
|
{
|
2008-03-19 05:22:21 +08:00
|
|
|
gdouble xres;
|
|
|
|
gdouble yres;
|
|
|
|
gdouble resolution;
|
2004-11-10 09:17:40 +08:00
|
|
|
|
2009-10-07 01:20:44 +08:00
|
|
|
gimp_image_get_resolution (gimp_display_get_image (shell->display),
|
|
|
|
&xres, &yres);
|
2007-12-27 01:33:41 +08:00
|
|
|
|
2004-11-10 09:17:40 +08:00
|
|
|
switch (axis)
|
|
|
|
{
|
|
|
|
case GIMP_ORIENTATION_HORIZONTAL:
|
2007-12-27 01:33:41 +08:00
|
|
|
resolution = xres;
|
2004-11-10 09:17:40 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case GIMP_ORIENTATION_VERTICAL:
|
2007-12-27 01:33:41 +08:00
|
|
|
resolution = yres;
|
2004-11-10 09:17:40 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_return_if_reached ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-09-23 00:44:47 +08:00
|
|
|
gimp_statusbar_push (statusbar, context,
|
2014-05-07 21:30:38 +08:00
|
|
|
icon_name,
|
2006-09-23 00:44:47 +08:00
|
|
|
statusbar->length_format_str,
|
|
|
|
title,
|
2010-02-21 23:46:39 +08:00
|
|
|
gimp_pixels_to_units (value, shell->unit, resolution),
|
2007-01-21 09:24:51 +08:00
|
|
|
help);
|
2004-11-10 09:17:40 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-07-15 00:37:13 +08:00
|
|
|
void
|
|
|
|
gimp_statusbar_replace (GimpStatusbar *statusbar,
|
|
|
|
const gchar *context,
|
2014-05-07 21:30:38 +08:00
|
|
|
const gchar *icon_name,
|
2006-09-23 00:44:47 +08:00
|
|
|
const gchar *format,
|
|
|
|
...)
|
2006-09-28 19:07:55 +08:00
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
|
|
|
g_return_if_fail (context != NULL);
|
|
|
|
g_return_if_fail (format != NULL);
|
|
|
|
|
|
|
|
va_start (args, format);
|
2014-05-07 21:30:38 +08:00
|
|
|
gimp_statusbar_replace_valist (statusbar, context, icon_name, format, args);
|
2006-09-28 19:07:55 +08:00
|
|
|
va_end (args);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_statusbar_replace_valist (GimpStatusbar *statusbar,
|
|
|
|
const gchar *context,
|
2014-05-07 21:30:38 +08:00
|
|
|
const gchar *icon_name,
|
2006-09-28 19:07:55 +08:00
|
|
|
const gchar *format,
|
|
|
|
va_list args)
|
2004-07-15 00:37:13 +08:00
|
|
|
{
|
2016-04-20 16:25:14 +08:00
|
|
|
guint context_id;
|
2004-07-15 00:37:13 +08:00
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
2006-09-01 20:15:14 +08:00
|
|
|
g_return_if_fail (context != NULL);
|
2006-09-23 00:44:47 +08:00
|
|
|
g_return_if_fail (format != NULL);
|
2004-07-15 00:37:13 +08:00
|
|
|
|
|
|
|
context_id = gimp_statusbar_get_context_id (statusbar, context);
|
|
|
|
|
2016-04-20 16:25:14 +08:00
|
|
|
gimp_statusbar_add_message (statusbar,
|
|
|
|
context_id,
|
|
|
|
icon_name, format, args,
|
|
|
|
/* move_to_front = */ FALSE);
|
2002-02-03 20:10:23 +08:00
|
|
|
}
|
|
|
|
|
2008-03-25 22:07:10 +08:00
|
|
|
const gchar *
|
|
|
|
gimp_statusbar_peek (GimpStatusbar *statusbar,
|
|
|
|
const gchar *context)
|
|
|
|
{
|
|
|
|
GSList *list;
|
|
|
|
guint context_id;
|
|
|
|
|
2008-03-25 22:31:05 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_STATUSBAR (statusbar), NULL);
|
|
|
|
g_return_val_if_fail (context != NULL, NULL);
|
2008-03-25 22:07:10 +08:00
|
|
|
|
|
|
|
context_id = gimp_statusbar_get_context_id (statusbar, context);
|
|
|
|
|
|
|
|
for (list = statusbar->messages; list; list = list->next)
|
|
|
|
{
|
|
|
|
GimpStatusbarMsg *msg = list->data;
|
|
|
|
|
|
|
|
if (msg->context_id == context_id)
|
|
|
|
{
|
|
|
|
return msg->text;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2004-07-15 00:37:13 +08:00
|
|
|
void
|
|
|
|
gimp_statusbar_pop (GimpStatusbar *statusbar,
|
|
|
|
const gchar *context)
|
|
|
|
{
|
2016-04-20 16:25:14 +08:00
|
|
|
guint context_id;
|
2004-07-15 00:37:13 +08:00
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
2006-09-01 20:15:14 +08:00
|
|
|
g_return_if_fail (context != NULL);
|
2004-07-15 00:37:13 +08:00
|
|
|
|
|
|
|
context_id = gimp_statusbar_get_context_id (statusbar, context);
|
|
|
|
|
2016-04-20 16:25:14 +08:00
|
|
|
gimp_statusbar_remove_message (statusbar,
|
|
|
|
context_id);
|
2004-07-15 00:37:13 +08:00
|
|
|
}
|
2004-06-19 21:31:58 +08:00
|
|
|
|
2006-09-23 00:44:47 +08:00
|
|
|
void
|
2008-08-16 00:32:09 +08:00
|
|
|
gimp_statusbar_push_temp (GimpStatusbar *statusbar,
|
|
|
|
GimpMessageSeverity severity,
|
2014-05-07 21:30:38 +08:00
|
|
|
const gchar *icon_name,
|
2008-08-16 00:32:09 +08:00
|
|
|
const gchar *format,
|
2006-09-23 00:44:47 +08:00
|
|
|
...)
|
2006-09-28 19:07:55 +08:00
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
va_start (args, format);
|
2014-05-07 21:30:38 +08:00
|
|
|
gimp_statusbar_push_temp_valist (statusbar, severity, icon_name, format, args);
|
2006-09-28 19:07:55 +08:00
|
|
|
va_end (args);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2008-08-16 00:32:09 +08:00
|
|
|
gimp_statusbar_push_temp_valist (GimpStatusbar *statusbar,
|
|
|
|
GimpMessageSeverity severity,
|
2014-05-07 21:30:38 +08:00
|
|
|
const gchar *icon_name,
|
2008-08-16 00:32:09 +08:00
|
|
|
const gchar *format,
|
|
|
|
va_list args)
|
2006-09-23 00:44:47 +08:00
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
2008-08-16 00:32:09 +08:00
|
|
|
g_return_if_fail (severity <= GIMP_MESSAGE_WARNING);
|
2006-09-23 00:44:47 +08:00
|
|
|
g_return_if_fail (format != NULL);
|
|
|
|
|
2008-08-16 00:32:09 +08:00
|
|
|
/* don't accept a message if we are already displaying a more severe one */
|
|
|
|
if (statusbar->temp_timeout_id && statusbar->temp_severity > severity)
|
|
|
|
return;
|
|
|
|
|
2006-09-23 00:44:47 +08:00
|
|
|
if (statusbar->temp_timeout_id)
|
|
|
|
g_source_remove (statusbar->temp_timeout_id);
|
|
|
|
|
|
|
|
statusbar->temp_timeout_id =
|
2007-01-08 23:41:47 +08:00
|
|
|
g_timeout_add (MESSAGE_TIMEOUT,
|
|
|
|
(GSourceFunc) gimp_statusbar_temp_timeout, statusbar);
|
2006-09-23 00:44:47 +08:00
|
|
|
|
2008-08-16 00:32:09 +08:00
|
|
|
statusbar->temp_severity = severity;
|
|
|
|
|
2016-04-20 16:25:14 +08:00
|
|
|
gimp_statusbar_add_message (statusbar,
|
|
|
|
statusbar->temp_context_id,
|
|
|
|
icon_name, format, args,
|
|
|
|
/* move_to_front = */ TRUE);
|
2017-10-28 20:50:51 +08:00
|
|
|
|
|
|
|
if (severity >= GIMP_MESSAGE_WARNING)
|
|
|
|
gimp_widget_blink (statusbar->label);
|
2006-09-23 00:44:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_statusbar_pop_temp (GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
|
|
|
|
|
|
|
if (statusbar->temp_timeout_id)
|
|
|
|
{
|
|
|
|
g_source_remove (statusbar->temp_timeout_id);
|
|
|
|
statusbar->temp_timeout_id = 0;
|
|
|
|
|
2016-04-20 16:25:14 +08:00
|
|
|
gimp_statusbar_remove_message (statusbar,
|
|
|
|
statusbar->temp_context_id);
|
2006-09-23 00:44:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-02-03 20:10:23 +08:00
|
|
|
void
|
2008-08-21 00:22:09 +08:00
|
|
|
gimp_statusbar_update_cursor (GimpStatusbar *statusbar,
|
|
|
|
GimpCursorPrecision precision,
|
|
|
|
gdouble x,
|
|
|
|
gdouble y)
|
2002-02-03 20:10:23 +08:00
|
|
|
{
|
2004-06-02 06:04:20 +08:00
|
|
|
GimpDisplayShell *shell;
|
2009-10-07 01:20:44 +08:00
|
|
|
GimpImage *image;
|
2004-06-02 06:04:20 +08:00
|
|
|
gchar buffer[CURSOR_LEN];
|
2002-02-03 20:10:23 +08:00
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
|
|
|
|
|
2004-06-02 06:04:20 +08:00
|
|
|
shell = statusbar->shell;
|
2009-10-07 01:20:44 +08:00
|
|
|
image = gimp_display_get_image (shell->display);
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2009-10-07 01:20:44 +08:00
|
|
|
if (! image ||
|
|
|
|
x < 0 ||
|
|
|
|
y < 0 ||
|
|
|
|
x >= gimp_image_get_width (image) ||
|
|
|
|
y >= gimp_image_get_height (image))
|
2006-07-13 16:06:06 +08:00
|
|
|
{
|
|
|
|
gtk_widget_set_sensitive (statusbar->cursor_label, FALSE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gtk_widget_set_sensitive (statusbar->cursor_label, TRUE);
|
|
|
|
}
|
|
|
|
|
2008-08-21 00:22:09 +08:00
|
|
|
switch (precision)
|
|
|
|
{
|
|
|
|
case GIMP_CURSOR_PRECISION_PIXEL_CENTER:
|
2009-02-21 00:57:26 +08:00
|
|
|
x = (gint) x;
|
|
|
|
y = (gint) y;
|
2008-08-21 00:22:09 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case GIMP_CURSOR_PRECISION_PIXEL_BORDER:
|
|
|
|
x = RINT (x);
|
|
|
|
y = RINT (y);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GIMP_CURSOR_PRECISION_SUBPIXEL:
|
|
|
|
break;
|
|
|
|
}
|
2022-03-09 20:16:01 +08:00
|
|
|
statusbar->cursor_precision = precision;
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2004-06-02 06:04:20 +08:00
|
|
|
if (shell->unit == GIMP_UNIT_PIXEL)
|
2002-02-03 20:10:23 +08:00
|
|
|
{
|
2008-08-21 00:22:09 +08:00
|
|
|
if (precision == GIMP_CURSOR_PRECISION_SUBPIXEL)
|
|
|
|
{
|
|
|
|
g_snprintf (buffer, sizeof (buffer),
|
|
|
|
statusbar->cursor_format_str_f,
|
|
|
|
"", x, ", ", y, "");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_snprintf (buffer, sizeof (buffer),
|
|
|
|
statusbar->cursor_format_str,
|
|
|
|
"", (gint) RINT (x), ", ", (gint) RINT (y), "");
|
|
|
|
}
|
2003-10-02 01:32:14 +08:00
|
|
|
}
|
2004-05-10 18:33:21 +08:00
|
|
|
else /* show real world units */
|
2002-02-03 20:10:23 +08:00
|
|
|
{
|
2008-08-21 00:22:09 +08:00
|
|
|
GtkTreeModel *model;
|
|
|
|
GimpUnitStore *store;
|
|
|
|
|
|
|
|
model = gtk_combo_box_get_model (GTK_COMBO_BOX (statusbar->unit_combo));
|
|
|
|
store = GIMP_UNIT_STORE (model);
|
|
|
|
|
|
|
|
gimp_unit_store_set_pixel_values (store, x, y);
|
2004-06-02 06:04:20 +08:00
|
|
|
gimp_unit_store_get_values (store, shell->unit, &x, &y);
|
2004-05-10 18:33:21 +08:00
|
|
|
|
2004-06-02 06:04:20 +08:00
|
|
|
g_snprintf (buffer, sizeof (buffer),
|
|
|
|
statusbar->cursor_format_str,
|
2007-01-21 09:24:51 +08:00
|
|
|
"", x, ", ", y, "");
|
2002-02-03 20:10:23 +08:00
|
|
|
}
|
2004-05-10 18:33:21 +08:00
|
|
|
|
macos: Fix 7690 (slow drawing)
Gets drawing in the canvas speed on retina displays up to the speed
of FullHD displays on macOS, making 2.99 usable on macOS.
Generic change:
Changes the cursor_label to delay the drawing phase to the idle
queue, from immediate draw on all platforms.
Before the fix in 32049afd (using a deprecated function in Gtk3)
any draws on this label forced a full canvas redraw. This is due
to a quirk in how GtkLabel functions.
The redraw occurred because GtkLabels resize themselves and everything
around them by sending a resize message any time they receive new
text. These resizes then trigger the full canvas resize which triggers
a full canvas redraw that cannot be optimized by either Gtk or Big Sur.
MacOS changes:
Only redraws the cursor position label and each of the horizontal and
vertical rules (cursor tracking widgets) 3 times a second max for a
total of 9 redraws a second (ideally out of 60, though I don't believe
under any circumstances that GIMP achieves a 60fps).
Each of the cursor tracking widgets gets its own timeslice, and so
will not redraw when the other cursor tracking widgets are drawing.
This is required because Big Sur is merging all draw rects into
one large rect, dramatically slowing down draws.
This timeslicing ensures that draw rects are maintained at the smallest
possible size. So the typical redraw is a small rect around the
brush. However, 9 times a second, the rect will include one of the
3 cursor tracking widgets (rulers and cursor label).
Additionally, the code tries to minimize resizing the width of the
cursor label by checking if the widget is too small for the text,
then setting the char_width to a greater size so that resizes won't
be that common.
This improves the appearance of the widget as it no longer
constantly jumps about in size on each cursor move.
Here is a discussion of the issue:
https://gitlab.gnome.org/GNOME/gimp/-/merge_requests/572#note_1389445
Reviewer's (Jehan) notes:
* The whole issue about GtkLabel resizing is no more after 32049afd. It
is normal for a widget to request a resize when needed. We just don't
want the statusbar to resize and triggering canvas redraws.
* Changing cursor position text into an idle function generally makes
sense.
Also it reverts commit 6de9ea70223 which had a bug I hadn't realized
when I accepted it: when we test for time, we don't know yet if it
will be the last position change, hence we could "refuse" the last
update. Therefore displayed cursor position would end up outdated
on macOS. This new implementation doesn't have the problem (the last
idle update always happens after the last move).
* The change about giving 1/3 timeslices to side canvas components
(rulers and statusbar) is a complete hack to work around the fact that
macOs doesn't report properly each damaged rectangle. Instead it
returns a huge bounding box. The workaround here is to expose these
area separately.
We have not been able to find a proper solution yet. This is the only
reason why I accept this code, for macOS only, to at least have
something usable there.
See discussions in MRs gimp!572 and gimp-macos-build!86. With these 2
MRs, Lukas reported GIMP 2.99 to perform even better than GIMP 2.10 on
Monterey, though it could not be tested on Big Sur unfortunately.
* Lastly the set_width_chars() thing is also an ugly hack which I will
try later to revisit (see !581). I only accepted it (with mandatory
macOS-only macro) to have an acceptable state for release after seeing
a screencast where the label size indeed "jumps around" on macOS.
2022-02-19 09:25:51 +08:00
|
|
|
if (g_strcmp0 (buffer, statusbar->cursor_string_last) == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
g_free (statusbar->cursor_string_todraw);
|
|
|
|
statusbar->cursor_string_todraw = g_strdup (buffer);
|
|
|
|
|
|
|
|
if (statusbar->statusbar_pos_redraw_idle_id == 0)
|
|
|
|
{
|
|
|
|
statusbar->statusbar_pos_redraw_idle_id =
|
|
|
|
g_idle_add_full (G_PRIORITY_LOW,
|
|
|
|
gimp_statusbar_queue_pos_redraw,
|
|
|
|
statusbar,
|
|
|
|
NULL);
|
|
|
|
}
|
2002-02-03 20:10:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-05-10 18:33:21 +08:00
|
|
|
gimp_statusbar_clear_cursor (GimpStatusbar *statusbar)
|
|
|
|
{
|
2022-03-09 18:49:24 +08:00
|
|
|
gtk_label_set_text (GTK_LABEL (statusbar->cursor_label), "");
|
2004-08-05 22:56:18 +08:00
|
|
|
gtk_widget_set_sensitive (statusbar->cursor_label, TRUE);
|
2004-05-10 18:33:21 +08:00
|
|
|
}
|
|
|
|
|
2006-09-23 00:44:47 +08:00
|
|
|
|
|
|
|
/* private functions */
|
|
|
|
|
|
|
|
static gboolean
|
2010-10-20 02:26:16 +08:00
|
|
|
gimp_statusbar_label_draw (GtkWidget *widget,
|
|
|
|
cairo_t *cr,
|
|
|
|
GimpStatusbar *statusbar)
|
2006-09-23 00:44:47 +08:00
|
|
|
{
|
2008-04-14 18:10:02 +08:00
|
|
|
if (statusbar->icon)
|
2006-10-09 16:17:22 +08:00
|
|
|
{
|
2019-01-01 02:12:00 +08:00
|
|
|
cairo_surface_t *surface;
|
|
|
|
PangoRectangle rect;
|
|
|
|
GtkAllocation allocation;
|
|
|
|
gint scale_factor;
|
|
|
|
gint x, y;
|
2008-04-14 18:10:02 +08:00
|
|
|
|
|
|
|
gtk_label_get_layout_offsets (GTK_LABEL (widget), &x, &y);
|
|
|
|
|
2010-11-19 21:00:33 +08:00
|
|
|
gtk_widget_get_allocation (widget, &allocation);
|
|
|
|
x -= allocation.x;
|
|
|
|
y -= allocation.y;
|
|
|
|
|
2008-04-14 18:10:02 +08:00
|
|
|
pango_layout_index_to_pos (gtk_label_get_layout (GTK_LABEL (widget)), 0,
|
|
|
|
&rect);
|
|
|
|
|
2008-04-14 19:05:18 +08:00
|
|
|
/* the rectangle width is negative when rendering right-to-left */
|
|
|
|
x += PANGO_PIXELS (rect.x) + (rect.width < 0 ?
|
|
|
|
PANGO_PIXELS (rect.width) : 0);
|
|
|
|
y += PANGO_PIXELS (rect.y);
|
|
|
|
|
2019-01-01 02:12:00 +08:00
|
|
|
scale_factor = gtk_widget_get_scale_factor (widget);
|
|
|
|
surface = gdk_cairo_surface_create_from_pixbuf (statusbar->icon,
|
|
|
|
scale_factor, NULL);
|
|
|
|
cairo_set_source_surface (cr, surface, x, y);
|
|
|
|
cairo_surface_destroy (surface);
|
|
|
|
|
2010-07-30 19:14:10 +08:00
|
|
|
cairo_paint (cr);
|
2006-10-09 16:17:22 +08:00
|
|
|
}
|
2006-09-23 00:44:47 +08:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2004-05-10 18:33:21 +08:00
|
|
|
static void
|
|
|
|
gimp_statusbar_shell_scaled (GimpDisplayShell *shell,
|
|
|
|
GimpStatusbar *statusbar)
|
2002-02-03 20:10:23 +08:00
|
|
|
{
|
|
|
|
static PangoLayout *layout = NULL;
|
|
|
|
|
2009-10-07 01:20:44 +08:00
|
|
|
GimpImage *image = gimp_display_get_image (shell->display);
|
2004-05-10 18:33:21 +08:00
|
|
|
GtkTreeModel *model;
|
|
|
|
const gchar *text;
|
2008-03-19 05:22:21 +08:00
|
|
|
gint image_width;
|
|
|
|
gint image_height;
|
|
|
|
gdouble image_xres;
|
|
|
|
gdouble image_yres;
|
2004-05-10 18:33:21 +08:00
|
|
|
gint width;
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2008-03-19 05:22:21 +08:00
|
|
|
if (image)
|
|
|
|
{
|
|
|
|
image_width = gimp_image_get_width (image);
|
|
|
|
image_height = gimp_image_get_height (image);
|
|
|
|
gimp_image_get_resolution (image, &image_xres, &image_yres);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
image_width = shell->disp_width;
|
|
|
|
image_height = shell->disp_height;
|
|
|
|
image_xres = shell->display->config->monitor_xres;
|
|
|
|
image_yres = shell->display->config->monitor_yres;
|
|
|
|
}
|
|
|
|
|
2004-05-10 18:33:21 +08:00
|
|
|
g_signal_handlers_block_by_func (statusbar->scale_combo,
|
|
|
|
gimp_statusbar_scale_changed, statusbar);
|
|
|
|
gimp_scale_combo_box_set_scale (GIMP_SCALE_COMBO_BOX (statusbar->scale_combo),
|
2005-09-26 01:03:03 +08:00
|
|
|
gimp_zoom_model_get_factor (shell->zoom));
|
2004-05-10 18:33:21 +08:00
|
|
|
g_signal_handlers_unblock_by_func (statusbar->scale_combo,
|
|
|
|
gimp_statusbar_scale_changed, statusbar);
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2004-05-08 07:31:01 +08:00
|
|
|
model = gtk_combo_box_get_model (GTK_COMBO_BOX (statusbar->unit_combo));
|
2008-03-19 05:22:21 +08:00
|
|
|
gimp_unit_store_set_resolutions (GIMP_UNIT_STORE (model),
|
|
|
|
image_xres, image_yres);
|
2004-05-08 06:16:15 +08:00
|
|
|
|
2004-05-08 07:31:01 +08:00
|
|
|
g_signal_handlers_block_by_func (statusbar->unit_combo,
|
2004-05-08 06:16:15 +08:00
|
|
|
gimp_statusbar_unit_changed, statusbar);
|
2004-05-10 18:33:21 +08:00
|
|
|
gimp_unit_combo_box_set_active (GIMP_UNIT_COMBO_BOX (statusbar->unit_combo),
|
2004-06-02 06:04:20 +08:00
|
|
|
shell->unit);
|
2004-05-08 07:31:01 +08:00
|
|
|
g_signal_handlers_unblock_by_func (statusbar->unit_combo,
|
2004-05-08 06:16:15 +08:00
|
|
|
gimp_statusbar_unit_changed, statusbar);
|
|
|
|
|
2004-06-02 06:04:20 +08:00
|
|
|
if (shell->unit == GIMP_UNIT_PIXEL)
|
2002-02-03 20:10:23 +08:00
|
|
|
{
|
|
|
|
g_snprintf (statusbar->cursor_format_str,
|
|
|
|
sizeof (statusbar->cursor_format_str),
|
2007-01-21 09:24:51 +08:00
|
|
|
"%%s%%d%%s%%d%%s");
|
2008-08-21 00:22:09 +08:00
|
|
|
g_snprintf (statusbar->cursor_format_str_f,
|
|
|
|
sizeof (statusbar->cursor_format_str_f),
|
|
|
|
"%%s%%.1f%%s%%.1f%%s");
|
2004-11-10 09:17:40 +08:00
|
|
|
g_snprintf (statusbar->length_format_str,
|
|
|
|
sizeof (statusbar->length_format_str),
|
2007-01-21 09:24:51 +08:00
|
|
|
"%%s%%d%%s");
|
2022-03-09 20:16:01 +08:00
|
|
|
|
|
|
|
statusbar->cursor_w_digits = 0;
|
|
|
|
statusbar->cursor_h_digits = 0;
|
2002-02-03 20:10:23 +08:00
|
|
|
}
|
|
|
|
else /* show real world units */
|
|
|
|
{
|
2017-01-24 03:52:32 +08:00
|
|
|
gint w_digits;
|
|
|
|
gint h_digits;
|
2016-11-24 01:12:51 +08:00
|
|
|
|
2017-01-24 03:52:32 +08:00
|
|
|
w_digits = gimp_unit_get_scaled_digits (shell->unit, image_xres);
|
|
|
|
h_digits = gimp_unit_get_scaled_digits (shell->unit, image_yres);
|
2016-11-24 01:12:51 +08:00
|
|
|
|
2002-02-03 20:10:23 +08:00
|
|
|
g_snprintf (statusbar->cursor_format_str,
|
|
|
|
sizeof (statusbar->cursor_format_str),
|
2007-01-21 09:24:51 +08:00
|
|
|
"%%s%%.%df%%s%%.%df%%s",
|
2016-11-24 01:12:51 +08:00
|
|
|
w_digits, h_digits);
|
2008-08-21 00:22:09 +08:00
|
|
|
strcpy (statusbar->cursor_format_str_f, statusbar->cursor_format_str);
|
2004-11-10 09:17:40 +08:00
|
|
|
g_snprintf (statusbar->length_format_str,
|
|
|
|
sizeof (statusbar->length_format_str),
|
2017-01-24 03:52:32 +08:00
|
|
|
"%%s%%.%df%%s", MAX (w_digits, h_digits));
|
2022-03-09 20:16:01 +08:00
|
|
|
|
|
|
|
statusbar->cursor_w_digits = w_digits;
|
|
|
|
statusbar->cursor_h_digits = h_digits;
|
2002-02-03 20:10:23 +08:00
|
|
|
}
|
|
|
|
|
2008-08-21 00:22:09 +08:00
|
|
|
gimp_statusbar_update_cursor (statusbar, GIMP_CURSOR_PRECISION_SUBPIXEL,
|
2010-02-12 02:55:20 +08:00
|
|
|
-image_width, -image_height);
|
2004-05-08 06:16:15 +08:00
|
|
|
|
|
|
|
text = gtk_label_get_text (GTK_LABEL (statusbar->cursor_label));
|
|
|
|
|
2002-02-03 20:10:23 +08:00
|
|
|
/* one static layout for all displays should be fine */
|
|
|
|
if (! layout)
|
2007-11-14 22:42:05 +08:00
|
|
|
layout = gtk_widget_create_pango_layout (statusbar->cursor_label, NULL);
|
2002-02-03 20:10:23 +08:00
|
|
|
|
2007-11-14 22:42:05 +08:00
|
|
|
pango_layout_set_text (layout, text, -1);
|
2004-05-10 18:33:21 +08:00
|
|
|
pango_layout_get_pixel_size (layout, &width, NULL);
|
2004-05-08 07:45:29 +08:00
|
|
|
|
2004-05-10 18:33:21 +08:00
|
|
|
gtk_widget_set_size_request (statusbar->cursor_label, width, -1);
|
|
|
|
|
|
|
|
gimp_statusbar_clear_cursor (statusbar);
|
2002-02-03 20:10:23 +08:00
|
|
|
}
|
2004-05-08 06:16:15 +08:00
|
|
|
|
2017-11-15 10:37:20 +08:00
|
|
|
static void
|
|
|
|
gimp_statusbar_shell_rotated (GimpDisplayShell *shell,
|
|
|
|
GimpStatusbar *statusbar)
|
|
|
|
{
|
2017-11-16 02:56:33 +08:00
|
|
|
if (shell->rotate_angle != 0.0)
|
|
|
|
{
|
|
|
|
/* Degree symbol U+00B0. There are no spaces between the value and the
|
2018-06-04 21:13:23 +08:00
|
|
|
* unit for angular rotation.
|
|
|
|
*/
|
|
|
|
gchar *text = g_strdup_printf (" %.2f\xC2\xB0", shell->rotate_angle);
|
|
|
|
|
|
|
|
gtk_label_set_text (GTK_LABEL (statusbar->rotate_label), text);
|
|
|
|
g_free (text);
|
|
|
|
|
|
|
|
gtk_widget_show (statusbar->rotate_widget);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gtk_widget_hide (statusbar->rotate_widget);
|
2017-11-16 02:56:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (shell->flip_horizontally)
|
|
|
|
gtk_widget_show (statusbar->horizontal_flip_icon);
|
|
|
|
else
|
|
|
|
gtk_widget_hide (statusbar->horizontal_flip_icon);
|
2018-06-04 21:13:23 +08:00
|
|
|
|
2017-11-16 02:56:33 +08:00
|
|
|
if (shell->flip_vertically)
|
|
|
|
gtk_widget_show (statusbar->vertical_flip_icon);
|
|
|
|
else
|
|
|
|
gtk_widget_hide (statusbar->vertical_flip_icon);
|
2017-11-15 10:37:20 +08:00
|
|
|
}
|
|
|
|
|
2009-10-04 21:31:38 +08:00
|
|
|
static void
|
|
|
|
gimp_statusbar_shell_status_notify (GimpDisplayShell *shell,
|
|
|
|
const GParamSpec *pspec,
|
|
|
|
GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
gimp_statusbar_replace (statusbar, "title",
|
|
|
|
NULL, "%s", shell->status);
|
2022-08-02 07:22:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_statusbar_shell_color_config_notify (GObject *config,
|
|
|
|
const GParamSpec *pspec,
|
|
|
|
GimpStatusbar *statusbar)
|
|
|
|
{
|
2022-08-08 12:05:53 +08:00
|
|
|
gboolean active = FALSE;
|
|
|
|
gint optimize = 0;
|
|
|
|
GimpColorConfig *color_config = GIMP_COLOR_CONFIG (config);
|
|
|
|
GimpColorManagementMode mode = gimp_color_config_get_mode (color_config);
|
2022-08-02 07:22:05 +08:00
|
|
|
|
|
|
|
if (mode == GIMP_COLOR_MANAGEMENT_SOFTPROOF)
|
|
|
|
{
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (statusbar->soft_proof_button),
|
|
|
|
TRUE);
|
2022-08-08 12:05:53 +08:00
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (statusbar->proof_colors_toggle),
|
|
|
|
TRUE);
|
2022-08-02 07:22:05 +08:00
|
|
|
gtk_button_set_relief (GTK_BUTTON (statusbar->soft_proof_button),
|
|
|
|
GTK_RELIEF_NORMAL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (statusbar->soft_proof_button),
|
|
|
|
FALSE);
|
2022-08-08 12:05:53 +08:00
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (statusbar->proof_colors_toggle),
|
|
|
|
FALSE);
|
2022-08-02 07:22:05 +08:00
|
|
|
gtk_button_set_relief (GTK_BUTTON (statusbar->soft_proof_button),
|
|
|
|
GTK_RELIEF_NONE);
|
|
|
|
}
|
2022-08-08 12:05:53 +08:00
|
|
|
|
|
|
|
optimize = gimp_color_config_get_simulation_optimize (color_config);
|
|
|
|
gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (statusbar->optimize_combo),
|
|
|
|
optimize);
|
|
|
|
|
|
|
|
active = gimp_color_config_get_simulation_gamut_check (color_config);
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (statusbar->out_of_gamut_toggle),
|
|
|
|
active);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_statusbar_shell_set_image (GimpStatusbar *statusbar,
|
|
|
|
GimpImage *image)
|
|
|
|
{
|
|
|
|
g_return_if_fail (image == NULL || GIMP_IS_IMAGE (image));
|
|
|
|
|
|
|
|
if (image != statusbar->image)
|
|
|
|
{
|
|
|
|
if (statusbar->image)
|
|
|
|
{
|
|
|
|
g_signal_handlers_disconnect_by_func (statusbar->image,
|
|
|
|
gimp_statusbar_shell_image_simulation_changed,
|
|
|
|
statusbar);
|
|
|
|
g_object_unref (statusbar->image);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
statusbar->image = image;
|
|
|
|
|
|
|
|
if (statusbar->image)
|
|
|
|
{
|
|
|
|
g_object_ref (statusbar->image);
|
|
|
|
|
|
|
|
g_signal_connect (statusbar->image, "simulation-profile-changed",
|
|
|
|
G_CALLBACK (gimp_statusbar_shell_image_simulation_changed),
|
|
|
|
statusbar);
|
|
|
|
g_signal_connect (statusbar->image, "simulation-intent-changed",
|
|
|
|
G_CALLBACK (gimp_statusbar_shell_image_simulation_changed),
|
|
|
|
statusbar);
|
|
|
|
g_signal_connect (statusbar->image, "simulation-bpc-changed",
|
|
|
|
G_CALLBACK (gimp_statusbar_shell_image_simulation_changed),
|
|
|
|
statusbar);
|
|
|
|
|
|
|
|
gimp_statusbar_shell_image_simulation_changed (statusbar->image,
|
|
|
|
statusbar);
|
|
|
|
}
|
2009-10-04 21:31:38 +08:00
|
|
|
}
|
|
|
|
|
2004-05-08 06:16:15 +08:00
|
|
|
static void
|
2004-05-10 18:33:21 +08:00
|
|
|
gimp_statusbar_unit_changed (GimpUnitComboBox *combo,
|
|
|
|
GimpStatusbar *statusbar)
|
2004-05-08 06:16:15 +08:00
|
|
|
{
|
2004-06-02 06:04:20 +08:00
|
|
|
gimp_display_shell_set_unit (statusbar->shell,
|
|
|
|
gimp_unit_combo_box_get_active (combo));
|
2004-05-08 06:16:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-05-10 18:33:21 +08:00
|
|
|
gimp_statusbar_scale_changed (GimpScaleComboBox *combo,
|
|
|
|
GimpStatusbar *statusbar)
|
2004-05-08 06:16:15 +08:00
|
|
|
{
|
2004-05-10 18:33:21 +08:00
|
|
|
gimp_display_shell_scale (statusbar->shell,
|
|
|
|
GIMP_ZOOM_TO,
|
2008-10-02 22:53:35 +08:00
|
|
|
gimp_scale_combo_box_get_scale (combo),
|
|
|
|
GIMP_ZOOM_FOCUS_BEST_GUESS);
|
2004-05-08 06:16:15 +08:00
|
|
|
}
|
2004-06-19 21:31:58 +08:00
|
|
|
|
2009-09-24 15:35:34 +08:00
|
|
|
static void
|
|
|
|
gimp_statusbar_scale_activated (GimpScaleComboBox *combo,
|
|
|
|
GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
gtk_widget_grab_focus (statusbar->shell->canvas);
|
|
|
|
}
|
|
|
|
|
2022-08-02 07:22:05 +08:00
|
|
|
static void
|
2022-08-08 12:05:53 +08:00
|
|
|
gimp_statusbar_shell_image_changed (GimpStatusbar *statusbar,
|
|
|
|
GimpImage *image,
|
|
|
|
GimpContext *context)
|
2022-08-02 07:22:05 +08:00
|
|
|
{
|
2022-08-08 12:05:53 +08:00
|
|
|
GimpColorConfig *color_config = NULL;
|
2022-08-02 07:22:05 +08:00
|
|
|
|
2022-08-08 12:05:53 +08:00
|
|
|
if (image == statusbar->image)
|
|
|
|
return;
|
2022-08-02 07:22:05 +08:00
|
|
|
|
2022-08-08 12:05:53 +08:00
|
|
|
if (statusbar->shell && statusbar->shell->display)
|
|
|
|
color_config = gimp_display_shell_get_color_config (statusbar->shell);
|
2022-08-02 07:22:05 +08:00
|
|
|
|
2022-08-08 12:05:53 +08:00
|
|
|
gimp_statusbar_shell_set_image (statusbar, image);
|
2022-08-02 07:22:05 +08:00
|
|
|
|
2022-08-08 12:05:53 +08:00
|
|
|
gimp_statusbar_shell_color_config_notify (G_OBJECT (color_config), NULL,
|
|
|
|
statusbar);
|
2022-08-02 07:22:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2022-08-08 12:05:53 +08:00
|
|
|
gimp_statusbar_shell_image_simulation_changed (GimpImage *image,
|
|
|
|
GimpStatusbar *statusbar)
|
2022-08-02 07:22:05 +08:00
|
|
|
{
|
2022-08-08 12:05:53 +08:00
|
|
|
GimpColorProfile *simulation_profile = NULL;
|
|
|
|
gchar *text;
|
|
|
|
const gchar *profile_label;
|
|
|
|
GimpColorRenderingIntent intent =
|
|
|
|
GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC;
|
|
|
|
gboolean bpc = FALSE;
|
2022-08-02 07:22:05 +08:00
|
|
|
|
|
|
|
if (image)
|
2022-08-08 12:05:53 +08:00
|
|
|
{
|
|
|
|
simulation_profile = gimp_image_get_simulation_profile (image);
|
|
|
|
intent = gimp_image_get_simulation_intent (image);
|
|
|
|
bpc = gimp_image_get_simulation_bpc (image);
|
|
|
|
}
|
2022-08-02 07:22:05 +08:00
|
|
|
|
2022-08-08 12:05:53 +08:00
|
|
|
if (simulation_profile && GIMP_IS_COLOR_PROFILE (simulation_profile))
|
|
|
|
{
|
|
|
|
profile_label = gimp_color_profile_get_label (simulation_profile);
|
|
|
|
gtk_widget_set_sensitive (statusbar->soft_proof_button, TRUE);
|
|
|
|
gtk_widget_set_sensitive (statusbar->proof_colors_toggle, TRUE);
|
|
|
|
}
|
2022-08-02 07:22:05 +08:00
|
|
|
else
|
2022-08-08 12:05:53 +08:00
|
|
|
{
|
|
|
|
profile_label = _("None");
|
|
|
|
gtk_widget_set_sensitive (statusbar->soft_proof_button, FALSE);
|
|
|
|
gtk_widget_set_sensitive (statusbar->proof_colors_toggle, FALSE);
|
|
|
|
}
|
2023-12-16 21:12:31 +08:00
|
|
|
gtk_event_box_set_above_child (GTK_EVENT_BOX (statusbar->soft_proof_container), TRUE);
|
2022-08-08 12:05:53 +08:00
|
|
|
|
|
|
|
text = g_strdup_printf ("<b>%s</b>: %s",
|
|
|
|
_("Current Soft-Proofing Profile"),
|
|
|
|
profile_label);
|
|
|
|
gtk_label_set_markup (GTK_LABEL (statusbar->profile_label), text);
|
|
|
|
g_free (text);
|
|
|
|
|
|
|
|
gimp_color_profile_combo_box_set_active_profile (GIMP_COLOR_PROFILE_COMBO_BOX (statusbar->profile_combo),
|
|
|
|
simulation_profile);
|
|
|
|
gtk_combo_box_set_active (GTK_COMBO_BOX (statusbar->rendering_intent_combo),
|
|
|
|
intent);
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (statusbar->bpc_toggle),
|
|
|
|
bpc);
|
2022-08-02 07:22:05 +08:00
|
|
|
}
|
|
|
|
|
2017-11-15 10:37:20 +08:00
|
|
|
static gboolean
|
2017-11-16 02:56:33 +08:00
|
|
|
gimp_statusbar_rotate_pressed (GtkWidget *event_box,
|
|
|
|
GdkEvent *event,
|
|
|
|
GimpStatusbar *statusbar)
|
2017-11-15 10:37:20 +08:00
|
|
|
{
|
2023-01-31 21:17:00 +08:00
|
|
|
GAction *action;
|
|
|
|
|
|
|
|
action = g_action_map_lookup_action (G_ACTION_MAP (statusbar->gimp->app),
|
|
|
|
"view-rotate-other");
|
|
|
|
gimp_action_activate (GIMP_ACTION (action));
|
2017-11-15 10:37:20 +08:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2017-11-16 02:56:33 +08:00
|
|
|
static gboolean
|
|
|
|
gimp_statusbar_horiz_flip_pressed (GtkWidget *event_box,
|
|
|
|
GdkEvent *event,
|
|
|
|
GimpStatusbar *statusbar)
|
|
|
|
{
|
2023-01-31 21:17:00 +08:00
|
|
|
GAction *action;
|
2017-11-16 02:56:33 +08:00
|
|
|
|
2023-01-31 21:17:00 +08:00
|
|
|
action = g_action_map_lookup_action (G_ACTION_MAP (statusbar->gimp->app),
|
|
|
|
"view-flip-horizontally");
|
|
|
|
gimp_action_activate (GIMP_ACTION (action));
|
2017-11-16 02:56:33 +08:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_statusbar_vert_flip_pressed (GtkWidget *event_box,
|
|
|
|
GdkEvent *event,
|
|
|
|
GimpStatusbar *statusbar)
|
|
|
|
{
|
2023-01-31 21:17:00 +08:00
|
|
|
GAction *action;
|
2017-11-16 02:56:33 +08:00
|
|
|
|
2023-01-31 21:17:00 +08:00
|
|
|
action = g_action_map_lookup_action (G_ACTION_MAP (statusbar->gimp->app),
|
|
|
|
"view-flip-vertically");
|
|
|
|
gimp_action_activate (GIMP_ACTION (action));
|
2017-11-16 02:56:33 +08:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2004-07-15 00:37:13 +08:00
|
|
|
static guint
|
2004-06-19 21:31:58 +08:00
|
|
|
gimp_statusbar_get_context_id (GimpStatusbar *statusbar,
|
2004-07-15 00:37:13 +08:00
|
|
|
const gchar *context)
|
2004-06-19 21:31:58 +08:00
|
|
|
{
|
2006-09-01 20:15:14 +08:00
|
|
|
guint id = GPOINTER_TO_UINT (g_hash_table_lookup (statusbar->context_ids,
|
|
|
|
context));
|
2006-09-01 19:33:39 +08:00
|
|
|
|
|
|
|
if (! id)
|
2004-06-19 21:31:58 +08:00
|
|
|
{
|
2006-09-01 20:15:14 +08:00
|
|
|
id = statusbar->seq_context_id++;
|
|
|
|
|
|
|
|
g_hash_table_insert (statusbar->context_ids,
|
|
|
|
g_strdup (context), GUINT_TO_POINTER (id));
|
2004-06-19 21:31:58 +08:00
|
|
|
}
|
|
|
|
|
2006-09-01 20:15:14 +08:00
|
|
|
return id;
|
2004-06-19 21:31:58 +08:00
|
|
|
}
|
2006-09-23 00:44:47 +08:00
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_statusbar_temp_timeout (GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
gimp_statusbar_pop_temp (statusbar);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
2006-10-09 16:17:22 +08:00
|
|
|
|
2020-06-18 18:05:47 +08:00
|
|
|
static void
|
|
|
|
gimp_statusbar_add_size_widget (GimpStatusbar *statusbar,
|
|
|
|
GtkWidget *widget)
|
|
|
|
{
|
|
|
|
statusbar->size_widgets = g_slist_prepend (statusbar->size_widgets, widget);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_statusbar_update_size (GimpStatusbar *statusbar)
|
|
|
|
{
|
|
|
|
GSList *iter;
|
|
|
|
gint height = -1;
|
|
|
|
|
|
|
|
for (iter = statusbar->size_widgets; iter; iter = g_slist_next (iter))
|
|
|
|
{
|
|
|
|
GtkWidget *widget = iter->data;
|
|
|
|
gint natural_height;
|
|
|
|
gboolean visible;
|
|
|
|
|
|
|
|
visible = gtk_widget_get_visible (widget);
|
|
|
|
gtk_widget_set_visible (widget, TRUE);
|
|
|
|
|
|
|
|
gtk_widget_get_preferred_height (widget, NULL, &natural_height);
|
|
|
|
|
|
|
|
gtk_widget_set_visible (widget, visible);
|
|
|
|
|
|
|
|
height = MAX (height, natural_height);
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_widget_set_size_request (GTK_WIDGET (statusbar), -1, height);
|
|
|
|
}
|
|
|
|
|
2016-04-20 16:25:14 +08:00
|
|
|
static void
|
|
|
|
gimp_statusbar_add_message (GimpStatusbar *statusbar,
|
|
|
|
guint context_id,
|
|
|
|
const gchar *icon_name,
|
|
|
|
const gchar *format,
|
|
|
|
va_list args,
|
|
|
|
gboolean move_to_front)
|
|
|
|
{
|
|
|
|
gchar *message;
|
|
|
|
GSList *list;
|
|
|
|
GimpStatusbarMsg *msg;
|
|
|
|
gint position;
|
|
|
|
|
|
|
|
message = gimp_statusbar_vprintf (format, args);
|
|
|
|
|
|
|
|
for (list = statusbar->messages; list; list = g_slist_next (list))
|
|
|
|
{
|
|
|
|
msg = list->data;
|
|
|
|
|
|
|
|
if (msg->context_id == context_id)
|
|
|
|
{
|
|
|
|
gboolean is_front_message = (list == statusbar->messages);
|
|
|
|
|
|
|
|
if ((is_front_message || ! move_to_front) &&
|
2016-04-20 16:37:36 +08:00
|
|
|
strcmp (msg->text, message) == 0 &&
|
|
|
|
g_strcmp0 (msg->icon_name, icon_name) == 0)
|
2016-04-20 16:25:14 +08:00
|
|
|
{
|
|
|
|
g_free (message);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (move_to_front)
|
|
|
|
{
|
|
|
|
statusbar->messages = g_slist_remove (statusbar->messages, msg);
|
|
|
|
gimp_statusbar_msg_free (msg);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_free (msg->icon_name);
|
|
|
|
msg->icon_name = g_strdup (icon_name);
|
|
|
|
|
|
|
|
g_free (msg->text);
|
|
|
|
msg->text = message;
|
|
|
|
|
|
|
|
if (is_front_message)
|
|
|
|
gimp_statusbar_update (statusbar);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
msg = g_slice_new (GimpStatusbarMsg);
|
|
|
|
|
|
|
|
msg->context_id = context_id;
|
|
|
|
msg->icon_name = g_strdup (icon_name);
|
|
|
|
msg->text = message;
|
|
|
|
|
|
|
|
/* find the position at which to insert the new message */
|
|
|
|
position = 0;
|
2016-04-20 16:48:17 +08:00
|
|
|
/* progress messages are always at the front of the list */
|
|
|
|
if (! (statusbar->progress_active &&
|
|
|
|
context_id == gimp_statusbar_get_context_id (statusbar, "progress")))
|
|
|
|
{
|
|
|
|
if (statusbar->progress_active)
|
|
|
|
position++;
|
|
|
|
|
|
|
|
/* temporary messages are in front of all other non-progress messages */
|
|
|
|
if (statusbar->temp_timeout_id &&
|
|
|
|
context_id != statusbar->temp_context_id)
|
|
|
|
position++;
|
|
|
|
}
|
2016-04-20 16:25:14 +08:00
|
|
|
|
|
|
|
statusbar->messages = g_slist_insert (statusbar->messages, msg, position);
|
|
|
|
|
|
|
|
if (position == 0)
|
|
|
|
gimp_statusbar_update (statusbar);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_statusbar_remove_message (GimpStatusbar *statusbar,
|
|
|
|
guint context_id)
|
|
|
|
{
|
|
|
|
GSList *list;
|
|
|
|
gboolean needs_update = FALSE;
|
|
|
|
|
|
|
|
for (list = statusbar->messages; list; list = g_slist_next (list))
|
|
|
|
{
|
|
|
|
GimpStatusbarMsg *msg = list->data;
|
|
|
|
|
|
|
|
if (msg->context_id == context_id)
|
|
|
|
{
|
|
|
|
needs_update = (list == statusbar->messages);
|
|
|
|
|
|
|
|
statusbar->messages = g_slist_remove (statusbar->messages, msg);
|
|
|
|
gimp_statusbar_msg_free (msg);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (needs_update)
|
|
|
|
gimp_statusbar_update (statusbar);
|
|
|
|
}
|
|
|
|
|
2006-10-09 16:17:22 +08:00
|
|
|
static void
|
|
|
|
gimp_statusbar_msg_free (GimpStatusbarMsg *msg)
|
|
|
|
{
|
2014-05-07 21:30:38 +08:00
|
|
|
g_free (msg->icon_name);
|
2006-10-09 16:17:22 +08:00
|
|
|
g_free (msg->text);
|
2007-05-23 17:04:20 +08:00
|
|
|
|
|
|
|
g_slice_free (GimpStatusbarMsg, msg);
|
2006-10-09 16:17:22 +08:00
|
|
|
}
|
2007-02-14 21:13:40 +08:00
|
|
|
|
|
|
|
static gchar *
|
|
|
|
gimp_statusbar_vprintf (const gchar *format,
|
|
|
|
va_list args)
|
|
|
|
{
|
|
|
|
gchar *message;
|
|
|
|
gchar *newline;
|
|
|
|
|
|
|
|
message = g_strdup_vprintf (format, args);
|
|
|
|
|
|
|
|
/* guard us from multi-line strings */
|
2007-11-09 02:20:30 +08:00
|
|
|
newline = strchr (message, '\r');
|
|
|
|
if (newline)
|
|
|
|
*newline = '\0';
|
|
|
|
|
2007-02-14 21:13:40 +08:00
|
|
|
newline = strchr (message, '\n');
|
|
|
|
if (newline)
|
|
|
|
*newline = '\0';
|
|
|
|
|
|
|
|
return message;
|
|
|
|
}
|
2014-05-31 01:38:17 +08:00
|
|
|
|
|
|
|
static GdkPixbuf *
|
|
|
|
gimp_statusbar_load_icon (GimpStatusbar *statusbar,
|
|
|
|
const gchar *icon_name)
|
|
|
|
{
|
|
|
|
GdkPixbuf *icon;
|
|
|
|
|
|
|
|
if (G_UNLIKELY (! statusbar->icon_hash))
|
|
|
|
{
|
|
|
|
statusbar->icon_hash =
|
|
|
|
g_hash_table_new_full (g_str_hash,
|
|
|
|
g_str_equal,
|
|
|
|
(GDestroyNotify) g_free,
|
|
|
|
(GDestroyNotify) g_object_unref);
|
|
|
|
}
|
|
|
|
|
|
|
|
icon = g_hash_table_lookup (statusbar->icon_hash, icon_name);
|
|
|
|
|
|
|
|
if (icon)
|
|
|
|
return g_object_ref (icon);
|
|
|
|
|
|
|
|
icon = gimp_widget_load_icon (statusbar->label, icon_name, 16);
|
|
|
|
|
|
|
|
/* this is not optimal but so what */
|
|
|
|
if (g_hash_table_size (statusbar->icon_hash) > 16)
|
|
|
|
g_hash_table_remove_all (statusbar->icon_hash);
|
|
|
|
|
|
|
|
g_hash_table_insert (statusbar->icon_hash,
|
|
|
|
g_strdup (icon_name), g_object_ref (icon));
|
|
|
|
|
|
|
|
return icon;
|
|
|
|
}
|
macos: Fix 7690 (slow drawing)
Gets drawing in the canvas speed on retina displays up to the speed
of FullHD displays on macOS, making 2.99 usable on macOS.
Generic change:
Changes the cursor_label to delay the drawing phase to the idle
queue, from immediate draw on all platforms.
Before the fix in 32049afd (using a deprecated function in Gtk3)
any draws on this label forced a full canvas redraw. This is due
to a quirk in how GtkLabel functions.
The redraw occurred because GtkLabels resize themselves and everything
around them by sending a resize message any time they receive new
text. These resizes then trigger the full canvas resize which triggers
a full canvas redraw that cannot be optimized by either Gtk or Big Sur.
MacOS changes:
Only redraws the cursor position label and each of the horizontal and
vertical rules (cursor tracking widgets) 3 times a second max for a
total of 9 redraws a second (ideally out of 60, though I don't believe
under any circumstances that GIMP achieves a 60fps).
Each of the cursor tracking widgets gets its own timeslice, and so
will not redraw when the other cursor tracking widgets are drawing.
This is required because Big Sur is merging all draw rects into
one large rect, dramatically slowing down draws.
This timeslicing ensures that draw rects are maintained at the smallest
possible size. So the typical redraw is a small rect around the
brush. However, 9 times a second, the rect will include one of the
3 cursor tracking widgets (rulers and cursor label).
Additionally, the code tries to minimize resizing the width of the
cursor label by checking if the widget is too small for the text,
then setting the char_width to a greater size so that resizes won't
be that common.
This improves the appearance of the widget as it no longer
constantly jumps about in size on each cursor move.
Here is a discussion of the issue:
https://gitlab.gnome.org/GNOME/gimp/-/merge_requests/572#note_1389445
Reviewer's (Jehan) notes:
* The whole issue about GtkLabel resizing is no more after 32049afd. It
is normal for a widget to request a resize when needed. We just don't
want the statusbar to resize and triggering canvas redraws.
* Changing cursor position text into an idle function generally makes
sense.
Also it reverts commit 6de9ea70223 which had a bug I hadn't realized
when I accepted it: when we test for time, we don't know yet if it
will be the last position change, hence we could "refuse" the last
update. Therefore displayed cursor position would end up outdated
on macOS. This new implementation doesn't have the problem (the last
idle update always happens after the last move).
* The change about giving 1/3 timeslices to side canvas components
(rulers and statusbar) is a complete hack to work around the fact that
macOs doesn't report properly each damaged rectangle. Instead it
returns a huge bounding box. The workaround here is to expose these
area separately.
We have not been able to find a proper solution yet. This is the only
reason why I accept this code, for macOS only, to at least have
something usable there.
See discussions in MRs gimp!572 and gimp-macos-build!86. With these 2
MRs, Lukas reported GIMP 2.99 to perform even better than GIMP 2.10 on
Monterey, though it could not be tested on Big Sur unfortunately.
* Lastly the set_width_chars() thing is also an ugly hack which I will
try later to revisit (see !581). I only accepted it (with mandatory
macOS-only macro) to have an acceptable state for release after seeing
a screencast where the label size indeed "jumps around" on macOS.
2022-02-19 09:25:51 +08:00
|
|
|
|
2022-03-09 18:49:24 +08:00
|
|
|
static gboolean
|
|
|
|
gimp_statusbar_queue_pos_redraw (gpointer data)
|
macos: Fix 7690 (slow drawing)
Gets drawing in the canvas speed on retina displays up to the speed
of FullHD displays on macOS, making 2.99 usable on macOS.
Generic change:
Changes the cursor_label to delay the drawing phase to the idle
queue, from immediate draw on all platforms.
Before the fix in 32049afd (using a deprecated function in Gtk3)
any draws on this label forced a full canvas redraw. This is due
to a quirk in how GtkLabel functions.
The redraw occurred because GtkLabels resize themselves and everything
around them by sending a resize message any time they receive new
text. These resizes then trigger the full canvas resize which triggers
a full canvas redraw that cannot be optimized by either Gtk or Big Sur.
MacOS changes:
Only redraws the cursor position label and each of the horizontal and
vertical rules (cursor tracking widgets) 3 times a second max for a
total of 9 redraws a second (ideally out of 60, though I don't believe
under any circumstances that GIMP achieves a 60fps).
Each of the cursor tracking widgets gets its own timeslice, and so
will not redraw when the other cursor tracking widgets are drawing.
This is required because Big Sur is merging all draw rects into
one large rect, dramatically slowing down draws.
This timeslicing ensures that draw rects are maintained at the smallest
possible size. So the typical redraw is a small rect around the
brush. However, 9 times a second, the rect will include one of the
3 cursor tracking widgets (rulers and cursor label).
Additionally, the code tries to minimize resizing the width of the
cursor label by checking if the widget is too small for the text,
then setting the char_width to a greater size so that resizes won't
be that common.
This improves the appearance of the widget as it no longer
constantly jumps about in size on each cursor move.
Here is a discussion of the issue:
https://gitlab.gnome.org/GNOME/gimp/-/merge_requests/572#note_1389445
Reviewer's (Jehan) notes:
* The whole issue about GtkLabel resizing is no more after 32049afd. It
is normal for a widget to request a resize when needed. We just don't
want the statusbar to resize and triggering canvas redraws.
* Changing cursor position text into an idle function generally makes
sense.
Also it reverts commit 6de9ea70223 which had a bug I hadn't realized
when I accepted it: when we test for time, we don't know yet if it
will be the last position change, hence we could "refuse" the last
update. Therefore displayed cursor position would end up outdated
on macOS. This new implementation doesn't have the problem (the last
idle update always happens after the last move).
* The change about giving 1/3 timeslices to side canvas components
(rulers and statusbar) is a complete hack to work around the fact that
macOs doesn't report properly each damaged rectangle. Instead it
returns a huge bounding box. The workaround here is to expose these
area separately.
We have not been able to find a proper solution yet. This is the only
reason why I accept this code, for macOS only, to at least have
something usable there.
See discussions in MRs gimp!572 and gimp-macos-build!86. With these 2
MRs, Lukas reported GIMP 2.99 to perform even better than GIMP 2.10 on
Monterey, though it could not be tested on Big Sur unfortunately.
* Lastly the set_width_chars() thing is also an ugly hack which I will
try later to revisit (see !581). I only accepted it (with mandatory
macOS-only macro) to have an acceptable state for release after seeing
a screencast where the label size indeed "jumps around" on macOS.
2022-02-19 09:25:51 +08:00
|
|
|
{
|
2022-02-19 03:22:20 +08:00
|
|
|
GimpStatusbar *statusbar = GIMP_STATUSBAR (data);
|
|
|
|
GimpDisplayShell *shell;
|
|
|
|
GimpImage *image;
|
|
|
|
gint image_width = 0;
|
|
|
|
gint image_height = 0;
|
|
|
|
gint label_width_chars = 2;
|
|
|
|
|
|
|
|
shell = statusbar->shell;
|
|
|
|
image = gimp_display_get_image (shell->display);
|
|
|
|
|
2022-03-09 20:16:01 +08:00
|
|
|
if (image)
|
|
|
|
{
|
|
|
|
image_width = gimp_image_get_width (image);
|
|
|
|
image_height = gimp_image_get_height (image);
|
|
|
|
|
|
|
|
/* The number of chars within up to 2 times the image bounds is:
|
|
|
|
* - max width chars: floor (log10 (2 * max_width)) + 1
|
|
|
|
* - max height chars: floor (log10 (2 * max_height)) + 1
|
|
|
|
* - the comma and a space: + 2
|
|
|
|
* - optional 2 minus characters when going in negative
|
|
|
|
* dimensions: + 2
|
|
|
|
* - optional decimal separators and digits when showing
|
|
|
|
* fractional values.
|
|
|
|
*
|
|
|
|
* The goal of this is to avoid the label size jumping up and
|
|
|
|
* down. Actually it was not a problem on Linux, but this was
|
|
|
|
* reported on macOS.
|
|
|
|
* See: https://gitlab.gnome.org/GNOME/gimp/-/merge_requests/572#note_1389445
|
|
|
|
* So we just compute what looks like a reasonable "biggest size"
|
|
|
|
* in worst cases.
|
|
|
|
* Of course, it could still happen for people going way
|
|
|
|
* off-canvas but that's acceptable edge-case.
|
|
|
|
*/
|
|
|
|
if (shell->unit == GIMP_UNIT_PIXEL)
|
|
|
|
{
|
|
|
|
label_width_chars = floor (log10 (2 * image_width)) + floor (log10 (2 * image_height)) + 6;
|
|
|
|
|
|
|
|
if (statusbar->cursor_precision == GIMP_CURSOR_PRECISION_SUBPIXEL)
|
|
|
|
/* In subpixel precision, we have a 1 digit precision per
|
|
|
|
* dimension, so 4 additional characters, decimal
|
|
|
|
* separators-included.
|
|
|
|
*/
|
|
|
|
label_width_chars += 4;
|
|
|
|
}
|
|
|
|
else /* showing real world units */
|
|
|
|
{
|
|
|
|
GtkTreeModel *model;
|
|
|
|
GimpUnitStore *store;
|
|
|
|
gdouble max_x = (gdouble) image_width;
|
|
|
|
gdouble max_y = (gdouble) image_height;
|
|
|
|
|
|
|
|
model = gtk_combo_box_get_model (GTK_COMBO_BOX (statusbar->unit_combo));
|
|
|
|
store = GIMP_UNIT_STORE (model);
|
|
|
|
|
|
|
|
gimp_unit_store_set_pixel_values (store, max_x, max_y);
|
|
|
|
gimp_unit_store_get_values (store, shell->unit, &max_x, &max_y);
|
|
|
|
|
|
|
|
label_width_chars = /* max width (int) up to 2 times image bounds - 1 */
|
|
|
|
floor (log10 (2 * max_x)) +
|
|
|
|
/* max height (int) up to 2 times image bounds - 1 */
|
|
|
|
floor (log10 (2 * max_y)) +
|
|
|
|
/* + 2 + comma + space + 2 minuses */
|
|
|
|
6 +
|
|
|
|
/* 2 (optional) decimal separators + digits. */
|
|
|
|
(statusbar->cursor_w_digits > 0 ? 1 + statusbar->cursor_w_digits : 0) +
|
|
|
|
(statusbar->cursor_h_digits > 0 ? 1 + statusbar->cursor_h_digits : 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
macos: Fix 7690 (slow drawing)
Gets drawing in the canvas speed on retina displays up to the speed
of FullHD displays on macOS, making 2.99 usable on macOS.
Generic change:
Changes the cursor_label to delay the drawing phase to the idle
queue, from immediate draw on all platforms.
Before the fix in 32049afd (using a deprecated function in Gtk3)
any draws on this label forced a full canvas redraw. This is due
to a quirk in how GtkLabel functions.
The redraw occurred because GtkLabels resize themselves and everything
around them by sending a resize message any time they receive new
text. These resizes then trigger the full canvas resize which triggers
a full canvas redraw that cannot be optimized by either Gtk or Big Sur.
MacOS changes:
Only redraws the cursor position label and each of the horizontal and
vertical rules (cursor tracking widgets) 3 times a second max for a
total of 9 redraws a second (ideally out of 60, though I don't believe
under any circumstances that GIMP achieves a 60fps).
Each of the cursor tracking widgets gets its own timeslice, and so
will not redraw when the other cursor tracking widgets are drawing.
This is required because Big Sur is merging all draw rects into
one large rect, dramatically slowing down draws.
This timeslicing ensures that draw rects are maintained at the smallest
possible size. So the typical redraw is a small rect around the
brush. However, 9 times a second, the rect will include one of the
3 cursor tracking widgets (rulers and cursor label).
Additionally, the code tries to minimize resizing the width of the
cursor label by checking if the widget is too small for the text,
then setting the char_width to a greater size so that resizes won't
be that common.
This improves the appearance of the widget as it no longer
constantly jumps about in size on each cursor move.
Here is a discussion of the issue:
https://gitlab.gnome.org/GNOME/gimp/-/merge_requests/572#note_1389445
Reviewer's (Jehan) notes:
* The whole issue about GtkLabel resizing is no more after 32049afd. It
is normal for a widget to request a resize when needed. We just don't
want the statusbar to resize and triggering canvas redraws.
* Changing cursor position text into an idle function generally makes
sense.
Also it reverts commit 6de9ea70223 which had a bug I hadn't realized
when I accepted it: when we test for time, we don't know yet if it
will be the last position change, hence we could "refuse" the last
update. Therefore displayed cursor position would end up outdated
on macOS. This new implementation doesn't have the problem (the last
idle update always happens after the last move).
* The change about giving 1/3 timeslices to side canvas components
(rulers and statusbar) is a complete hack to work around the fact that
macOs doesn't report properly each damaged rectangle. Instead it
returns a huge bounding box. The workaround here is to expose these
area separately.
We have not been able to find a proper solution yet. This is the only
reason why I accept this code, for macOS only, to at least have
something usable there.
See discussions in MRs gimp!572 and gimp-macos-build!86. With these 2
MRs, Lukas reported GIMP 2.99 to perform even better than GIMP 2.10 on
Monterey, though it could not be tested on Big Sur unfortunately.
* Lastly the set_width_chars() thing is also an ugly hack which I will
try later to revisit (see !581). I only accepted it (with mandatory
macOS-only macro) to have an acceptable state for release after seeing
a screencast where the label size indeed "jumps around" on macOS.
2022-02-19 09:25:51 +08:00
|
|
|
g_free (statusbar->cursor_string_last);
|
2022-02-19 03:22:20 +08:00
|
|
|
gtk_label_set_width_chars (GTK_LABEL (statusbar->cursor_label), label_width_chars);
|
2022-03-09 18:49:24 +08:00
|
|
|
gtk_label_set_text (GTK_LABEL (statusbar->cursor_label), statusbar->cursor_string_todraw);
|
macos: Fix 7690 (slow drawing)
Gets drawing in the canvas speed on retina displays up to the speed
of FullHD displays on macOS, making 2.99 usable on macOS.
Generic change:
Changes the cursor_label to delay the drawing phase to the idle
queue, from immediate draw on all platforms.
Before the fix in 32049afd (using a deprecated function in Gtk3)
any draws on this label forced a full canvas redraw. This is due
to a quirk in how GtkLabel functions.
The redraw occurred because GtkLabels resize themselves and everything
around them by sending a resize message any time they receive new
text. These resizes then trigger the full canvas resize which triggers
a full canvas redraw that cannot be optimized by either Gtk or Big Sur.
MacOS changes:
Only redraws the cursor position label and each of the horizontal and
vertical rules (cursor tracking widgets) 3 times a second max for a
total of 9 redraws a second (ideally out of 60, though I don't believe
under any circumstances that GIMP achieves a 60fps).
Each of the cursor tracking widgets gets its own timeslice, and so
will not redraw when the other cursor tracking widgets are drawing.
This is required because Big Sur is merging all draw rects into
one large rect, dramatically slowing down draws.
This timeslicing ensures that draw rects are maintained at the smallest
possible size. So the typical redraw is a small rect around the
brush. However, 9 times a second, the rect will include one of the
3 cursor tracking widgets (rulers and cursor label).
Additionally, the code tries to minimize resizing the width of the
cursor label by checking if the widget is too small for the text,
then setting the char_width to a greater size so that resizes won't
be that common.
This improves the appearance of the widget as it no longer
constantly jumps about in size on each cursor move.
Here is a discussion of the issue:
https://gitlab.gnome.org/GNOME/gimp/-/merge_requests/572#note_1389445
Reviewer's (Jehan) notes:
* The whole issue about GtkLabel resizing is no more after 32049afd. It
is normal for a widget to request a resize when needed. We just don't
want the statusbar to resize and triggering canvas redraws.
* Changing cursor position text into an idle function generally makes
sense.
Also it reverts commit 6de9ea70223 which had a bug I hadn't realized
when I accepted it: when we test for time, we don't know yet if it
will be the last position change, hence we could "refuse" the last
update. Therefore displayed cursor position would end up outdated
on macOS. This new implementation doesn't have the problem (the last
idle update always happens after the last move).
* The change about giving 1/3 timeslices to side canvas components
(rulers and statusbar) is a complete hack to work around the fact that
macOs doesn't report properly each damaged rectangle. Instead it
returns a huge bounding box. The workaround here is to expose these
area separately.
We have not been able to find a proper solution yet. This is the only
reason why I accept this code, for macOS only, to at least have
something usable there.
See discussions in MRs gimp!572 and gimp-macos-build!86. With these 2
MRs, Lukas reported GIMP 2.99 to perform even better than GIMP 2.10 on
Monterey, though it could not be tested on Big Sur unfortunately.
* Lastly the set_width_chars() thing is also an ugly hack which I will
try later to revisit (see !581). I only accepted it (with mandatory
macOS-only macro) to have an acceptable state for release after seeing
a screencast where the label size indeed "jumps around" on macOS.
2022-02-19 09:25:51 +08:00
|
|
|
statusbar->cursor_string_last = statusbar->cursor_string_todraw;
|
|
|
|
statusbar->cursor_string_todraw = NULL;
|
|
|
|
|
|
|
|
statusbar->statusbar_pos_redraw_idle_id = 0;
|
|
|
|
|
|
|
|
return G_SOURCE_REMOVE;
|
|
|
|
}
|