Commit 7bb7cfb2 authored by Carlos Garnacho's avatar Carlos Garnacho Committed by Carlos Garnacho

Refactor GtkFileChooserDialog sizing.

2007-05-18  Carlos Garnacho  <carlos@imendio.com>

        Refactor GtkFileChooserDialog sizing.

        * gtkfilechooserembed.[ch] (delegate_get_resizable_hints)
        (_gtk_file_chooser_embed_get_resizable_hints):
        s/resizable_hints/resizable/, return just one boolean value to
        determine whether the filechooser should be resizable or not.

        * gtkfilechooserprivate.h (struct GtkFileChooserDialogPrivate): remove
        variables related to the GtkFileChooserEmbed get_default_size() and
        get_resizable() implementations.
        (struct GtkFileChooserDefault): Move default size management here.

        * gtkfilechooserdefault.c (gtk_file_chooser_default_size_allocate):
        Added, store currently allocated size to calculate default size later.
        (gtk_file_chooser_default_get_resizable_hints):
        s/resizable_hints/resizable/.
        (gtk_file_chooser_default_set_property): Reload settings if the file
        chooser action changes, this way the save expander state will be known
        before mapping the window, avoiding wrong window positioning and
        flickering. (#424299, #424309)
        (find_good_size_from_style): Only get size from style if it wasn't set
        previously.
        (gtk_file_chooser_default_get_default_size): return default size based
        on stored default size and preview/extra widget sizes.

        * gtkfilechooserdialog.c (file_chooser_widget_update_hints)
        (file_chooser_widget_realized_size_changed)
        (file_chooser_widget_unrealized_size_changed): simplified to
        (file_chooser_widget_size_changed): set window size and resizability
        based on the GtkFileChooserEmbed interface implementation. (Bug
        #420285, Tomeu Vizoso)
        (gtk_file_chooser_dialog_map): force a dialog size change, so it's
        clamped for sure to the 75% of the screen size.


svn path=/trunk/; revision=17859
parent a1498f76
2007-05-18 Carlos Garnacho <carlos@imendio.com>
Refactor GtkFileChooserDialog sizing.
* gtkfilechooserembed.[ch] (delegate_get_resizable_hints)
(_gtk_file_chooser_embed_get_resizable_hints):
s/resizable_hints/resizable/, return just one boolean value to
determine whether the filechooser should be resizable or not.
* gtkfilechooserprivate.h (struct GtkFileChooserDialogPrivate): remove
variables related to the GtkFileChooserEmbed get_default_size() and
get_resizable() implementations.
(struct GtkFileChooserDefault): Move default size management here.
* gtkfilechooserdefault.c (gtk_file_chooser_default_size_allocate):
Added, store currently allocated size to calculate default size later.
(gtk_file_chooser_default_get_resizable_hints):
s/resizable_hints/resizable/.
(gtk_file_chooser_default_set_property): Reload settings if the file
chooser action changes, this way the save expander state will be known
before mapping the window, avoiding wrong window positioning and
flickering. (#424299, #424309)
(find_good_size_from_style): Only get size from style if it wasn't set
previously.
(gtk_file_chooser_default_get_default_size): return default size based
on stored default size and preview/extra widget sizes.
* gtkfilechooserdialog.c (file_chooser_widget_update_hints)
(file_chooser_widget_realized_size_changed)
(file_chooser_widget_unrealized_size_changed): simplified to
(file_chooser_widget_size_changed): set window size and resizability
based on the GtkFileChooserEmbed interface implementation. (Bug
#420285, Tomeu Vizoso)
(gtk_file_chooser_dialog_map): force a dialog size change, so it's
clamped for sure to the 75% of the screen size.
2007-05-18 Carlos Garnacho <carlos@imendio.com>
* gtk/gtknotebook.c (gtk_notebook_real_insert_page): Do not unset
......
......@@ -324,6 +324,8 @@ static void gtk_file_chooser_default_style_set (GtkWidget *
GtkStyle *previous_style);
static void gtk_file_chooser_default_screen_changed (GtkWidget *widget,
GdkScreen *previous_screen);
static void gtk_file_chooser_default_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static gboolean gtk_file_chooser_default_set_current_folder (GtkFileChooser *chooser,
const GtkFilePath *path,
......@@ -362,9 +364,7 @@ static GSList * gtk_file_chooser_default_list_shortcut_folders (GtkFileCh
static void gtk_file_chooser_default_get_default_size (GtkFileChooserEmbed *chooser_embed,
gint *default_width,
gint *default_height);
static void gtk_file_chooser_default_get_resizable_hints (GtkFileChooserEmbed *chooser_embed,
gboolean *resize_horizontally,
gboolean *resize_vertically);
static gboolean gtk_file_chooser_default_get_resizable (GtkFileChooserEmbed *chooser_embed);
static gboolean gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed);
static void gtk_file_chooser_default_initial_focus (GtkFileChooserEmbed *chooser_embed);
......@@ -487,6 +487,7 @@ static void search_switch_to_browse_mode (GtkFileChooserDefault *impl);
static GSList *search_get_selected_paths (GtkFileChooserDefault *impl);
static void search_entry_activate_cb (GtkEntry *entry,
gpointer data);
static void settings_load (GtkFileChooserDefault *impl);
static void search_get_valid_child_iter (GtkFileChooserDefault *impl,
GtkTreeIter *child_iter,
GtkTreeIter *iter);
......@@ -613,6 +614,7 @@ _gtk_file_chooser_default_class_init (GtkFileChooserDefaultClass *class)
widget_class->hierarchy_changed = gtk_file_chooser_default_hierarchy_changed;
widget_class->style_set = gtk_file_chooser_default_style_set;
widget_class->screen_changed = gtk_file_chooser_default_screen_changed;
widget_class->size_allocate = gtk_file_chooser_default_size_allocate;
signals[LOCATION_POPUP] =
_gtk_binding_signal_new (I_("location-popup"),
......@@ -811,7 +813,7 @@ static void
gtk_file_chooser_embed_default_iface_init (GtkFileChooserEmbedIface *iface)
{
iface->get_default_size = gtk_file_chooser_default_get_default_size;
iface->get_resizable_hints = gtk_file_chooser_default_get_resizable_hints;
iface->get_resizable = gtk_file_chooser_default_get_resizable;
iface->should_respond = gtk_file_chooser_default_should_respond;
iface->initial_focus = gtk_file_chooser_default_initial_focus;
}
......@@ -5473,6 +5475,7 @@ gtk_file_chooser_default_set_property (GObject *object,
}
impl->action = action;
update_appearance (impl);
settings_load (impl);
}
}
break;
......@@ -5917,6 +5920,37 @@ gtk_file_chooser_default_screen_changed (GtkWidget *widget,
profile_end ("end", NULL);
}
static void
gtk_file_chooser_default_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkFileChooserDefault *impl;
impl = GTK_FILE_CHOOSER_DEFAULT (widget);
GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->size_allocate (widget, allocation);
if (!gtk_file_chooser_default_get_resizable (GTK_FILE_CHOOSER_EMBED (impl)))
{
/* The dialog is not resizable, we shouldn't
* trust in the size it has in this stage
*/
return;
}
impl->default_width = allocation->width;
impl->default_height = allocation->height;
if (impl->preview_widget_active &&
impl->preview_widget &&
GTK_WIDGET_DRAWABLE (impl->preview_widget))
impl->default_width -= impl->preview_widget->allocation.width + PREVIEW_HBOX_SPACING;
if (impl->extra_widget &&
GTK_WIDGET_DRAWABLE (impl->extra_widget))
impl->default_height -= GTK_BOX (widget)->spacing + impl->extra_widget->allocation.height;
}
static gboolean
get_is_file_filtered (GtkFileChooserDefault *impl,
const GtkFilePath *path,
......@@ -7760,49 +7794,35 @@ find_good_size_from_style (GtkWidget *widget,
gint *height)
{
GtkFileChooserDefault *impl;
gint default_width, default_height;
int font_size;
GtkRequisition req;
GdkScreen *screen;
double resolution;
g_assert (widget->style != NULL);
impl = GTK_FILE_CHOOSER_DEFAULT (widget);
screen = gtk_widget_get_screen (widget);
if (screen)
if (impl->default_width == 0 &&
impl->default_height == 0)
{
resolution = gdk_screen_get_resolution (screen);
if (resolution < 0.0) /* will be -1 if the resolution is not defined in the GdkScreen */
resolution = 96.0;
}
else
resolution = 96.0; /* wheeee */
font_size = pango_font_description_get_size (widget->style->font_desc);
font_size = PANGO_PIXELS (font_size) * resolution / 72.0;
screen = gtk_widget_get_screen (widget);
if (screen)
{
resolution = gdk_screen_get_resolution (screen);
if (resolution < 0.0) /* will be -1 if the resolution is not defined in the GdkScreen */
resolution = 96.0;
}
else
resolution = 96.0; /* wheeee */
default_width = font_size * NUM_CHARS;
default_height = font_size * NUM_LINES;
font_size = pango_font_description_get_size (widget->style->font_desc);
font_size = PANGO_PIXELS (font_size) * resolution / 72.0;
if (impl->preview_widget_active && impl->preview_widget)
{
gtk_widget_size_request (impl->preview_box, &req);
default_width += PREVIEW_HBOX_SPACING + req.width;
impl->default_width = font_size * NUM_CHARS;
impl->default_height = font_size * NUM_LINES;
}
if (impl->extra_widget)
{
gtk_widget_size_request (impl->extra_align, &req);
default_height += GTK_BOX (widget)->spacing + req.height;
}
gtk_widget_size_request (widget, &req);
default_width = MAX (default_width, req.width);
default_height = MAX (default_height, req.height);
*width = default_width;
*height = default_height;
*width = impl->default_width;
*height = impl->default_height;
}
static void
......@@ -7811,35 +7831,37 @@ gtk_file_chooser_default_get_default_size (GtkFileChooserEmbed *chooser_embed,
gint *default_height)
{
GtkFileChooserDefault *impl;
GtkRequisition req;
impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed);
find_good_size_from_style (GTK_WIDGET (chooser_embed), default_width, default_height);
if (impl->preview_widget_active &&
impl->preview_widget &&
GTK_WIDGET_VISIBLE (impl->preview_widget))
{
gtk_widget_size_request (impl->preview_box, &req);
*default_width += PREVIEW_HBOX_SPACING + req.width;
}
if (impl->extra_widget &&
GTK_WIDGET_VISIBLE (impl->extra_widget))
{
gtk_widget_size_request (impl->extra_align, &req);
*default_height += GTK_BOX (chooser_embed)->spacing + req.height;
}
}
static void
gtk_file_chooser_default_get_resizable_hints (GtkFileChooserEmbed *chooser_embed,
gboolean *resize_horizontally,
gboolean *resize_vertically)
static gboolean
gtk_file_chooser_default_get_resizable (GtkFileChooserEmbed *chooser_embed)
{
GtkFileChooserDefault *impl;
g_return_if_fail (resize_horizontally != NULL);
g_return_if_fail (resize_vertically != NULL);
impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed);
*resize_horizontally = TRUE;
*resize_vertically = TRUE;
if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
{
if (! gtk_expander_get_expanded (GTK_EXPANDER (impl->save_expander)))
{
*resize_horizontally = FALSE;
*resize_vertically = FALSE;
}
}
return (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
gtk_expander_get_expanded (GTK_EXPANDER (impl->save_expander)));
}
struct switch_folder_closure {
......
......@@ -86,10 +86,6 @@ gtk_file_chooser_dialog_init (GtkFileChooserDialog *dialog)
GtkDialog *fc_dialog = GTK_DIALOG (dialog);
dialog->priv = priv;
dialog->priv->default_width = -1;
dialog->priv->default_height = -1;
dialog->priv->resize_horizontally = TRUE;
dialog->priv->resize_vertically = TRUE;
dialog->priv->response_requested = FALSE;
gtk_dialog_set_has_separator (fc_dialog, FALSE);
......@@ -152,25 +148,6 @@ file_chooser_widget_file_activated (GtkFileChooser *chooser,
g_list_free (children);
}
static void
file_chooser_widget_update_hints (GtkFileChooserDialog *dialog,
gint width)
{
GtkFileChooserDialogPrivate *priv;
GdkGeometry geometry;
priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog);
geometry.min_width = (!priv->resize_horizontally ? width : -1);
geometry.min_height = -1;
geometry.max_width = (priv->resize_horizontally?G_MAXSHORT:-1);
geometry.max_height = (priv->resize_vertically?G_MAXSHORT:-1);
gtk_window_set_geometry_hints (GTK_WINDOW (dialog), NULL,
&geometry,
GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
}
static void
clamp_to_screen (GtkWidget *widget,
gint *width,
......@@ -195,131 +172,57 @@ clamp_to_screen (GtkWidget *widget,
}
static void
file_chooser_widget_default_realized_size_changed (GtkWidget *widget,
GtkFileChooserDialog *dialog)
file_chooser_widget_default_size_changed (GtkWidget *widget,
GtkFileChooserDialog *dialog)
{
GtkFileChooserDialogPrivate *priv;
gint width;
gint height;
gint width, height;
gint default_width, default_height;
GtkRequisition req;
gboolean resize_horizontally;
gboolean resize_vertically;
gboolean update_hints;
gint dx = 0, dy = 0;
gint cur_width, cur_height;
GtkRequisition req, widget_req;
gboolean resizable;
priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog);
/* Force a size request of everything before we start. This will make sure
* that widget->requisition is meaningful. */
gtk_widget_size_request (GTK_WIDGET (dialog), &req);
gtk_window_get_size (GTK_WINDOW (dialog), &cur_width, &cur_height);
width = GTK_WIDGET (dialog)->requisition.width - priv->widget->requisition.width;
height = GTK_WIDGET (dialog)->requisition.height - priv->widget->requisition.height;
_gtk_file_chooser_embed_get_default_size (GTK_FILE_CHOOSER_EMBED (priv->widget),
&default_width, &default_height);
/* Ideal target size modulo any resizing */
width = default_width + width;
height = default_height + height;
/* Unset any previously set size */
gtk_widget_set_size_request (GTK_WIDGET (dialog), -1, -1);
/* Now, we test for resizability */
update_hints = FALSE;
_gtk_file_chooser_embed_get_resizable_hints (GTK_FILE_CHOOSER_EMBED (priv->widget),
&resize_horizontally,
&resize_vertically);
resize_vertically = (!! resize_vertically); /* normalize */
resize_horizontally = (!! resize_horizontally);
if (resize_horizontally && priv->resize_horizontally)
if (GTK_WIDGET_DRAWABLE (widget))
{
dx = default_width - priv->default_width;
priv->default_width = default_width;
}
else if (resize_horizontally && ! priv->resize_horizontally)
{
/* We restore to the ideal size + any change in default_size (which is not
* expected). It would be nicer to store the older size to restore to in
* the future. */
dx = default_width - priv->default_width;
dx += width - cur_width;
priv->default_width = default_width;
update_hints = TRUE;
}
else
{
update_hints = TRUE;
}
/* Force a size request of everything before we start. This will make sure
* that widget->requisition is meaningful. */
gtk_widget_size_request (GTK_WIDGET (dialog), &req);
gtk_widget_size_request (widget, &widget_req);
if (resize_vertically && priv->resize_vertically)
{
dy = default_height - priv->default_height;
priv->default_height = default_height;
}
else if (resize_vertically && ! priv->resize_vertically)
{
dy = default_height - priv->default_height;
dy += height - cur_height;
priv->default_height = default_height;
update_hints = TRUE;
width = req.width - widget_req.width;
height = req.height - widget_req.height;
}
else
{
update_hints = TRUE;
width = GTK_WIDGET (dialog)->allocation.width - widget->allocation.width;
height = GTK_WIDGET (dialog)->allocation.height - widget->allocation.height;
}
priv->resize_horizontally = resize_horizontally;
priv->resize_vertically = resize_vertically;
if (dx != 0 || dy != 0)
{
gint new_width = cur_width + dx;
gint new_height = cur_height + dy;
clamp_to_screen (GTK_WIDGET (dialog), &new_width, &new_height);
gtk_window_resize (GTK_WINDOW (dialog), new_width, new_height);
}
/* Only store the size if we can resize in that direction. */
if (update_hints)
file_chooser_widget_update_hints (dialog, width);
}
static void
file_chooser_widget_default_unrealized_size_changed (GtkWidget *widget,
GtkFileChooserDialog *dialog)
{
GtkFileChooserDialogPrivate *priv;
GtkRequisition req;
gint width, height;
priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog);
gtk_widget_size_request (GTK_WIDGET (dialog), &req);
_gtk_file_chooser_embed_get_resizable_hints (GTK_FILE_CHOOSER_EMBED (priv->widget),
&(priv->resize_horizontally),
&(priv->resize_vertically));
resizable = _gtk_file_chooser_embed_get_resizable (GTK_FILE_CHOOSER_EMBED (priv->widget));
_gtk_file_chooser_embed_get_default_size (GTK_FILE_CHOOSER_EMBED (priv->widget),
&(priv->default_width), &(priv->default_height));
/* Determine how much space the rest of the dialog uses compared to priv->widget */
width = priv->default_width + GTK_WIDGET (dialog)->requisition.width - priv->widget->requisition.width;
height = priv->default_height + GTK_WIDGET (dialog)->requisition.height - priv->widget->requisition.height;
&default_width, &default_height);
gtk_window_set_default_size (GTK_WINDOW (dialog), width, height);
file_chooser_widget_update_hints (dialog, width);
}
/* Ideal target size plus any extra size */
width = default_width + width + (2 * GTK_CONTAINER (dialog)->border_width);
height = default_height + height + (2 * GTK_CONTAINER (dialog)->border_width);
static void
file_chooser_widget_default_size_changed (GtkWidget *widget,
GtkFileChooserDialog *dialog)
{
if (GTK_WIDGET_REALIZED (dialog))
file_chooser_widget_default_realized_size_changed (widget, dialog);
clamp_to_screen (GTK_WIDGET (dialog), &width, &height);
if (resizable)
{
gtk_window_set_resizable (GTK_WINDOW (dialog), resizable);
gtk_window_resize (GTK_WINDOW (dialog), width, height);
}
else
file_chooser_widget_default_unrealized_size_changed (widget, dialog);
{
gtk_widget_set_size_request (GTK_WIDGET (dialog), width, -1);
gtk_window_set_resizable (GTK_WINDOW (dialog), resizable);
}
}
static void
......@@ -490,6 +393,7 @@ gtk_file_chooser_dialog_map (GtkWidget *widget)
if (!GTK_WIDGET_MAPPED (priv->widget))
gtk_widget_map (priv->widget);
file_chooser_widget_default_size_changed (priv->widget, dialog);
_gtk_file_chooser_embed_initial_focus (GTK_FILE_CHOOSER_EMBED (priv->widget));
GTK_WIDGET_CLASS (gtk_file_chooser_dialog_parent_class)->map (widget);
......
......@@ -28,9 +28,7 @@ static void gtk_file_chooser_embed_class_init (gpointer g_iface);
static void delegate_get_default_size (GtkFileChooserEmbed *chooser_embed,
gint *default_width,
gint *default_height);
static void delegate_get_resizable_hints (GtkFileChooserEmbed *chooser_embed,
gboolean *resize_horizontally,
gboolean *resize_vertically);
static gboolean delegate_get_resizable (GtkFileChooserEmbed *chooser_embed);
static gboolean delegate_should_respond (GtkFileChooserEmbed *chooser_embed);
static void delegate_initial_focus (GtkFileChooserEmbed *chooser_embed);
static void delegate_default_size_changed (GtkFileChooserEmbed *chooser_embed,
......@@ -57,7 +55,7 @@ void
_gtk_file_chooser_embed_delegate_iface_init (GtkFileChooserEmbedIface *iface)
{
iface->get_default_size = delegate_get_default_size;
iface->get_resizable_hints = delegate_get_resizable_hints;
iface->get_resizable = delegate_get_resizable;
iface->should_respond = delegate_should_respond;
iface->initial_focus = delegate_initial_focus;
}
......@@ -96,13 +94,11 @@ delegate_get_default_size (GtkFileChooserEmbed *chooser_embed,
{
_gtk_file_chooser_embed_get_default_size (get_delegate (chooser_embed), default_width, default_height);
}
static void
delegate_get_resizable_hints (GtkFileChooserEmbed *chooser_embed,
gboolean *resize_horizontally,
gboolean *resize_vertically)
static gboolean
delegate_get_resizable (GtkFileChooserEmbed *chooser_embed)
{
_gtk_file_chooser_embed_get_resizable_hints (get_delegate (chooser_embed), resize_horizontally, resize_vertically);
return _gtk_file_chooser_embed_get_resizable (get_delegate (chooser_embed));
}
static gboolean
......@@ -208,14 +204,10 @@ _gtk_file_chooser_embed_initial_focus (GtkFileChooserEmbed *chooser_embed)
GTK_FILE_CHOOSER_EMBED_GET_IFACE (chooser_embed)->initial_focus (chooser_embed);
}
void
_gtk_file_chooser_embed_get_resizable_hints (GtkFileChooserEmbed *chooser_embed,
gboolean *resize_horizontally,
gboolean *resize_vertically)
gboolean
_gtk_file_chooser_embed_get_resizable (GtkFileChooserEmbed *chooser_embed)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER_EMBED (chooser_embed));
g_return_if_fail (resize_horizontally != NULL);
g_return_if_fail (resize_vertically != NULL);
g_return_val_if_fail (GTK_IS_FILE_CHOOSER_EMBED (chooser_embed), FALSE);
GTK_FILE_CHOOSER_EMBED_GET_IFACE (chooser_embed)->get_resizable_hints (chooser_embed, resize_horizontally, resize_vertically);
return GTK_FILE_CHOOSER_EMBED_GET_IFACE (chooser_embed)->get_resizable (chooser_embed);
}
......@@ -43,9 +43,7 @@ struct _GtkFileChooserEmbedIface
void (*get_default_size) (GtkFileChooserEmbed *chooser_embed,
gint *default_width,
gint *default_height);
void (*get_resizable_hints) (GtkFileChooserEmbed *chooser_embed,
gboolean *resize_horizontally,
gboolean *resize_vertically);
gboolean (*get_resizable) (GtkFileChooserEmbed *chooser_embed);
gboolean (*should_respond) (GtkFileChooserEmbed *chooser_embed);
......@@ -61,10 +59,7 @@ GType _gtk_file_chooser_embed_get_type (void) G_GNUC_CONST;
void _gtk_file_chooser_embed_get_default_size (GtkFileChooserEmbed *chooser_embed,
gint *default_width,
gint *default_height);
void _gtk_file_chooser_embed_get_resizable_hints (GtkFileChooserEmbed *chooser_embed,
gboolean *resize_horizontally,
gboolean *resize_vertically);
gboolean _gtk_file_chooser_embed_get_resizable (GtkFileChooserEmbed *chooser_embed);
gboolean _gtk_file_chooser_embed_should_respond (GtkFileChooserEmbed *chooser_embed);
void _gtk_file_chooser_embed_initial_focus (GtkFileChooserEmbed *chooser_embed);
......
......@@ -112,10 +112,6 @@ struct _GtkFileChooserDialogPrivate
char *file_system;
/* for use with GtkFileChooserEmbed */
gint default_width;
gint default_height;
gboolean resize_horizontally;
gboolean resize_vertically;
gboolean response_requested;
};
......@@ -289,6 +285,9 @@ struct _GtkFileChooserDefault
GSource *shortcuts_drag_outside_idle;
#endif
gint default_width;
gint default_height;
/* Flags */
guint local_only : 1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment