Commit 56a8cb68 authored by Martin Nordholts's avatar Martin Nordholts
Browse files

app: Have dialog factory entries for the dock windows

Let dock windows have proper GimpDialogFactory entries. This allows us
to get rid of a lot of ugly mostly duplicated code. This also makes us
ready the merge the dock window and toolbox factories which will soon
be done. A few things should be noted:

 * We adjust the wrap box aspect ratio in the toolbox to avoid having
   the toolbox dock window explode

 * We make sure that we still can handle sessionrc files from GIMP 2.6
   and older
parent 862ae52d
......@@ -104,6 +104,20 @@ GimpContainer *global_recent_docks = NULL;
FALSE /* remember_if_open */, \
FALSE /* dockable */}
#define DOCK_WINDOW(id, new_func) \
{ id /* identifier */, \
NULL /* name */, \
NULL /* blurb */, \
NULL /* stock_id */, \
NULL /* help_id */, \
new_func /* new_func */, \
0 /* view_size */, \
FALSE /* singleton */, \
TRUE /* session_managed */, \
TRUE /* remember_size */, \
TRUE /* remember_if_open */, \
FALSE /* dockable */}
#define LISTGRID(id, name, blurb, stock_id, help_id, view_size) \
{ "gimp-"#id"-list" /* identifier */, \
name /* name */, \
......@@ -216,6 +230,12 @@ static const GimpDialogFactoryEntry dock_entries[] =
DOCK ("gimp-toolbox",
dialogs_toolbox_new),
/* dock windows */
DOCK_WINDOW ("gimp-dock-window",
dialogs_dock_window_new),
DOCK_WINDOW ("gimp-toolbox-window",
dialogs_toolbox_dock_window_new),
/* singleton dockables */
DOCKABLE ("gimp-tool-options",
N_("Tool Options"), NULL, GIMP_STOCK_TOOL_OPTIONS,
......@@ -323,6 +343,17 @@ static const GimpDialogFactoryEntry dock_entries[] =
dialogs_palette_editor_get, 0, TRUE)
};
static const GimpDialogFactoryEntry toolbox_entries[] =
{
/* docks */
DOCK ("gimp-toolbox",
dialogs_toolbox_new),
/* dock windows */
DOCK_WINDOW ("gimp-toolbox-window",
dialogs_toolbox_dock_window_new)
};
/* public functions */
......@@ -346,16 +377,12 @@ dialogs_init (Gimp *gimp,
gimp_get_user_context (gimp),
menu_factory,
TRUE);
gimp_dialog_factory_set_dock_window_func (global_toolbox_factory,
dialogs_toolbox_dock_window_new);
/* Dock window */
global_dock_window_factory = gimp_dialog_factory_new ("dock",
gimp_get_user_context (gimp),
menu_factory,
TRUE);
gimp_dialog_factory_set_dock_window_func (global_dock_window_factory,
dialogs_dock_window_new);
/* Display */
global_display_factory = gimp_dialog_factory_new ("display",
......@@ -394,6 +421,21 @@ dialogs_init (Gimp *gimp,
dock_entries[i].remember_if_open,
dock_entries[i].dockable);
for (i = 0; i < G_N_ELEMENTS (toolbox_entries); i++)
gimp_dialog_factory_register_entry (global_toolbox_factory,
toolbox_entries[i].identifier,
gettext (toolbox_entries[i].name),
gettext (toolbox_entries[i].blurb),
toolbox_entries[i].stock_id,
toolbox_entries[i].help_id,
toolbox_entries[i].new_func,
toolbox_entries[i].view_size,
toolbox_entries[i].singleton,
toolbox_entries[i].session_managed,
toolbox_entries[i].remember_size,
toolbox_entries[i].remember_if_open,
toolbox_entries[i].dockable);
gimp_dialog_factory_register_entry (global_display_factory,
"gimp-empty-image-window",
NULL, NULL,
......
......@@ -262,20 +262,24 @@ gimp_ui_configurer_move_docks_to_window (GimpUIConfigurer *ui_configurer,
for (iter = docks; iter; iter = iter->next)
{
GimpDock *dock = GIMP_DOCK (iter->data);
GtkWidget *dock_window = NULL;
GimpDialogFactory *dialog_factory = NULL;
GimpDock *dock = GIMP_DOCK (iter->data);
GtkWidget *dock_window = NULL;
/* This is kind of ugly but not a disaster. We need the dock
* window correctly configured if we create it for the toolbox
/* 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
*/
dialog_factory = (GIMP_IS_TOOLBOX (dock) ?
global_toolbox_factory :
global_dock_window_factory);
/* Create a dock window to put the dock in */
dock_window = gimp_dialog_factory_dock_window_new (dialog_factory,
screen);
dock_window =
gimp_dialog_factory_dialog_new ((GIMP_IS_TOOLBOX (dock) ?
global_toolbox_factory :
global_dock_window_factory),
screen,
(GIMP_IS_TOOLBOX (dock) ?
"gimp-toolbox-window" :
"gimp-dock-window"),
-1 /*view_size*/,
FALSE /*present*/);
/* Move the dock to the window */
g_object_ref (dock);
......
......@@ -126,11 +126,12 @@ session_init (Gimp *gimp)
case G_TOKEN_SYMBOL:
if (scanner->value.v_symbol == GINT_TO_POINTER (SESSION_INFO))
{
GimpDialogFactory *factory;
GimpSessionInfo *info;
gchar *factory_name;
gchar *entry_name;
gboolean skip = FALSE;
GimpDialogFactory *factory = NULL;
GimpSessionInfo *info = NULL;
gchar *factory_name = NULL;
gchar *entry_name = NULL;
GimpDialogFactoryEntry *entry = NULL;
gboolean skip = FALSE;
token = G_TOKEN_STRING;
......@@ -138,7 +139,6 @@ session_init (Gimp *gimp)
break;
factory = gimp_dialog_factory_from_name (factory_name);
g_free (factory_name);
if (! factory)
break;
......@@ -148,30 +148,40 @@ session_init (Gimp *gimp)
info = gimp_session_info_new ();
/* "dock" entries in the "dock" factory are just dummy
* entries and don't have any dialog factory entry, so
* don't bother looking for entires for them
/* Previously, GimpDock was a toplevel. That is why
* versions <= GIMP 2.6 has "dock" as the entry name. We
* want "dock" to be interpreted as 'dock window'
* however so have some special-casing for that. When
* the entry name is "dock" the factory name is either
* "dock" or "toolbox".
*/
if (strcmp (entry_name, "dock"))
if (strcmp (entry_name, "dock") == 0)
{
GimpDialogFactoryEntry *entry =
entry =
gimp_dialog_factory_find_entry (factory,
entry_name);
if (entry)
{
gimp_session_info_set_factory_entry (info, entry);
}
else
{
/* If we expected a dialog factory entry but failed
* to find one, skip to add this session info object
*/
skip = TRUE;
}
(strcmp (factory_name, "toolbox") == 0 ?
"gimp-toolbox-window" :
"gimp-dock-window"));
}
else
{
entry = gimp_dialog_factory_find_entry (factory,
entry_name);
}
/* We're done with these now */
g_free (factory_name);
g_free (entry_name);
if (entry)
{
gimp_session_info_set_factory_entry (info, entry);
}
else
{
skip = TRUE;
}
if (gimp_config_deserialize (GIMP_CONFIG (info), scanner, 1, NULL))
{
if (! skip)
......
......@@ -73,8 +73,6 @@ struct _GimpDialogFactoryPrivate
GList *open_dialogs;
GList *session_infos;
GimpDialogNewFunc new_dock_window_func;
GList *registered_dialogs;
gboolean toggle_visibility;
......@@ -319,16 +317,6 @@ gimp_dialog_factory_from_name (const gchar *name)
return factory;
}
void
gimp_dialog_factory_set_dock_window_func (GimpDialogFactory *factory,
GimpDialogNewFunc new_dock_window_func)
{
g_return_if_fail (GIMP_IS_DIALOG_FACTORY (factory));
g_return_if_fail (new_dock_window_func != NULL);
factory->p->new_dock_window_func = new_dock_window_func;
}
void
gimp_dialog_factory_register_entry (GimpDialogFactory *factory,
const gchar *identifier,
......@@ -430,8 +418,7 @@ gimp_dialog_factory_dialog_sane (GimpDialogFactory *factory,
GimpDialogFactoryEntry *widget_entry,
GtkWidget *widget)
{
/* Note that GimpDockWindows don't have any entry */
if (! widget_factory || (! widget_entry && ! GIMP_IS_DOCK_WINDOW (widget)))
if (! widget_factory || ! widget_entry)
{
g_warning ("%s: dialog was not created by a GimpDialogFactory",
G_STRFUNC);
......@@ -701,7 +688,10 @@ gimp_dialog_factory_add_session_info (GimpDialogFactory *factory,
GimpSessionInfo *info)
{
g_return_if_fail (GIMP_IS_DIALOG_FACTORY (factory));
/* We want to append rather than prepend so that the serialized
* order in sessionrc remains the same
*/
factory->p->session_infos = g_list_append (factory->p->session_infos, info);
}
......@@ -839,18 +829,27 @@ gimp_dialog_factory_dock_with_window_new (GimpDialogFactory *factory,
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
/* Create a dock window to put the dock in. We need to create the
* dock window before the dock because the dock has a dependnecy to
* dock window before the dock because the dock has a dependency to
* the ui manager in the dock window
*/
dock_window = gimp_dialog_factory_dock_window_new (factory, screen);
dock_window =
gimp_dialog_factory_dialog_new (factory,
screen,
(strcmp ("toolbox", gimp_object_get_name (factory)) == 0 ?
"gimp-toolbox-window" :
"gimp-dock-window"),
-1 /*view_size*/,
FALSE /*present*/);
/* Create the dock */
ui_manager = gimp_dock_window_get_ui_manager (GIMP_DOCK_WINDOW (dock_window));
dock_id = g_strconcat ("gimp-", gimp_object_get_name (factory), NULL);
dock = gimp_dialog_factory_dialog_new (global_dock_window_factory,
dock = gimp_dialog_factory_dialog_new (factory,
screen,
"gimp-dock",
(strcmp ("toolbox", gimp_object_get_name (factory)) == 0 ?
"gimp-toolbox" :
"gimp-dock"),
-1 /*view_size*/,
FALSE /*present*/);
g_free (dock_id);
......@@ -866,38 +865,6 @@ gimp_dialog_factory_dock_with_window_new (GimpDialogFactory *factory,
return dock;
}
/**
* gimp_dialog_factory_dock_window_new:
* @factory:
* @screen:
*
* Creates a new dock window.
*
* Returns:
**/
GtkWidget *
gimp_dialog_factory_dock_window_new (GimpDialogFactory *factory,
GdkScreen *screen)
{
GtkWidget *dock_window = NULL;
g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (factory), NULL);
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
g_return_val_if_fail (factory->p->new_dock_window_func != NULL, NULL);
/* Create the dock window */
dock_window = factory->p->new_dock_window_func (factory, factory->p->context, NULL, 0);
gtk_window_set_screen (GTK_WINDOW (dock_window), screen);
gimp_dialog_factory_set_widget_data (dock_window, factory, NULL);
/* Add it to the dialog factory so it's position is saved when the
* app quits
*/
gimp_dialog_factory_add_dialog (factory, dock_window);
return dock_window;
}
void
gimp_dialog_factory_add_dialog (GimpDialogFactory *factory,
GtkWidget *dialog)
......@@ -1004,56 +971,12 @@ gimp_dialog_factory_add_dialog (GimpDialogFactory *factory,
factory->p->session_infos = g_list_append (factory->p->session_infos, info);
}
}
else /* dialog is a GimpDockWindow */
{
GIMP_LOG (DIALOG_FACTORY, "adding dock (dialog = %p)", dialog);
for (list = factory->p->session_infos; list; list = g_list_next (list))
{
GimpSessionInfo *current_info = list->data;
/* take the first empty slot */
if (! gimp_session_info_get_factory_entry (current_info) &&
! gimp_session_info_get_widget (current_info))
{
gimp_session_info_set_widget (current_info, dialog);
GIMP_LOG (DIALOG_FACTORY,
"updating session info %p (widget %p) for dock",
current_info, gimp_session_info_get_widget (current_info));
gimp_session_info_apply_geometry (current_info);
info = current_info;
break;
}
}
if (! info)
{
info = gimp_session_info_new ();
gimp_session_info_set_widget (info, dialog);
GIMP_LOG (DIALOG_FACTORY,
"creating session info %p (widget %p) for dock",
info, gimp_session_info_get_widget (info));
/* let new docks appear at the pointer position */
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
/* if we create a new session info, we never call
* gimp_session_info_apply_geometry(), but still the
* dialog needs GDK_HINT_USER_POS so it keeps its
* position when hidden/shown within this(!) session.
*/
g_signal_connect (dialog, "configure-event",
G_CALLBACK (gimp_dialog_factory_set_user_pos),
NULL);
factory->p->session_infos = g_list_append (factory->p->session_infos, info);
}
/* Some special logic for dock windows */
if (GIMP_IS_DOCK_WINDOW (dialog))
{
/* let new docks appear at the pointer position */
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
g_signal_emit (factory, factory_signals[DOCK_WINDOW_ADDED], 0, dialog);
}
......@@ -1143,7 +1066,7 @@ gimp_dialog_factory_remove_dialog (GimpDialogFactory *factory,
return;
GIMP_LOG (DIALOG_FACTORY, "removing \"%s\" (dialog = %p)",
entry ? entry->identifier : "dock",
entry->identifier,
dialog);
for (list = factory->p->session_infos; list; list = g_list_next (list))
......@@ -1155,7 +1078,7 @@ gimp_dialog_factory_remove_dialog (GimpDialogFactory *factory,
GIMP_LOG (DIALOG_FACTORY,
"clearing session info %p (widget %p) for \"%s\"",
session_info, gimp_session_info_get_widget (session_info),
entry ? entry->identifier : "dock");
entry->identifier);
gimp_session_info_set_widget (session_info, NULL);
......@@ -1513,7 +1436,7 @@ gimp_dialog_factory_dialog_configure (GtkWidget *dialog,
GIMP_LOG (DIALOG_FACTORY,
"updated session info for \"%s\" from window geometry "
"(x=%d y=%d %dx%d)",
entry ? entry->identifier : "dock",
entry->identifier,
gimp_session_info_get_x (session_info),
gimp_session_info_get_y (session_info),
gimp_session_info_get_width (session_info),
......@@ -1535,13 +1458,15 @@ gimp_dialog_factories_save_foreach (gconstpointer key,
for (infos = factory->p->session_infos; infos; infos = g_list_next (infos))
{
GimpSessionInfo *info = infos->data;
GimpSessionInfo *info = infos->data;
const gchar *identifier = NULL;
/* we keep session info entries for all toplevel dialogs created
* by the factory but don't save them if they don't want to be
* managed
*/
if (! gimp_session_info_is_session_managed (info))
if (! gimp_session_info_is_session_managed (info) ||
gimp_session_info_get_factory_entry (info) == NULL)
continue;
if (gimp_session_info_get_widget (info))
......@@ -1550,10 +1475,13 @@ gimp_dialog_factories_save_foreach (gconstpointer key,
gimp_config_writer_open (writer, "session-info");
gimp_config_writer_string (writer,
gimp_object_get_name (factory));
gimp_config_writer_string (writer,
gimp_session_info_get_factory_entry (info) ?
gimp_session_info_get_factory_entry (info)->identifier :
"dock");
/* Some special casing to be avoid changing sessionrc */
identifier = gimp_session_info_get_factory_entry (info)->identifier;
if (strcmp (identifier, "gimp-dock-window") == 0 ||
strcmp (identifier, "gimp-toolbox-window") == 0)
identifier = "dock";
gimp_config_writer_string (writer, identifier);
GIMP_CONFIG_GET_INTERFACE (info)->serialize (GIMP_CONFIG (info),
writer,
......
......@@ -110,8 +110,6 @@ GimpDialogFactory * gimp_dialog_factory_new (const gchar
GimpMenuFactory *menu_factory,
gboolean toggle_visibility);
GimpDialogFactory * gimp_dialog_factory_from_name (const gchar *name);
void gimp_dialog_factory_set_dock_window_func (GimpDialogFactory *factory,
GimpDialogNewFunc new_dock_window_func);
void gimp_dialog_factory_register_entry (GimpDialogFactory *factory,
const gchar *identifier,
const gchar *name,
......@@ -151,8 +149,6 @@ GtkWidget * gimp_dialog_factory_dockable_new (GimpDialogFactory
gint view_size);
GtkWidget * gimp_dialog_factory_dock_with_window_new (GimpDialogFactory *factory,
GdkScreen *screen);
GtkWidget * gimp_dialog_factory_dock_window_new (GimpDialogFactory *factory,
GdkScreen *screen);
void gimp_dialog_factory_add_dialog (GimpDialogFactory *factory,
GtkWidget *dialog);
void gimp_dialog_factory_add_foreign (GimpDialogFactory *factory,
......
......@@ -226,7 +226,7 @@ gimp_session_info_dock_restore (GimpSessionInfoDock *dock_info,
* type of dock depends on the factory
*/
dock_id = g_strconcat ("gimp-", gimp_object_get_name (factory), NULL);
dock = gimp_dialog_factory_dialog_new (global_dock_window_factory /* FIXME */,
dock = gimp_dialog_factory_dialog_new (factory,
screen,
dock_id,
-1 /*view_size*/,
......
......@@ -28,6 +28,8 @@
#include "widgets-types.h"
#include "dialogs/dialogs.h"
#include "gimpdialogfactory.h"
#include "gimpdock.h"
#include "gimpdockwindow.h"
......@@ -278,9 +280,6 @@ gimp_session_info_deserialize (GimpConfig *config,
{
GimpSessionInfoDock *dock_info = NULL;
if (info->p->factory_entry)
goto error;
g_scanner_set_scope (scanner, scope_id + 1);
token = gimp_session_info_dock_deserialize (scanner, scope_id + 1,
&dock_info);
......@@ -356,8 +355,9 @@ void
gimp_session_info_restore (GimpSessionInfo *info,
GimpDialogFactory *factory)
{
GdkDisplay *display;
GdkScreen *screen = NULL;
GtkWidget *dialog = NULL;
GdkDisplay *display = NULL;
GdkScreen *screen = NULL;
g_return_if_fail (GIMP_IS_SESSION_INFO (info));
g_return_if_fail (GIMP_IS_DIALOG_FACTORY (factory));
......@@ -373,10 +373,8 @@ gimp_session_info_restore (GimpSessionInfo *info,
info->p->open = FALSE;
info->p->screen = DEFAULT_SCREEN;
if (info->p->factory_entry && ! info->p->factory_entry->dockable)
if (! info->p->factory_entry->dockable)
{
GtkWidget *dialog;
GIMP_LOG (DIALOG_FACTORY, "restoring toplevel \"%s\" (info %p)",
info->p->factory_entry->identifier,
info);
......@@ -390,40 +388,29 @@ gimp_session_info_restore (GimpSessionInfo *info,
if (dialog && info->p->aux_info)
gimp_session_info_aux_set_list (dialog, info->p->aux_info);
}
else
{
GtkWidget *dock_window = NULL;
GList *iter = NULL;
GIMP_LOG (DIALOG_FACTORY, "restoring dock window (info %p)",
info);
dock_window = gimp_dialog_factory_dock_window_new (factory, screen);
if (dock_window && info->p->aux_info)
gimp_session_info_aux_set_list (GTK_WIDGET (dock_window), info->p->aux_info);
/* If we have docks, proceed as usual. If we don't have docks,
* assume it is the toolbox and restore the dock anyway
*/
if (info->p->docks)
{
for (iter = info->p->docks; iter; iter = g_list_next (iter))
gimp_session_info_dock_restore ((GimpSessionInfoDock *)iter->data,
factory,
screen,
GIMP_DOCK_WINDOW (dock_window));
}
else
{
gimp_session_info_dock_restore (NULL,
factory,
screen,
GIMP_DOCK_WINDOW (dock_window));
}
/* If we have docks, proceed as usual. If we don't have docks,
* assume it is the toolbox and restore the dock anyway
*/
if (info->p->docks)
{
GList *iter = NULL;
gtk_widget_show (GTK_WIDGET (dock_window));
for (iter = info->p->docks; iter; iter = g_list_next (iter))
gimp_session_info_dock_restore ((GimpSessionInfoDock *)iter->data,
factory,
screen,
GIMP_DOCK_WINDOW (dialog));
}
else
{
gimp_session_info_dock_restore (NULL,
factory,
screen,
GIMP_DOCK_WINDOW (dialog));
}
gtk_widget_show (dialog);
}
/* This function mostly lifted from
......@@ -633,9 +620,7 @@ gimp_session_info_get_info (GimpSessionInfo *info)
info->p->aux_info = gimp_session_info_aux_get_list (info->p->widget);
if (info->p->factory_entry == NULL ||
(info->p->factory_entry &&
info->p->factory_entry->dockable))
if (GIMP_IS_DOCK_WINDOW (info->p->widget))
{
GList *iter = NULL;
......
......@@ -286,7 +286,12 @@ gimp_toolbox_constructor (GType type,
gtk_wrap_box_set_justify (GTK_WRAP_BOX (toolbox->p->tool_wbox), GTK_JUSTIFY_TOP);
gtk_wrap_box_set_line_justify (GTK_WRAP_BOX (toolbox->p->tool_wbox),
GTK_JUSTIFY_LEFT);
gtk_wrap_box_set_aspect_ratio (GTK_WRAP_BOX (toolbox->p->tool_wbox), 1.0 / 30.0);
/* Be careful with this mechanism, it has a tendency to make the
* toolbox explode, meaning the size request for height becomes huge
*/
gtk_wrap_box_set_aspect_ratio (GTK_WRAP_BOX (toolbox->p->tool_wbox),
2.0 / 15.0);
gtk_box_pack_start (GTK_BOX (toolbox->p->vbox), toolbox->p->tool_wbox,
FALSE, FALSE, 0);
......@@ -296,7 +301,8 @@ gimp_toolbox_constructor (GType type,
gtk_wrap_box_set_justify (GTK_WRAP_BOX (toolbox->p->area_wbox), GTK_JUSTIFY_TOP);
gtk_wrap_box_set_line_justify (GTK_WRAP_BOX (toolbox->p->area_wbox),
GTK_JUSTIFY_LEFT);
gtk_wrap_box_set_aspect_ratio (GTK_WRAP_BOX (toolbox->p->area_wbox), 1.0 / 30.0);
gtk_wrap_box_set_aspect_ratio (GTK_WRAP_BOX (toolbox->p->area_wbox),
2.0 / 15.0);