776 lines
21 KiB
C
776 lines
21 KiB
C
/* PIKA - Photo and Image Kooker Application
|
|
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
|
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
|
*
|
|
* Original copyright, applying to most contents (license remains unchanged):
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <gegl.h>
|
|
#include <gtk/gtk.h>
|
|
|
|
#include "libpikawidgets/pikawidgets.h"
|
|
|
|
#include "actions-types.h"
|
|
|
|
#include "core/pika.h"
|
|
#include "core/pikacontainer.h"
|
|
#include "core/pikacontext.h"
|
|
#include "core/pikaimage.h"
|
|
#include "core/pikatooloptions.h"
|
|
#include "core/pikatoolinfo.h"
|
|
|
|
#include "widgets/pikaactionfactory.h"
|
|
#include "widgets/pikaactiongroup.h"
|
|
#include "widgets/pikacontainereditor.h"
|
|
#include "widgets/pikacontainerview.h"
|
|
#include "widgets/pikadock.h"
|
|
#include "widgets/pikadockable.h"
|
|
#include "widgets/pikadockwindow.h"
|
|
#include "widgets/pikaimageeditor.h"
|
|
#include "widgets/pikaitemtreeview.h"
|
|
|
|
#include "display/pikadisplay.h"
|
|
#include "display/pikadisplayshell.h"
|
|
#include "display/pikaimagewindow.h"
|
|
#include "display/pikanavigationeditor.h"
|
|
#include "display/pikastatusbar.h"
|
|
|
|
#include "dialogs/dialogs.h"
|
|
|
|
#include "actions.h"
|
|
#include "brush-editor-actions.h"
|
|
#include "brushes-actions.h"
|
|
#include "buffers-actions.h"
|
|
#include "channels-actions.h"
|
|
#include "colormap-actions.h"
|
|
#include "context-actions.h"
|
|
#include "cursor-info-actions.h"
|
|
#include "dashboard-actions.h"
|
|
#include "debug-actions.h"
|
|
#include "dialogs-actions.h"
|
|
#include "dock-actions.h"
|
|
#include "dockable-actions.h"
|
|
#include "documents-actions.h"
|
|
#include "drawable-actions.h"
|
|
#include "dynamics-actions.h"
|
|
#include "dynamics-editor-actions.h"
|
|
#include "edit-actions.h"
|
|
#include "error-console-actions.h"
|
|
#include "file-actions.h"
|
|
#include "filters-actions.h"
|
|
#include "fonts-actions.h"
|
|
#include "gradient-editor-actions.h"
|
|
#include "gradients-actions.h"
|
|
#include "help-actions.h"
|
|
#include "image-actions.h"
|
|
#include "images-actions.h"
|
|
#include "layers-actions.h"
|
|
#include "mypaint-brushes-actions.h"
|
|
#include "palette-editor-actions.h"
|
|
#include "palettes-actions.h"
|
|
#include "patterns-actions.h"
|
|
#include "plug-in-actions.h"
|
|
#include "quick-mask-actions.h"
|
|
#include "sample-points-actions.h"
|
|
#include "select-actions.h"
|
|
#include "templates-actions.h"
|
|
#include "text-editor-actions.h"
|
|
#include "text-tool-actions.h"
|
|
#include "tool-options-actions.h"
|
|
#include "tool-presets-actions.h"
|
|
#include "tool-preset-editor-actions.h"
|
|
#include "tools-actions.h"
|
|
#include "vector-toolpath-actions.h"
|
|
#include "vectors-actions.h"
|
|
#include "view-actions.h"
|
|
#include "windows-actions.h"
|
|
|
|
#include "pika-intl.h"
|
|
|
|
|
|
/* global variables */
|
|
|
|
PikaActionFactory *global_action_factory = NULL;
|
|
|
|
|
|
/* private variables */
|
|
|
|
static const PikaActionFactoryEntry action_groups[] =
|
|
{
|
|
{ "brush-editor", N_("Brush Editor"), PIKA_ICON_BRUSH,
|
|
brush_editor_actions_setup,
|
|
brush_editor_actions_update },
|
|
{ "brushes", N_("Brushes"), PIKA_ICON_BRUSH,
|
|
brushes_actions_setup,
|
|
brushes_actions_update },
|
|
{ "buffers", N_("Buffers"), PIKA_ICON_BUFFER,
|
|
buffers_actions_setup,
|
|
buffers_actions_update },
|
|
{ "channels", N_("Channels"), PIKA_ICON_CHANNEL,
|
|
channels_actions_setup,
|
|
channels_actions_update },
|
|
{ "colormap", N_("Colormap"), PIKA_ICON_COLORMAP,
|
|
colormap_actions_setup,
|
|
colormap_actions_update },
|
|
{ "context", N_("Context"), PIKA_ICON_DIALOG_TOOL_OPTIONS /* well... */,
|
|
context_actions_setup,
|
|
context_actions_update },
|
|
{ "cursor-info", N_("Pointer Information"), NULL,
|
|
cursor_info_actions_setup,
|
|
cursor_info_actions_update },
|
|
{ "dashboard", N_("Dashboard"), PIKA_ICON_DIALOG_DASHBOARD,
|
|
dashboard_actions_setup,
|
|
dashboard_actions_update },
|
|
{ "debug", N_("Debug"), NULL,
|
|
debug_actions_setup,
|
|
debug_actions_update },
|
|
{ "dialogs", N_("Dialogs"), NULL,
|
|
dialogs_actions_setup,
|
|
dialogs_actions_update },
|
|
{ "dock", N_("Dock"), NULL,
|
|
dock_actions_setup,
|
|
dock_actions_update },
|
|
{ "dockable", N_("Dockable"), NULL,
|
|
dockable_actions_setup,
|
|
dockable_actions_update },
|
|
{ "documents", N_("Document History"), NULL,
|
|
documents_actions_setup,
|
|
documents_actions_update },
|
|
{ "drawable", N_("Drawable"), PIKA_ICON_LAYER,
|
|
drawable_actions_setup,
|
|
drawable_actions_update },
|
|
{ "dynamics", N_("Paint Dynamics"), PIKA_ICON_DYNAMICS,
|
|
dynamics_actions_setup,
|
|
dynamics_actions_update },
|
|
{ "dynamics-editor", N_("Paint Dynamics Editor"), PIKA_ICON_DYNAMICS,
|
|
dynamics_editor_actions_setup,
|
|
dynamics_editor_actions_update },
|
|
{ "edit", N_("Edit"), PIKA_ICON_EDIT,
|
|
edit_actions_setup,
|
|
edit_actions_update },
|
|
{ "error-console", N_("Error Console"), PIKA_ICON_DIALOG_WARNING,
|
|
error_console_actions_setup,
|
|
error_console_actions_update },
|
|
{ "file", N_("File"), "text-x-generic",
|
|
file_actions_setup,
|
|
file_actions_update },
|
|
{ "filters", N_("Filters"), PIKA_ICON_GEGL,
|
|
filters_actions_setup,
|
|
filters_actions_update },
|
|
{ "fonts", N_("Fonts"), PIKA_ICON_FONT,
|
|
fonts_actions_setup,
|
|
fonts_actions_update },
|
|
{ "gradient-editor", N_("Gradient Editor"), PIKA_ICON_GRADIENT,
|
|
gradient_editor_actions_setup,
|
|
gradient_editor_actions_update },
|
|
{ "gradients", N_("Gradients"), PIKA_ICON_GRADIENT,
|
|
gradients_actions_setup,
|
|
gradients_actions_update },
|
|
{ "tool-presets", N_("Tool Presets"), PIKA_ICON_TOOL_PRESET,
|
|
tool_presets_actions_setup,
|
|
tool_presets_actions_update },
|
|
{ "tool-preset-editor", N_("Tool Preset Editor"), PIKA_ICON_TOOL_PRESET,
|
|
tool_preset_editor_actions_setup,
|
|
tool_preset_editor_actions_update },
|
|
{ "help", N_("Help"), "help-browser",
|
|
help_actions_setup,
|
|
help_actions_update },
|
|
{ "image", N_("Image"), PIKA_ICON_IMAGE,
|
|
image_actions_setup,
|
|
image_actions_update },
|
|
{ "images", N_("Images"), PIKA_ICON_IMAGE,
|
|
images_actions_setup,
|
|
images_actions_update },
|
|
{ "layers", N_("Layers"), PIKA_ICON_LAYER,
|
|
layers_actions_setup,
|
|
layers_actions_update },
|
|
{ "mypaint-brushes", N_("MyPaint Brushes"), PIKA_ICON_MYPAINT_BRUSH,
|
|
mypaint_brushes_actions_setup,
|
|
mypaint_brushes_actions_update },
|
|
{ "palette-editor", N_("Palette Editor"), PIKA_ICON_PALETTE,
|
|
palette_editor_actions_setup,
|
|
palette_editor_actions_update },
|
|
{ "palettes", N_("Palettes"), PIKA_ICON_PALETTE,
|
|
palettes_actions_setup,
|
|
palettes_actions_update },
|
|
{ "patterns", N_("Patterns"), PIKA_ICON_PATTERN,
|
|
patterns_actions_setup,
|
|
patterns_actions_update },
|
|
{ "plug-in", N_("Plug-ins"), PIKA_ICON_PLUGIN,
|
|
plug_in_actions_setup,
|
|
plug_in_actions_update },
|
|
{ "quick-mask", N_("Quick Mask"), PIKA_ICON_QUICK_MASK_ON,
|
|
quick_mask_actions_setup,
|
|
quick_mask_actions_update },
|
|
{ "sample-points", N_("Sample Points"), PIKA_ICON_SAMPLE_POINT,
|
|
sample_points_actions_setup,
|
|
sample_points_actions_update },
|
|
{ "select", N_("Select"), PIKA_ICON_SELECTION,
|
|
select_actions_setup,
|
|
select_actions_update },
|
|
{ "templates", N_("Templates"), PIKA_ICON_TEMPLATE,
|
|
templates_actions_setup,
|
|
templates_actions_update },
|
|
{ "text-tool", N_("Text Tool"), PIKA_ICON_EDIT,
|
|
text_tool_actions_setup,
|
|
text_tool_actions_update },
|
|
{ "text-editor", N_("Text Editor"), PIKA_ICON_EDIT,
|
|
text_editor_actions_setup,
|
|
text_editor_actions_update },
|
|
{ "tool-options", N_("Tool Options"), PIKA_ICON_DIALOG_TOOL_OPTIONS,
|
|
tool_options_actions_setup,
|
|
tool_options_actions_update },
|
|
{ "tools", N_("Tools"), PIKA_ICON_DIALOG_TOOLS,
|
|
tools_actions_setup,
|
|
tools_actions_update },
|
|
{ "vector-toolpath", N_("Path Toolpath"), PIKA_ICON_PATH,
|
|
vector_toolpath_actions_setup,
|
|
vector_toolpath_actions_update },
|
|
{ "vectors", N_("Paths"), PIKA_ICON_PATH,
|
|
vectors_actions_setup,
|
|
vectors_actions_update },
|
|
{ "view", N_("View"), PIKA_ICON_VISIBLE,
|
|
view_actions_setup,
|
|
view_actions_update },
|
|
{ "windows", N_("Windows"), NULL,
|
|
windows_actions_setup,
|
|
windows_actions_update }
|
|
};
|
|
|
|
|
|
/* public functions */
|
|
|
|
void
|
|
actions_init (Pika *pika)
|
|
{
|
|
gint i;
|
|
|
|
g_return_if_fail (PIKA_IS_PIKA (pika));
|
|
g_return_if_fail (global_action_factory == NULL);
|
|
|
|
global_action_factory = pika_action_factory_new (pika);
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (action_groups); i++)
|
|
pika_action_factory_group_register (global_action_factory,
|
|
action_groups[i].identifier,
|
|
gettext (action_groups[i].label),
|
|
action_groups[i].icon_name,
|
|
action_groups[i].setup_func,
|
|
action_groups[i].update_func);
|
|
}
|
|
|
|
void
|
|
actions_exit (Pika *pika)
|
|
{
|
|
g_return_if_fail (PIKA_IS_PIKA (pika));
|
|
g_return_if_fail (global_action_factory != NULL);
|
|
g_return_if_fail (global_action_factory->pika == pika);
|
|
|
|
g_clear_object (&global_action_factory);
|
|
}
|
|
|
|
Pika *
|
|
action_data_get_pika (gpointer data)
|
|
{
|
|
Pika *result = NULL;
|
|
static gboolean recursion = FALSE;
|
|
|
|
if (! data || recursion)
|
|
return NULL;
|
|
|
|
recursion = TRUE;
|
|
|
|
if (PIKA_IS_PIKA (data))
|
|
result = data;
|
|
|
|
if (! result)
|
|
{
|
|
PikaDisplay *display = action_data_get_display (data);
|
|
|
|
if (display)
|
|
result = display->pika;
|
|
}
|
|
|
|
if (! result)
|
|
{
|
|
PikaContext *context = action_data_get_context (data);
|
|
|
|
if (context)
|
|
result = context->pika;
|
|
}
|
|
|
|
recursion = FALSE;
|
|
|
|
return result;
|
|
}
|
|
|
|
PikaContext *
|
|
action_data_get_context (gpointer data)
|
|
{
|
|
PikaContext *result = NULL;
|
|
static gboolean recursion = FALSE;
|
|
|
|
if (! data || recursion)
|
|
return NULL;
|
|
|
|
recursion = TRUE;
|
|
|
|
if (PIKA_IS_DOCK (data))
|
|
result = pika_dock_get_context ((PikaDock *) data);
|
|
else if (PIKA_IS_DOCK_WINDOW (data))
|
|
result = pika_dock_window_get_context (((PikaDockWindow *) data));
|
|
else if (PIKA_IS_CONTAINER_VIEW (data))
|
|
result = pika_container_view_get_context ((PikaContainerView *) data);
|
|
else if (PIKA_IS_CONTAINER_EDITOR (data))
|
|
result = pika_container_view_get_context (((PikaContainerEditor *) data)->view);
|
|
else if (PIKA_IS_IMAGE_EDITOR (data))
|
|
result = ((PikaImageEditor *) data)->context;
|
|
else if (PIKA_IS_NAVIGATION_EDITOR (data))
|
|
result = ((PikaNavigationEditor *) data)->context;
|
|
|
|
if (! result)
|
|
{
|
|
Pika *pika = action_data_get_pika (data);
|
|
|
|
if (pika)
|
|
result = pika_get_user_context (pika);
|
|
}
|
|
|
|
recursion = FALSE;
|
|
|
|
return result;
|
|
}
|
|
|
|
PikaImage *
|
|
action_data_get_image (gpointer data)
|
|
{
|
|
PikaImage *result = NULL;
|
|
static gboolean recursion = FALSE;
|
|
|
|
if (! data || recursion)
|
|
return NULL;
|
|
|
|
recursion = TRUE;
|
|
|
|
if (PIKA_IS_ITEM_TREE_VIEW (data))
|
|
{
|
|
result = pika_item_tree_view_get_image ((PikaItemTreeView *) data);
|
|
recursion = FALSE;
|
|
return result;
|
|
}
|
|
else if (PIKA_IS_IMAGE_EDITOR (data))
|
|
{
|
|
result = ((PikaImageEditor *) data)->image;
|
|
recursion = FALSE;
|
|
return result;
|
|
}
|
|
|
|
if (! result)
|
|
{
|
|
PikaDisplay *display = action_data_get_display (data);
|
|
|
|
if (display)
|
|
result = pika_display_get_image (display);
|
|
}
|
|
|
|
if (! result)
|
|
{
|
|
PikaContext *context = action_data_get_context (data);
|
|
|
|
if (context)
|
|
result = pika_context_get_image (context);
|
|
}
|
|
|
|
recursion = FALSE;
|
|
|
|
return result;
|
|
}
|
|
|
|
PikaDisplay *
|
|
action_data_get_display (gpointer data)
|
|
{
|
|
PikaDisplay *result = NULL;
|
|
static gboolean recursion = FALSE;
|
|
|
|
if (! data || recursion)
|
|
return NULL;
|
|
|
|
recursion = TRUE;
|
|
|
|
if (PIKA_IS_DISPLAY (data))
|
|
result = data;
|
|
else if (PIKA_IS_IMAGE_WINDOW (data))
|
|
{
|
|
PikaDisplayShell *shell = pika_image_window_get_active_shell (data);
|
|
result = shell ? shell->display : NULL;
|
|
}
|
|
|
|
if (! result)
|
|
{
|
|
PikaContext *context = action_data_get_context (data);
|
|
|
|
if (context)
|
|
result = pika_context_get_display (context);
|
|
}
|
|
|
|
recursion = FALSE;
|
|
|
|
return result;
|
|
}
|
|
|
|
PikaDisplayShell *
|
|
action_data_get_shell (gpointer data)
|
|
{
|
|
PikaDisplayShell *result = NULL;
|
|
static gboolean recursion = FALSE;
|
|
|
|
if (! data || recursion)
|
|
return NULL;
|
|
|
|
recursion = TRUE;
|
|
|
|
if (! result)
|
|
{
|
|
PikaDisplay *display = action_data_get_display (data);
|
|
|
|
if (display)
|
|
result = pika_display_get_shell (display);
|
|
}
|
|
|
|
recursion = FALSE;
|
|
|
|
return result;
|
|
}
|
|
|
|
GtkWidget *
|
|
action_data_get_widget (gpointer data)
|
|
{
|
|
GtkWidget *result = NULL;
|
|
static gboolean recursion = FALSE;
|
|
|
|
if (! data || recursion)
|
|
return NULL;
|
|
|
|
recursion = TRUE;
|
|
|
|
if (GTK_IS_WIDGET (data))
|
|
result = data;
|
|
|
|
if (! result)
|
|
{
|
|
PikaDisplay *display = action_data_get_display (data);
|
|
|
|
if (display)
|
|
result = GTK_WIDGET (pika_display_get_shell (display));
|
|
}
|
|
|
|
if (! result)
|
|
result = dialogs_get_toolbox ();
|
|
|
|
recursion = FALSE;
|
|
|
|
return result;
|
|
}
|
|
|
|
gint
|
|
action_data_sel_count (gpointer data)
|
|
{
|
|
if (PIKA_IS_CONTAINER_EDITOR (data))
|
|
{
|
|
PikaContainerEditor *editor;
|
|
|
|
editor = PIKA_CONTAINER_EDITOR (data);
|
|
return pika_container_view_get_selected (editor->view, NULL, NULL);
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/* action_select_value:
|
|
* @select_type:
|
|
* @value:
|
|
* @min:
|
|
* max:
|
|
* def:
|
|
* small_inc:
|
|
* inc:
|
|
* skip_inc:
|
|
* delta_factor:
|
|
* wrap:
|
|
*
|
|
* For any valid enum @value (which are all negative), the corresponding
|
|
* action computes the semantic value (default, first, next, etc.).
|
|
* For a positive @value, it is considered as a per-thousand value
|
|
* between the @min and @max (possibly wrapped if @wrap is set, clamped
|
|
* otherwise), allowing to compute the returned value.
|
|
*
|
|
* Returns: the computed value to use for the action.
|
|
*/
|
|
gdouble
|
|
action_select_value (PikaActionSelectType select_type,
|
|
gdouble value,
|
|
gdouble min,
|
|
gdouble max,
|
|
gdouble def,
|
|
gdouble small_inc,
|
|
gdouble inc,
|
|
gdouble skip_inc,
|
|
gdouble delta_factor,
|
|
gboolean wrap)
|
|
{
|
|
switch (select_type)
|
|
{
|
|
case PIKA_ACTION_SELECT_SET_TO_DEFAULT:
|
|
value = def;
|
|
break;
|
|
|
|
case PIKA_ACTION_SELECT_FIRST:
|
|
value = min;
|
|
break;
|
|
|
|
case PIKA_ACTION_SELECT_LAST:
|
|
value = max;
|
|
break;
|
|
|
|
case PIKA_ACTION_SELECT_SMALL_PREVIOUS:
|
|
value -= small_inc;
|
|
break;
|
|
|
|
case PIKA_ACTION_SELECT_SMALL_NEXT:
|
|
value += small_inc;
|
|
break;
|
|
|
|
case PIKA_ACTION_SELECT_PREVIOUS:
|
|
value -= inc;
|
|
break;
|
|
|
|
case PIKA_ACTION_SELECT_NEXT:
|
|
value += inc;
|
|
break;
|
|
|
|
case PIKA_ACTION_SELECT_SKIP_PREVIOUS:
|
|
value -= skip_inc;
|
|
break;
|
|
|
|
case PIKA_ACTION_SELECT_SKIP_NEXT:
|
|
value += skip_inc;
|
|
break;
|
|
|
|
case PIKA_ACTION_SELECT_PERCENT_PREVIOUS:
|
|
g_return_val_if_fail (delta_factor >= 0.0, value);
|
|
value /= (1.0 + delta_factor);
|
|
break;
|
|
|
|
case PIKA_ACTION_SELECT_PERCENT_NEXT:
|
|
g_return_val_if_fail (delta_factor >= 0.0, value);
|
|
value *= (1.0 + delta_factor);
|
|
break;
|
|
|
|
default:
|
|
if ((gint) select_type >= 0)
|
|
value = (gdouble) select_type * (max - min) / 1000.0 + min;
|
|
else
|
|
g_return_val_if_reached (value);
|
|
break;
|
|
}
|
|
|
|
if (wrap)
|
|
{
|
|
while (value < min)
|
|
value = max - (min - value);
|
|
|
|
while (value > max)
|
|
value = min + (value - max);
|
|
}
|
|
else
|
|
{
|
|
value = CLAMP (value, min, max);
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
void
|
|
action_select_property (PikaActionSelectType select_type,
|
|
PikaDisplay *display,
|
|
GObject *object,
|
|
const gchar *property_name,
|
|
gdouble small_inc,
|
|
gdouble inc,
|
|
gdouble skip_inc,
|
|
gdouble delta_factor,
|
|
gboolean wrap)
|
|
{
|
|
GParamSpec *pspec;
|
|
|
|
g_return_if_fail (display == NULL || PIKA_IS_DISPLAY (display));
|
|
g_return_if_fail (G_IS_OBJECT (object));
|
|
g_return_if_fail (property_name != NULL);
|
|
|
|
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object),
|
|
property_name);
|
|
|
|
if (G_IS_PARAM_SPEC_DOUBLE (pspec))
|
|
{
|
|
gdouble value;
|
|
|
|
g_object_get (object, property_name, &value, NULL);
|
|
|
|
value = action_select_value (select_type,
|
|
value,
|
|
G_PARAM_SPEC_DOUBLE (pspec)->minimum,
|
|
G_PARAM_SPEC_DOUBLE (pspec)->maximum,
|
|
G_PARAM_SPEC_DOUBLE (pspec)->default_value,
|
|
small_inc, inc, skip_inc, delta_factor, wrap);
|
|
|
|
g_object_set (object, property_name, value, NULL);
|
|
|
|
if (display)
|
|
{
|
|
const gchar *blurb = g_param_spec_get_blurb (pspec);
|
|
|
|
if (blurb)
|
|
{
|
|
/* value description and new value shown in the status bar */
|
|
action_message (display, object, _("%s: %.2f"), blurb, value);
|
|
}
|
|
}
|
|
}
|
|
else if (G_IS_PARAM_SPEC_INT (pspec))
|
|
{
|
|
gint value;
|
|
|
|
g_object_get (object, property_name, &value, NULL);
|
|
|
|
value = action_select_value (select_type,
|
|
value,
|
|
G_PARAM_SPEC_INT (pspec)->minimum,
|
|
G_PARAM_SPEC_INT (pspec)->maximum,
|
|
G_PARAM_SPEC_INT (pspec)->default_value,
|
|
small_inc, inc, skip_inc, delta_factor, wrap);
|
|
|
|
g_object_set (object, property_name, value, NULL);
|
|
|
|
if (display)
|
|
{
|
|
const gchar *blurb = g_param_spec_get_blurb (pspec);
|
|
|
|
if (blurb)
|
|
{
|
|
/* value description and new value shown in the status bar */
|
|
action_message (display, object, _("%s: %d"), blurb, value);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
g_return_if_reached ();
|
|
}
|
|
}
|
|
|
|
PikaObject *
|
|
action_select_object (PikaActionSelectType select_type,
|
|
PikaContainer *container,
|
|
PikaObject *current)
|
|
{
|
|
gint select_index;
|
|
gint n_children;
|
|
|
|
g_return_val_if_fail (PIKA_IS_CONTAINER (container), NULL);
|
|
g_return_val_if_fail (current == NULL || PIKA_IS_OBJECT (current), NULL);
|
|
|
|
if (! current &&
|
|
select_type != PIKA_ACTION_SELECT_FIRST &&
|
|
select_type != PIKA_ACTION_SELECT_LAST)
|
|
return NULL;
|
|
|
|
n_children = pika_container_get_n_children (container);
|
|
|
|
if (n_children == 0)
|
|
return NULL;
|
|
|
|
switch (select_type)
|
|
{
|
|
case PIKA_ACTION_SELECT_FIRST:
|
|
select_index = 0;
|
|
break;
|
|
|
|
case PIKA_ACTION_SELECT_LAST:
|
|
select_index = n_children - 1;
|
|
break;
|
|
|
|
case PIKA_ACTION_SELECT_PREVIOUS:
|
|
select_index = pika_container_get_child_index (container, current) - 1;
|
|
break;
|
|
|
|
case PIKA_ACTION_SELECT_NEXT:
|
|
select_index = pika_container_get_child_index (container, current) + 1;
|
|
break;
|
|
|
|
case PIKA_ACTION_SELECT_SKIP_PREVIOUS:
|
|
select_index = pika_container_get_child_index (container, current) - 10;
|
|
break;
|
|
|
|
case PIKA_ACTION_SELECT_SKIP_NEXT:
|
|
select_index = pika_container_get_child_index (container, current) + 10;
|
|
break;
|
|
|
|
default:
|
|
if ((gint) select_type >= 0)
|
|
select_index = (gint) select_type;
|
|
else
|
|
g_return_val_if_reached (current);
|
|
break;
|
|
}
|
|
|
|
select_index = CLAMP (select_index, 0, n_children - 1);
|
|
|
|
return pika_container_get_child_by_index (container, select_index);
|
|
}
|
|
|
|
void
|
|
action_message (PikaDisplay *display,
|
|
GObject *object,
|
|
const gchar *format,
|
|
...)
|
|
{
|
|
PikaDisplayShell *shell = pika_display_get_shell (display);
|
|
PikaStatusbar *statusbar = pika_display_shell_get_statusbar (shell);
|
|
const gchar *icon_name = NULL;
|
|
va_list args;
|
|
|
|
if (PIKA_IS_TOOL_OPTIONS (object))
|
|
{
|
|
PikaToolInfo *tool_info = PIKA_TOOL_OPTIONS (object)->tool_info;
|
|
|
|
icon_name = pika_viewable_get_icon_name (PIKA_VIEWABLE (tool_info));
|
|
}
|
|
else if (PIKA_IS_VIEWABLE (object))
|
|
{
|
|
icon_name = pika_viewable_get_icon_name (PIKA_VIEWABLE (object));
|
|
}
|
|
|
|
va_start (args, format);
|
|
pika_statusbar_push_temp_valist (statusbar, PIKA_MESSAGE_INFO,
|
|
icon_name, format, args);
|
|
va_end (args);
|
|
}
|