Eine aufbereitete Darstellung der Quelle

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

Benutzer

Quelle  gimpuiconfigurer.c   Sprache: C

 

/* GIMP - The GNU Image Manipulation Program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * gimpuiconfigurer.c
 * Copyright (C) 2009 Martin Nordholts <martinn@src.gnome.org>
 *
 * 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 "libgimpbase/gimpbase.h"
#include "libgimpwidgets/gimpwidgets.h"

#include "gui-types.h"

#include "core/gimp.h"
#include "core/gimpcontext.h"

#include "widgets/gimpdialogfactory.h"
#include "widgets/gimpdock.h"
#include "widgets/gimpdockcolumns.h"
#include "widgets/gimpdockcontainer.h"
#include "widgets/gimpdockwindow.h"
#include "widgets/gimptoolbox.h"
#include "widgets/gimpwidgets-utils.h"

#include "display/gimpdisplay.h"
#include "display/gimpdisplayshell.h"
#include "display/gimpdisplayshell-appearance.h"
#include "display/gimpimagewindow.h"

#include "gimpuiconfigurer.h"


enum
{
  PROP_0,
  PROP_GIMP
};


struct _GimpUIConfigurerPrivate
{
  Gimp *gimp;
};


static void              gimp_ui_configurer_set_property                (GObject           *object,
                                                                         guint              property_id,
                                                                         const GValue      *value,
                                                                         GParamSpec        *pspec);
static void              gimp_ui_configurer_get_property                (GObject           *object,
                                                                         guint              property_id,
                                                                         GValue            *value,
                                                                         GParamSpec        *pspec);
static void              gimp_ui_configurer_move_docks_to_columns       (GimpUIConfigurer  *ui_configurer,
                                                                         GimpImageWindow   *uber_image_window);
static void              gimp_ui_configurer_move_shells                 (GimpUIConfigurer  *ui_configurer,
                                                                         GimpImageWindow   *source_image_window,
                                                                         GimpImageWindow   *target_image_window);
static void              gimp_ui_configurer_separate_docks              (GimpUIConfigurer  *ui_configurer,
                                                                         GimpImageWindow   *source_image_window);
static void              gimp_ui_configurer_move_docks_to_window        (GimpUIConfigurer  *ui_configurer,
                                                                         GimpDockColumns   *dock_columns,
                                                                         GimpAlignmentType  screen_side);
static void              gimp_ui_configurer_separate_shells             (GimpUIConfigurer  *ui_configurer,
                                                                         GimpImageWindow   *source_image_window);
static void              gimp_ui_configurer_configure_for_single_window (GimpUIConfigurer  *ui_configurer);
static void              gimp_ui_configurer_configure_for_multi_window  (GimpUIConfigurer  *ui_configurer);
static GimpImageWindow * gimp_ui_configurer_get_uber_window             (GimpUIConfigurer  *ui_configurer);


G_DEFINE_TYPE_WITH_PRIVATE (GimpUIConfigurer, gimp_ui_configurer,
                            GIMP_TYPE_OBJECT)

#define parent_class gimp_ui_configurer_parent_class


static void
gimp_ui_configurer_class_init (GimpUIConfigurerClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->set_property = gimp_ui_configurer_set_property;
  object_class->get_property = gimp_ui_configurer_get_property;

  g_object_class_install_property (object_class, PROP_GIMP,
                                   g_param_spec_object ("gimp", NULL, NULL,
                                                        GIMP_TYPE_GIMP,
                                                        GIMP_PARAM_READWRITE |
                                                        G_PARAM_CONSTRUCT_ONLY));
}

static void
gimp_ui_configurer_init (GimpUIConfigurer *ui_configurer)
{
  ui_configurer->p = gimp_ui_configurer_get_instance_private (ui_configurer);
}

static void
gimp_ui_configurer_set_property (GObject      *object,
                                 guint         property_id,
                                 const GValue *value,
                                 GParamSpec   *pspec)
{
  GimpUIConfigurer *ui_configurer = GIMP_UI_CONFIGURER (object);

  switch (property_id)
    {
    case PROP_GIMP:
      ui_configurer->p->gimp = g_value_get_object (value); /* don't ref */
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}

static void
gimp_ui_configurer_get_property (GObject    *object,
                                 guint       property_id,
                                 GValue     *value,
                                 GParamSpec *pspec)
{
  GimpUIConfigurer *ui_configurer = GIMP_UI_CONFIGURER (object);

  switch (property_id)
    {
    case PROP_GIMP:
      g_value_set_object (value, ui_configurer->p->gimp);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}


static void
gimp_ui_configurer_get_window_center_pos (GtkWindow *window,
                                          gint      *out_x,
                                          gint      *out_y)
{
  gint x, y, w, h;
  gtk_window_get_position (window, &x, &y);
  gtk_window_get_size (window, &w, &h);

  if (out_x)
    *out_x = x + w / 2;
  if (out_y)
    *out_y = y + h / 2;
}

/**
 * gimp_ui_configurer_get_relative_window_pos:
 * @window_a:
 * @window_b:
 *
 * Returns: At what side @window_b is relative to @window_a. Either
 * GIMP_ALIGN_LEFT or GIMP_ALIGN_RIGHT.
 **/

static GimpAlignmentType
gimp_ui_configurer_get_relative_window_pos (GtkWindow *window_a,
                                            GtkWindow *window_b)
{
  gint a_x, b_x;

  gimp_ui_configurer_get_window_center_pos (window_a, &a_x, NULL);
  gimp_ui_configurer_get_window_center_pos (window_b, &b_x, NULL);

  return b_x < a_x ? GIMP_ALIGN_LEFT : GIMP_ALIGN_RIGHT;
}

static void
gimp_ui_configurer_move_docks_to_columns (GimpUIConfigurer *ui_configurer,
                                          GimpImageWindow  *uber_image_window)
{
  GList *dialogs     = NULL;
  GList *dialog_iter = NULL;

  dialogs =
    g_list_copy (gimp_dialog_factory_get_open_dialogs (gimp_dialog_factory_get_singleton ()));

  for (dialog_iter = dialogs; dialog_iter; dialog_iter = dialog_iter->next)
    {
      GimpDockWindow    *dock_window;
      GimpDockContainer *dock_container;
      GimpDockColumns   *dock_columns;
      GList             *docks;
      GList             *dock_iter;

      if (!GIMP_IS_DOCK_WINDOW (dialog_iter->data))
        continue;

      dock_window = GIMP_DOCK_WINDOW (dialog_iter->data);

      /* If the dock window is on the left side of the image window,
       * move the docks to the left side. If the dock window is on the
       * right side, move the docks to the right side of the image
       * window.
       */

      if (gimp_ui_configurer_get_relative_window_pos (GTK_WINDOW (uber_image_window),
                                                      GTK_WINDOW (dock_window)) == GIMP_ALIGN_LEFT)
        dock_columns = gimp_image_window_get_left_docks (uber_image_window);
      else
        dock_columns = gimp_image_window_get_right_docks (uber_image_window);

      dock_container = GIMP_DOCK_CONTAINER (dock_window);

      g_object_add_weak_pointer (G_OBJECT (dock_window),
                                 (gpointer) &dock_window);

      docks = gimp_dock_container_get_docks (dock_container);
      for (dock_iter = docks; dock_iter; dock_iter = dock_iter->next)
        {
          GimpDock *dock = GIMP_DOCK (dock_iter->data);

          /* Move the dock from the image window to the dock columns
           * widget. Note that we need a ref while the dock is parentless
           */

          g_object_ref (dock);
          gimp_dock_window_remove_dock (dock_window, dock);
          gimp_dock_columns_add_dock (dock_columns, dock, -1);
          g_object_unref (dock);
        }
      g_list_free (docks);

      if (dock_window)
        g_object_remove_weak_pointer (G_OBJECT (dock_window),
                                      (gpointer) &dock_window);

      /* Kill the window if removing the dock didn't destroy it
       * already. This will be the case for the toolbox dock window
       */

      if (GTK_IS_WIDGET (dock_window))
        {
          guint docks_len;

          docks     = gimp_dock_container_get_docks (dock_container);
          docks_len = g_list_length (docks);

          if (docks_len == 0)
            {
              gimp_dialog_factory_remove_dialog (gimp_dialog_factory_get_singleton (),
                                                 GTK_WIDGET (dock_window));
              gtk_widget_destroy (GTK_WIDGET (dock_window));
            }

          g_list_free (docks);
        }
    }

  g_list_free (dialogs);
}

/**
 * gimp_ui_configurer_move_shells:
 * @ui_configurer:
 * @source_image_window:
 * @target_image_window:
 *
 * Move all display shells from one image window to the another.
 **/

static void
gimp_ui_configurer_move_shells (GimpUIConfigurer  *ui_configurer,
                                GimpImageWindow   *source_image_window,
                                GimpImageWindow   *target_image_window)
{
  while (gimp_image_window_get_n_shells (source_image_window) > 0)
    {
      GimpDisplayShell *shell;

      shell = gimp_image_window_get_shell (source_image_window, 0);

      g_object_ref (shell);
      gimp_image_window_remove_shell (source_image_window, shell);
      gimp_image_window_add_shell (target_image_window, shell);
      g_object_unref (shell);
    }
}

/**
 * gimp_ui_configurer_separate_docks:
 * @ui_configurer:
 * @image_window:
 *
 * Move out the docks from the image window.
 **/

static void
gimp_ui_configurer_separate_docks (GimpUIConfigurer  *ui_configurer,
                                   GimpImageWindow   *image_window)
{
  GimpDockColumns *left_docks  = NULL;
  GimpDockColumns *right_docks = NULL;

  left_docks  = gimp_image_window_get_left_docks (image_window);
  right_docks = gimp_image_window_get_right_docks (image_window);

  gimp_ui_configurer_move_docks_to_window (ui_configurer, left_docks, GIMP_ALIGN_LEFT);
  gimp_ui_configurer_move_docks_to_window (ui_configurer, right_docks, GIMP_ALIGN_RIGHT);
}

/**
 * gimp_ui_configurer_move_docks_to_window:
 * @dock_columns:
 * @screen_side: At what side of the screen the dock window should be put.
 *
 * Moves docks in @dock_columns into a new #GimpDockWindow and
 * position it on the screen in a non-overlapping manner.
 */

static void
gimp_ui_configurer_move_docks_to_window (GimpUIConfigurer  *ui_configurer,
                                         GimpDockColumns   *dock_columns,
                                         GimpAlignmentType  screen_side)
{
  GdkMonitor    *monitor;
  GdkRectangle   monitor_rect;
  GdkGravity     gravity;
  GList         *docks;
  GList         *iter;
  gboolean       contains_toolbox = FALSE;
  GtkWidget     *dock_window;
  GtkAllocation  original_size;
  gint           x, y;

  docks = g_list_copy (gimp_dock_columns_get_docks (dock_columns));
  if (! docks)
    return;

  monitor = gimp_widget_get_monitor (GTK_WIDGET (dock_columns));

  gdk_monitor_get_workarea (monitor, &monitor_rect);

  /* Remember the size so we can set the new dock window to the same
   * size
   */

  gtk_widget_get_allocation (GTK_WIDGET (dock_columns), &original_size);

  /* Do we need a toolbox window? */
  for (iter = docks; iter; iter = g_list_next (iter))
    {
      GimpDock *dock = GIMP_DOCK (iter->data);

      if (GIMP_IS_TOOLBOX (dock))
        {
          contains_toolbox = TRUE;
          break;
        }
    }

  /* Create a dock window to put the dock in. Checking for
   * GIMP_IS_TOOLBOX() is kind of ugly but not a disaster. We need
   * the dock window correctly configured if we create it for the
   * toolbox
   */

  dock_window =
    gimp_dialog_factory_dialog_new (gimp_dialog_factory_get_singleton (),
                                    monitor,
                                    NULL /*ui_manager*/,
                                    GTK_WIDGET (dock_columns),
                                    (contains_toolbox ?
                                     "gimp-toolbox-window" :
                                     "gimp-dock-window"),
                                    -1 /*view_size*/,
                                    FALSE /*present*/);

  for (iter = docks; iter; iter = g_list_next (iter))
    {
      GimpDock *dock = GIMP_DOCK (iter->data);

      /* Move the dock to the window */
      g_object_ref (dock);
      gimp_dock_columns_remove_dock (dock_columns, dock);
      gimp_dock_window_add_dock (GIMP_DOCK_WINDOW (dock_window), dock, -1);
      g_object_unref (dock);
    }

  /* Position the window */
  if (screen_side == GIMP_ALIGN_LEFT)
    {
      gravity = GDK_GRAVITY_NORTH_WEST;

      x = monitor_rect.x;
      y = monitor_rect.y;
    }
  else if (screen_side == GIMP_ALIGN_RIGHT)
    {
      gravity = GDK_GRAVITY_NORTH_EAST;

      x = monitor_rect.x + monitor_rect.width - original_size.width;
      y = monitor_rect.y;
    }
  else
    {
      gimp_assert_not_reached ();
    }

  gtk_window_set_gravity (GTK_WINDOW (dock_window), gravity);
  gtk_window_move (GTK_WINDOW (dock_window), x, y);

  /* Try to keep the same size */
  gtk_window_set_default_size (GTK_WINDOW (dock_window),
                               original_size.width,
                               original_size.height);

  /* Don't forget to show the window */
  gtk_widget_show (dock_window);

  g_list_free (docks);
}

/**
 * gimp_ui_configurer_separate_shells:
 * @ui_configurer:
 * @source_image_window:
 *
 * Create one image window per display shell and move it there.
 **/

static void
gimp_ui_configurer_separate_shells (GimpUIConfigurer *ui_configurer,
                                    GimpImageWindow  *source_image_window)
{
  GimpDisplayShell *active_shell  = gimp_image_window_get_active_shell (source_image_window);
  GimpImageWindow  *active_window = NULL;

  /* The last display shell remains in its window */
  while (gimp_image_window_get_n_shells (source_image_window) > 1)
    {
      GimpImageWindow  *new_image_window;
      GimpDisplayShell *shell;

      /* Create a new image window */
      new_image_window = gimp_image_window_new (ui_configurer->p->gimp,
                                                NULL,
                                                gimp_dialog_factory_get_singleton (),
                                                gimp_widget_get_monitor (GTK_WIDGET (source_image_window)));
      /* Move the shell there */
      shell = gimp_image_window_get_shell (source_image_window, 1);

      if (shell == active_shell)
        active_window = new_image_window;

      g_object_ref (shell);
      gimp_image_window_remove_shell (source_image_window, shell);
      gimp_image_window_add_shell (new_image_window, shell);
      g_object_unref (shell);

      /* FIXME: If we don't set a size request here the window will be
       * too small. Get rid of this hack and fix it the proper way
       */

      gtk_widget_set_size_request (GTK_WIDGET (new_image_window), 640, 480);

      /* Show after we have added the shell */
      gtk_widget_show (GTK_WIDGET (new_image_window));
    }

  /* If none of the shells were active, I assume the first one is. */
  if (active_window == NULL)
    active_window = source_image_window;

  /* The active tab must stay at the top of the windows stack. */
  gtk_window_present (GTK_WINDOW (active_window));
}

/**
 * gimp_ui_configurer_configure_for_single_window:
 * @ui_configurer:
 *
 * Move docks and display shells into a single window.
 **/

static void
gimp_ui_configurer_configure_for_single_window (GimpUIConfigurer *ui_configurer)
{
  Gimp             *gimp              = ui_configurer->p->gimp;
  GList            *windows           = gimp_get_image_windows (gimp);
  GList            *iter              = NULL;
  GimpImageWindow  *uber_image_window = NULL;
  GimpDisplay      *active_display    = gimp_context_get_display (gimp_get_user_context (gimp));
  GimpDisplayShell *active_shell      = gimp_display_get_shell (active_display);

  /* Get and setup the window to put everything in */
  uber_image_window = gimp_ui_configurer_get_uber_window (ui_configurer);

  /* Mve docks to the left and right side of the image window */
  gimp_ui_configurer_move_docks_to_columns (ui_configurer,
                                            uber_image_window);

  /* Move image shells from other windows to the uber image window */
  for (iter = windows; iter; iter = g_list_next (iter))
    {
      GimpImageWindow *image_window = GIMP_IMAGE_WINDOW (iter->data);

      /* Don't move stuff to itself */
      if (image_window == uber_image_window)
        continue;

      /* Put the displays in the rest of the image windows into
       * the uber image window
       */

      gimp_ui_configurer_move_shells (ui_configurer,
                                      image_window,
                                      uber_image_window);
      /* Destroy the window */
      gimp_image_window_destroy (image_window);
    }

  /* Ensure the context shell remains active after mode switch. */
  gimp_image_window_set_active_shell (uber_image_window, active_shell);

  g_list_free (windows);
}

/**
 * gimp_ui_configurer_configure_for_multi_window:
 * @ui_configurer:
 *
 * Moves all display shells into their own image window.
 **/

static void
gimp_ui_configurer_configure_for_multi_window (GimpUIConfigurer *ui_configurer)
{
  Gimp  *gimp    = ui_configurer->p->gimp;
  GList *windows = gimp_get_image_windows (gimp);
  GList *iter    = NULL;

  for (iter = windows; iter; iter = g_list_next (iter))
    {
      GimpImageWindow *image_window = GIMP_IMAGE_WINDOW (iter->data);

      gimp_ui_configurer_separate_docks (ui_configurer, image_window);

      gimp_ui_configurer_separate_shells (ui_configurer, image_window);
    }

  g_list_free (windows);
}

/**
 * gimp_ui_configurer_get_uber_window:
 * @ui_configurer:
 *
 * Returns: The window to be used as the main window for single-window
 *          mode.
 **/

static GimpImageWindow *
gimp_ui_configurer_get_uber_window (GimpUIConfigurer *ui_configurer)
{
  Gimp             *gimp         = ui_configurer->p->gimp;
  GimpDisplay      *display      = gimp_get_display_iter (gimp)->data;
  GimpDisplayShell *shell        = gimp_display_get_shell (display);
  GimpImageWindow  *image_window = gimp_display_shell_get_window (shell);

  return image_window;
}

/**
 * gimp_ui_configurer_update_appearance:
 * @ui_configurer:
 *
 * Updates the appearance of all shells in all image windows, so they
 * do whatever they deem necessary to fit the new UI mode mode.
 **/

static void
gimp_ui_configurer_update_appearance (GimpUIConfigurer *ui_configurer)
{
  Gimp  *gimp    = ui_configurer->p->gimp;
  GList *windows = gimp_get_image_windows (gimp);
  GList *list;

  for (list = windows; list; list = g_list_next (list))
    {
      GimpImageWindow *image_window = GIMP_IMAGE_WINDOW (list->data);
      gint             n_shells;
      gint             i;

      n_shells = gimp_image_window_get_n_shells (image_window);

      for (i = 0; i < n_shells; i++)
        {
          GimpDisplayShell *shell;

          shell = gimp_image_window_get_shell (image_window, i);

          gimp_display_shell_appearance_update (shell);
        }
    }

  g_list_free (windows);
}

/**
 * gimp_ui_configurer_configure:
 * @ui_configurer:
 * @single_window_mode:
 *
 * Configure the UI.
 **/

void
gimp_ui_configurer_configure (GimpUIConfigurer *ui_configurer,
                              gboolean          single_window_mode)
{
  if (single_window_mode)
    gimp_ui_configurer_configure_for_single_window (ui_configurer);
  else
    gimp_ui_configurer_configure_for_multi_window (ui_configurer);

  gimp_ui_configurer_update_appearance (ui_configurer);
}

Messung
CHZG
869810094

¤ Dauer der Verarbeitung: 0.13 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

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

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104857
#Domains=438743