mirror of
https://gitlab.gnome.org/GNOME/nautilus
synced 2024-09-17 23:01:59 +00:00
fd9598d8ba
2000-10-26 Mathieu Lacage <mathieu@eazel.com> Fix bug 2571: action not computed corected for dnd in list view. Also, the dnd in list view should be slightly nicer now :) * libnautilus-extensions/nautilus-gtk-extensions.c: (nautilus_gtk_marshal_NONE__POINTER_POINTER_POINTER_INT_INT_INT), space (nautilus_gtk_marshal_NONE__POINTER_POINTER_POINTER_POINTER_INT_INT _UINT): brand new function for brand new signal as below :) * libnautilus-extensions/nautilus-gtk-extensions.h: prototype. * libnautilus-extensions/nautilus-list.c: (nautilus_list_initialize_class), (nautilus_list_get_drop_action): * libnautilus-extensions/nautilus-list.h: Add signal get_default_action, remove old code to compute default action... * src/file-manager/fm-list-view.c: (nautilus_list_find_icon_list_drop_target), (fm_list_get_default_action), (set_up_list): connect to new signal, move old code to there, cleanup, finish.
1498 lines
37 KiB
C
1498 lines
37 KiB
C
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
|
|
|
/* nautilus-gtk-extensions.c - implementation of new functions that operate on
|
|
gtk classes. Perhaps some of these should be
|
|
rolled into gtk someday.
|
|
|
|
Copyright (C) 1999, 2000 Eazel, Inc.
|
|
|
|
The Gnome Library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public License as
|
|
published by the Free Software Foundation; either version 2 of the
|
|
License, or (at your option) any later version.
|
|
|
|
The Gnome Library 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
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public
|
|
License along with the Gnome Library; see the file COPYING.LIB. If not,
|
|
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
Boston, MA 02111-1307, USA.
|
|
|
|
Authors: John Sullivan <sullivan@eazel.com>
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include "nautilus-gtk-extensions.h"
|
|
#include "nautilus-gdk-extensions.h"
|
|
|
|
#include <gtk/gtkselection.h>
|
|
#include <gtk/gtksignal.h>
|
|
#include <libgnomeui/gnome-geometry.h>
|
|
#include "nautilus-glib-extensions.h"
|
|
#include "nautilus-string.h"
|
|
|
|
/* This number should be large enough to be visually noticeable,
|
|
* but small enough to not allow the user to perform other actions.
|
|
*/
|
|
#define BUTTON_AUTO_HIGHLIGHT_MILLISECONDS 100
|
|
|
|
/* This number is fairly arbitrary. Long enough to show a pretty long
|
|
* menu title, but not so long to make a menu grotesquely wide.
|
|
*/
|
|
#define MAXIMUM_MENU_TITLE_LENGTH 48
|
|
|
|
/* Used for window position & size sanity-checking. The sizes are big enough to prevent
|
|
* at least normal-sized gnome panels from obscuring the window at the screen edges.
|
|
*/
|
|
#define MINIMUM_ON_SCREEN_WIDTH 100
|
|
#define MINIMUM_ON_SCREEN_HEIGHT 100
|
|
|
|
static gboolean
|
|
finish_button_activation (gpointer data)
|
|
{
|
|
GtkButton *button;
|
|
|
|
button = GTK_BUTTON (data);
|
|
|
|
if (!button->in_button) {
|
|
gtk_button_clicked (button);
|
|
}
|
|
gtk_button_released (button);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_button_auto_click:
|
|
*
|
|
* Programatically activate a button as if the user had clicked on it,
|
|
* including briefly drawing the button's pushed-in state.
|
|
* @button: Any GtkButton.
|
|
**/
|
|
void
|
|
nautilus_gtk_button_auto_click (GtkButton *button)
|
|
{
|
|
g_return_if_fail (GTK_IS_BUTTON (button));
|
|
|
|
if (!GTK_WIDGET_IS_SENSITIVE (GTK_WIDGET (button))) {
|
|
return;
|
|
}
|
|
|
|
button->in_button = TRUE;
|
|
gtk_button_pressed (button);
|
|
button->in_button = FALSE;
|
|
|
|
/* FIXME bugzilla.eazel.com 2562:
|
|
* Nothing is preventing other events from occuring between
|
|
* now and when this timeout function fires, which means in
|
|
* theory the user could click on a different row or otherwise
|
|
* get in between the double-click and the button activation.
|
|
* In practice the timeout is short enough that this probably
|
|
* isn't a problem.
|
|
*/
|
|
g_timeout_add (BUTTON_AUTO_HIGHLIGHT_MILLISECONDS,
|
|
finish_button_activation, button);
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_button_set_padding
|
|
*
|
|
* Adds some padding around the contained widget in the button (typically the label).
|
|
* @button: a GtkButton
|
|
* @pad_amount: number of pixels of space to add around the button's contents.
|
|
* GNOME_PAD_SMALL is a typical value.
|
|
**/
|
|
void
|
|
nautilus_gtk_button_set_padding (GtkButton *button, int pad_amount)
|
|
{
|
|
g_return_if_fail (GTK_IS_BUTTON (button));
|
|
g_return_if_fail (pad_amount > 0);
|
|
|
|
gtk_misc_set_padding (GTK_MISC (GTK_BIN(button)->child),
|
|
pad_amount,
|
|
pad_amount);
|
|
}
|
|
|
|
|
|
/**
|
|
* nautilus_gtk_clist_get_first_selected_row:
|
|
*
|
|
* Get the index of the first selected row, or -1 if no rows are selected.
|
|
* @list: Any GtkCList
|
|
**/
|
|
int
|
|
nautilus_gtk_clist_get_first_selected_row (GtkCList *list)
|
|
{
|
|
GtkCListRow *row;
|
|
GList *p;
|
|
int row_number;
|
|
|
|
g_return_val_if_fail (GTK_IS_CLIST (list), -1);
|
|
|
|
row_number = 0;
|
|
for (p = GTK_CLIST (list)->row_list; p != NULL; p = p->next) {
|
|
row = p->data;
|
|
if (row->state == GTK_STATE_SELECTED) {
|
|
return row_number;
|
|
}
|
|
|
|
++row_number;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_clist_get_last_selected_row:
|
|
*
|
|
* Get the index of the last selected row, or -1 if no rows are selected.
|
|
* @list: Any GtkCList
|
|
**/
|
|
int
|
|
nautilus_gtk_clist_get_last_selected_row (GtkCList *list)
|
|
{
|
|
GtkCListRow *row;
|
|
GList *p;
|
|
int row_number;
|
|
|
|
g_return_val_if_fail (GTK_IS_CLIST (list), -1);
|
|
|
|
row_number = GTK_CLIST (list)->rows - 1;
|
|
for (p = GTK_CLIST (list)->row_list_end; p != NULL; p = p->prev) {
|
|
row = p->data;
|
|
if (row->state == GTK_STATE_SELECTED) {
|
|
return row_number;
|
|
}
|
|
|
|
--row_number;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static gint
|
|
activate_button_on_double_click (GtkWidget *widget,
|
|
GdkEventButton *event,
|
|
gpointer user_data)
|
|
{
|
|
g_assert (GTK_IS_CLIST (widget));
|
|
g_assert (GTK_IS_BUTTON (user_data));
|
|
|
|
/* Treat double-click like single click followed by
|
|
* click on specified button.
|
|
*/
|
|
if (event->type == GDK_2BUTTON_PRESS
|
|
&& GTK_WIDGET_SENSITIVE (GTK_WIDGET (user_data))) {
|
|
nautilus_gtk_button_auto_click (GTK_BUTTON (user_data));
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_clist_set_double_click_button:
|
|
*
|
|
* Set a button to be auto-clicked when a clist gets a double-click.
|
|
* @clist: Any GtkCList
|
|
* @button: A GtkButton that will be auto-clicked when the clist gets
|
|
* a double-click event. If the button is not sensitive, this function
|
|
* does nothing.
|
|
**/
|
|
void
|
|
nautilus_gtk_clist_set_double_click_button (GtkCList *clist, GtkButton *button)
|
|
{
|
|
g_return_if_fail (GTK_IS_CLIST (clist));
|
|
g_return_if_fail (GTK_IS_BUTTON (button));
|
|
|
|
gtk_signal_connect (GTK_OBJECT (clist),
|
|
"button_press_event",
|
|
(GtkSignalFunc) activate_button_on_double_click,
|
|
button);
|
|
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_signal_connect_free_data_custom:
|
|
*
|
|
* Attach a function pointer and user data to a signal, and call a
|
|
* a destroy function on the user data when the signal is disconnected.
|
|
* @object: the object which emits the signal. For example, a button in the button press signal.
|
|
* @name: the name of the signal.
|
|
* @func: function pointer to attach to the signal.
|
|
* @data: the user data associated with the function.
|
|
* @destroy_func: the function to call on the user data when the signal
|
|
* is disconnected.
|
|
**/
|
|
guint nautilus_gtk_signal_connect_free_data_custom (GtkObject *object,
|
|
const gchar *name,
|
|
GtkSignalFunc func,
|
|
gpointer data,
|
|
GtkDestroyNotify destroy_func)
|
|
{
|
|
return gtk_signal_connect_full (object,
|
|
name,
|
|
func,
|
|
NULL, /* marshal */
|
|
data,
|
|
destroy_func,
|
|
FALSE, /* is this an object signal? */
|
|
FALSE); /* invoke func after signal? */
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_signal_connect_free_data:
|
|
*
|
|
* Attach a function pointer and user data to a signal, and free
|
|
* the user data when the signal is disconnected.
|
|
* @object: the object which emits the signal. For example, a button in the button press signal.
|
|
* @name: the name of the signal.
|
|
* @func: function pointer to attach to the signal.
|
|
* @data: the user data associated with the function. g_free() will be called on
|
|
* this user data when the signal is disconnected.
|
|
**/
|
|
guint nautilus_gtk_signal_connect_free_data (GtkObject *object,
|
|
const gchar *name,
|
|
GtkSignalFunc func,
|
|
gpointer data)
|
|
{
|
|
return nautilus_gtk_signal_connect_free_data_custom
|
|
(object, name, func, data, g_free);
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_window_hide_retain_geometry:
|
|
*
|
|
* Hide a GtkWindow such that when reopened it will be in the same
|
|
* place it is now.
|
|
* @window: The GtkWindow to be hidden.
|
|
**/
|
|
static void
|
|
nautilus_gtk_window_hide_retain_geometry (GtkWindow *window) {
|
|
gchar *geometry_string;
|
|
int left, top, width, height;
|
|
|
|
g_return_if_fail (GTK_IS_WINDOW (window));
|
|
|
|
/* Save and restore position to keep it in same position when next shown. */
|
|
|
|
geometry_string = gnome_geometry_string (GTK_WIDGET (window)->window);
|
|
|
|
gtk_widget_hide (GTK_WIDGET (window));
|
|
|
|
if (gnome_parse_geometry (geometry_string, &left, &top, &width, &height))
|
|
{
|
|
gtk_window_set_default_size (window, width, height);
|
|
gtk_widget_set_uposition (GTK_WIDGET (window), left, top);
|
|
}
|
|
|
|
g_free (geometry_string);
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_window_present:
|
|
*
|
|
* Presents to the user a window that may be hidden, iconified, or buried.
|
|
* @window: The GtkWindow to be presented to the user.
|
|
**/
|
|
void
|
|
nautilus_gtk_window_present (GtkWindow *window) {
|
|
g_assert (GTK_IS_WINDOW (window));
|
|
|
|
/* Hide first if already showing, so it will reappear on top.
|
|
* This works with iconified windows as well.
|
|
*/
|
|
if (GTK_WIDGET_VISIBLE (GTK_WIDGET (window)))
|
|
{
|
|
nautilus_gtk_window_hide_retain_geometry (window);
|
|
}
|
|
|
|
gtk_widget_show (GTK_WIDGET (window));
|
|
}
|
|
|
|
static void
|
|
sanity_check_window_geometry (int *left, int *top, int *width, int *height)
|
|
{
|
|
g_assert (left != NULL);
|
|
g_assert (top != NULL);
|
|
g_assert (width != NULL);
|
|
g_assert (height != NULL);
|
|
|
|
/* Pin the size of the window to the screen, so we don't end up in
|
|
* a state where the window is so big essential parts of it can't
|
|
* be reached (might not be necessary with all window managers,
|
|
* but seems reasonable anyway).
|
|
*/
|
|
*width = MIN (*width, gdk_screen_width());
|
|
*height = MIN (*height, gdk_screen_height());
|
|
|
|
/* Make sure the top of the window is on screen, for
|
|
* draggability (might not be necessary with all window managers,
|
|
* but seems reasonable anyway). Make sure the top of the window
|
|
* isn't off the bottom of the screen, or so close to the bottom
|
|
* that it might be obscured by the panel.
|
|
*/
|
|
*top = CLAMP (*top, 0, gdk_screen_height() - MINIMUM_ON_SCREEN_HEIGHT);
|
|
|
|
/* FIXME bugzilla.eazel.com 669:
|
|
* If window has negative left coordinate, set_uposition sends it
|
|
* somewhere else entirely. Not sure what level contains this bug (XWindows?).
|
|
* Hacked around by pinning the left edge to zero, which just means you
|
|
* can't set a window to be partly off the left of the screen using
|
|
* this routine.
|
|
*/
|
|
/* Make sure the left edge of the window isn't off the right edge of
|
|
* the screen, or so close to the right edge that it might be
|
|
* obscured by the panel.
|
|
*/
|
|
*left = CLAMP (*left, 0, gdk_screen_width() - MINIMUM_ON_SCREEN_WIDTH);
|
|
}
|
|
|
|
|
|
/**
|
|
* nautilus_gtk_window_set_initial_geometry:
|
|
*
|
|
* Sets the position and size of a GtkWindow before the
|
|
* GtkWindow is shown. It is an error to call this on a window that
|
|
* is already on-screen. Takes into account screen size, and does
|
|
* some sanity-checking on the passed-in values.
|
|
*
|
|
* @window: A non-visible GtkWindow
|
|
* @left: pixel coordinate for left of window
|
|
* @top: pixel coordinate for top of window
|
|
* @width: width of window in pixels
|
|
* @height: height of window in pixels
|
|
*/
|
|
void
|
|
nautilus_gtk_window_set_initial_geometry (GtkWindow *window,
|
|
int left,
|
|
int top,
|
|
int width,
|
|
int height)
|
|
{
|
|
g_return_if_fail (GTK_IS_WINDOW (window));
|
|
g_return_if_fail (width > 0 && height > 0);
|
|
|
|
/* Setting the default size doesn't work when the window is already showing.
|
|
* Someday we could make this move an already-showing window, but we don't
|
|
* need that functionality yet.
|
|
*/
|
|
g_return_if_fail (!GTK_WIDGET_VISIBLE (window));
|
|
|
|
sanity_check_window_geometry (&left, &top, &width, &height);
|
|
|
|
gtk_widget_set_uposition (GTK_WIDGET (window), left, top);
|
|
gtk_window_set_default_size (GTK_WINDOW (window), width, height);
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_window_set_initial_geometry_from_string:
|
|
*
|
|
* Sets the position and size of a GtkWindow before the
|
|
* GtkWindow is shown. The geometry is passed in as a string.
|
|
* It is an error to call this on a window that
|
|
* is already on-screen. Takes into account screen size, and does
|
|
* some sanity-checking on the passed-in values.
|
|
*
|
|
* @window: A non-visible GtkWindow
|
|
* @geometry_string: A string suitable for use with gnome_parse_geometry
|
|
* @minimum_width: If the width from the string is smaller than this,
|
|
* use this for the width.
|
|
* @minimum_height: If the height from the string is smaller than this,
|
|
* use this for the height.
|
|
*/
|
|
void
|
|
nautilus_gtk_window_set_initial_geometry_from_string (GtkWindow *window,
|
|
const char *geometry_string,
|
|
guint minimum_width,
|
|
guint minimum_height)
|
|
{
|
|
int left, top, width, height;
|
|
gboolean parsed;
|
|
|
|
g_return_if_fail (GTK_IS_WINDOW (window));
|
|
g_return_if_fail (geometry_string != NULL);
|
|
|
|
/* Setting the default size doesn't work when the window is already showing.
|
|
* Someday we could make this move an already-showing window, but we don't
|
|
* need that functionality yet.
|
|
*/
|
|
g_return_if_fail (!GTK_WIDGET_VISIBLE (window));
|
|
|
|
parsed = gnome_parse_geometry (geometry_string, &left, &top, &width, &height);
|
|
|
|
/* Bogus string, dude. */
|
|
g_return_if_fail (parsed);
|
|
|
|
/* Make sure the window isn't smaller than makes sense for this window.
|
|
* Other sanity checks are performed in set_initial_geometry.
|
|
*/
|
|
width = MAX (width, minimum_width);
|
|
height = MAX (height, minimum_height);
|
|
|
|
nautilus_gtk_window_set_initial_geometry (window, left, top, width, height);
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_selection_data_copy_deep:
|
|
*
|
|
* Copies a GtkSelectionData, and copies the data too.
|
|
* @data: The GtkSelectionData to be copied.
|
|
**/
|
|
GtkSelectionData *
|
|
nautilus_gtk_selection_data_copy_deep (const GtkSelectionData *data)
|
|
{
|
|
GtkSelectionData *copy;
|
|
|
|
copy = g_new0 (GtkSelectionData, 1);
|
|
gtk_selection_data_set (copy, data->type, data->format, data->data, data->length);
|
|
|
|
return copy;
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_selection_data_free_deep:
|
|
*
|
|
* Frees a GtkSelectionData, and frees the data too.
|
|
* @data: The GtkSelectionData to be freed.
|
|
**/
|
|
void
|
|
nautilus_gtk_selection_data_free_deep (GtkSelectionData *data)
|
|
{
|
|
g_free (data->data);
|
|
gtk_selection_data_free (data);
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_signal_connect_free_data:
|
|
*
|
|
* Function to displace the popup menu some, otherwise the first item
|
|
* gets selected right away.
|
|
* This function gets called by gtk_menu_popup ().
|
|
*
|
|
* @menu: the popup menu.
|
|
* @x: x coord where gtk want to place the menu
|
|
* @y: y coord where gtk want to place the menu
|
|
* @user_data: something
|
|
**/
|
|
static void
|
|
nautilus_popup_menu_position_func (GtkMenu *menu,
|
|
int *x,
|
|
int *y,
|
|
gpointer user_data)
|
|
{
|
|
GdkPoint *offset;
|
|
GtkRequisition requisition;
|
|
|
|
g_assert (x != NULL);
|
|
g_assert (y != NULL);
|
|
|
|
offset = (GdkPoint*) user_data;
|
|
|
|
g_assert (offset != NULL);
|
|
|
|
/*
|
|
* FIXME bugzilla.eazel.com 2561: The cast from gint16 might cause problems.
|
|
* Unfortunately, GdkPoint uses gint16.
|
|
*/
|
|
gtk_widget_size_request (GTK_WIDGET (menu), &requisition);
|
|
|
|
*x = CLAMP (*x + (int) offset->x, 0, MAX (0, gdk_screen_width () - requisition.width));
|
|
*y = CLAMP (*y + (int) offset->y, 0, MAX (0, gdk_screen_height () - requisition.height));
|
|
}
|
|
|
|
/**
|
|
* nautilus_truncate_text_for_menu_item:
|
|
*
|
|
* Given an arbitrary string, returns a newly-allocated string
|
|
* suitable for use as a menu item label. Truncates long strings
|
|
* in the middle.
|
|
*/
|
|
char *
|
|
nautilus_truncate_text_for_menu_item (const char *text)
|
|
{
|
|
return nautilus_str_middle_truncate (text, MAXIMUM_MENU_TITLE_LENGTH);
|
|
}
|
|
|
|
/**
|
|
* nautilus_pop_up_context_menu:
|
|
*
|
|
* Pop up a context menu under the mouse.
|
|
* The menu is sunk after use, so it will be destroyed unless the
|
|
* caller first ref'ed it.
|
|
*
|
|
* This function is more of a helper function than a gtk extension,
|
|
* so perhaps it belongs in a different file.
|
|
*
|
|
* When calling from a callback other than button_press, make sure to pass
|
|
* 0 for button because otherwise the first button click after the button came
|
|
* up would not be handled properly (a subtle fragility of gtk_menu_popup).
|
|
*
|
|
* @menu: The menu to pop up under the mouse.
|
|
* @offset_x: Number of pixels to displace the popup menu vertically
|
|
* @offset_y: Number of pixels to displace the popup menu horizontally
|
|
* @button: current button if called from button_press.
|
|
**/
|
|
void
|
|
nautilus_pop_up_context_menu (GtkMenu *menu,
|
|
gint16 offset_x,
|
|
gint16 offset_y,
|
|
int button)
|
|
{
|
|
GdkPoint offset;
|
|
|
|
g_return_if_fail (GTK_IS_MENU (menu));
|
|
|
|
offset.x = offset_x;
|
|
offset.y = offset_y;
|
|
|
|
/* We pass current time here instead of extracting it from
|
|
* the event, for API simplicity. This does not seem to make
|
|
* any practical difference. See man XGrabPointer for details.
|
|
*/
|
|
gtk_menu_popup (menu, /* menu */
|
|
NULL, /* parent_menu_shell */
|
|
NULL, /* parent_menu_item */
|
|
nautilus_popup_menu_position_func, /* func */
|
|
&offset, /* data */
|
|
button, /* button */
|
|
GDK_CURRENT_TIME); /* activate_time */
|
|
|
|
gtk_object_sink (GTK_OBJECT(menu));
|
|
}
|
|
|
|
GtkMenuItem *
|
|
nautilus_gtk_menu_append_separator (GtkMenu *menu)
|
|
{
|
|
return nautilus_gtk_menu_insert_separator (menu, -1);
|
|
}
|
|
|
|
GtkMenuItem *
|
|
nautilus_gtk_menu_insert_separator (GtkMenu *menu, int index)
|
|
{
|
|
GtkWidget *menu_item;
|
|
|
|
menu_item = gtk_menu_item_new ();
|
|
gtk_widget_set_sensitive (menu_item, FALSE);
|
|
gtk_widget_show (menu_item);
|
|
gtk_menu_insert (menu, menu_item, index);
|
|
|
|
return GTK_MENU_ITEM (menu_item);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_menu_set_item_visibility (GtkMenu *menu, int index, gboolean visible)
|
|
{
|
|
GList *children;
|
|
GtkWidget *menu_item;
|
|
|
|
g_return_if_fail (GTK_IS_MENU (menu));
|
|
|
|
children = gtk_container_children (GTK_CONTAINER (menu));
|
|
g_return_if_fail (index >= 0 && index < g_list_length (children));
|
|
|
|
menu_item = GTK_WIDGET (g_list_nth_data (children, index));
|
|
if (visible) {
|
|
gtk_widget_show (menu_item);
|
|
} else {
|
|
gtk_widget_hide (menu_item);
|
|
}
|
|
|
|
g_list_free (children);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_NONE__POINTER_INT_INT_DOUBLE (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
(* (void (*)(GtkObject *, gpointer, int, int, double, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_POINTER (args[0]),
|
|
GTK_VALUE_INT (args[1]),
|
|
GTK_VALUE_INT (args[2]),
|
|
GTK_VALUE_DOUBLE (args[3]),
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_NONE__INT_INT_INT (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
(* (void (*)(GtkObject *, int, int, int, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_INT (args[0]),
|
|
GTK_VALUE_INT (args[1]),
|
|
GTK_VALUE_INT (args[2]),
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_NONE__POINTER_INT_INT_INT (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
(* (void (*)(GtkObject *, gpointer, int, int, int, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_POINTER (args[0]),
|
|
GTK_VALUE_INT (args[1]),
|
|
GTK_VALUE_INT (args[2]),
|
|
GTK_VALUE_INT (args[3]),
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_NONE__POINTER_INT_POINTER_POINTER (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
(* (void (*)(GtkObject *, gpointer, int, gpointer, gpointer, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_POINTER (args[0]),
|
|
GTK_VALUE_INT (args[1]),
|
|
GTK_VALUE_POINTER (args[2]),
|
|
GTK_VALUE_POINTER (args[3]),
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_NONE__POINTER_POINTER_INT_INT_INT (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
(* (void (*)(GtkObject *, gpointer, gpointer, int, int, int, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_POINTER (args[0]),
|
|
GTK_VALUE_POINTER (args[1]),
|
|
GTK_VALUE_INT (args[2]),
|
|
GTK_VALUE_INT (args[3]),
|
|
GTK_VALUE_INT (args[4]),
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_BOOL__INT_POINTER_INT_INT_UINT (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
* GTK_RETLOC_BOOL (args[5]) = (* (gboolean (*)(GtkObject *, int, gpointer, int, int, guint, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_INT (args[0]),
|
|
GTK_VALUE_POINTER (args[1]),
|
|
GTK_VALUE_INT (args[2]),
|
|
GTK_VALUE_INT (args[3]),
|
|
GTK_VALUE_UINT (args[4]),
|
|
func_data);
|
|
}
|
|
|
|
|
|
void
|
|
nautilus_gtk_marshal_NONE__INT_POINTER_INT_INT_UINT (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
(* (void (*)(GtkObject *, int, gpointer, int, int, guint, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_INT (args[0]),
|
|
GTK_VALUE_POINTER (args[1]),
|
|
GTK_VALUE_INT (args[2]),
|
|
GTK_VALUE_INT (args[3]),
|
|
GTK_VALUE_UINT (args[4]),
|
|
func_data);
|
|
|
|
}
|
|
|
|
|
|
void
|
|
nautilus_gtk_marshal_NONE__POINTER_POINTER_POINTER_INT_INT_INT (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
(* (void (*)(GtkObject *, gpointer, gpointer, gpointer, int, int, int, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_POINTER (args[0]),
|
|
GTK_VALUE_POINTER (args[1]),
|
|
GTK_VALUE_POINTER (args[2]),
|
|
GTK_VALUE_INT (args[3]),
|
|
GTK_VALUE_INT (args[4]),
|
|
GTK_VALUE_INT (args[5]),
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_NONE__POINTER_POINTER_POINTER_POINTER_INT_INT_UINT (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
(* (void (*)(GtkObject *, gpointer, gpointer, gpointer, gpointer, int, int, guint, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_POINTER (args[0]),
|
|
GTK_VALUE_POINTER (args[1]),
|
|
GTK_VALUE_POINTER (args[2]),
|
|
GTK_VALUE_POINTER (args[3]),
|
|
GTK_VALUE_INT (args[4]),
|
|
GTK_VALUE_INT (args[5]),
|
|
GTK_VALUE_INT (args[6]),
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_NONE__POINTER_INT_INT_DOUBLE_DOUBLE (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
(* (void (*)(GtkObject *, gpointer, int, int, double, double, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_POINTER (args[0]),
|
|
GTK_VALUE_INT (args[1]),
|
|
GTK_VALUE_INT (args[2]),
|
|
GTK_VALUE_DOUBLE (args[3]),
|
|
GTK_VALUE_DOUBLE (args[4]),
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_NONE__DOUBLE (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
(* (void (*)(GtkObject *, double, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_DOUBLE (args[0]),
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_NONE__DOUBLE_DOUBLE_DOUBLE (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
(* (void (*)(GtkObject *, double, double, double, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_DOUBLE (args[0]),
|
|
GTK_VALUE_DOUBLE (args[1]),
|
|
GTK_VALUE_DOUBLE (args[2]),
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_POINTER__NONE (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
* GTK_RETLOC_POINTER (args[0]) =
|
|
(* (void * (*)(GtkObject *, gpointer)) func)
|
|
(object,
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_INT__NONE (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
* GTK_RETLOC_INT (args[0]) =
|
|
(* (int (*)(GtkObject *, gpointer)) func)
|
|
(object,
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_POINTER__POINTER (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
* GTK_RETLOC_POINTER (args[1]) =
|
|
(* (gpointer (*)(GtkObject *, gpointer, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_POINTER (args[0]),
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_INT__POINTER_POINTER (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
* GTK_RETLOC_INT (args[2]) =
|
|
(* (int (*)(GtkObject *, gpointer, gpointer, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_POINTER (args[0]),
|
|
GTK_VALUE_POINTER (args[1]),
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_INT__POINTER_INT (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
* GTK_RETLOC_INT (args[2]) =
|
|
(* (int (*)(GtkObject *, gpointer, int, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_POINTER (args[0]),
|
|
GTK_VALUE_INT (args[1]),
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_POINTER__POINTER_POINTER (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
* GTK_RETLOC_POINTER (args[2]) =
|
|
(* (gpointer (*)(GtkObject *, gpointer, gpointer, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_POINTER (args[0]),
|
|
GTK_VALUE_POINTER (args[1]),
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_POINTER__POINTER_POINTER_POINTER (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
* GTK_RETLOC_POINTER (args[3]) =
|
|
(* (gpointer (*)(GtkObject *, gpointer, gpointer, gpointer, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_POINTER (args[0]),
|
|
GTK_VALUE_POINTER (args[1]),
|
|
GTK_VALUE_POINTER (args[2]),
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_NONE__POINTER_POINTER_POINTER (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
(* (void (*)(GtkObject *, gpointer, gpointer, gpointer, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_POINTER (args[0]),
|
|
GTK_VALUE_POINTER (args[1]),
|
|
GTK_VALUE_POINTER (args[2]),
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_POINTER__POINTER_INT_INT_POINTER_POINTER (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
* GTK_RETLOC_POINTER (args[5]) =
|
|
(* (gpointer (*)(GtkObject *, gpointer, int, int, gpointer, gpointer, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_POINTER (args[0]),
|
|
GTK_VALUE_INT (args[1]),
|
|
GTK_VALUE_INT (args[2]),
|
|
GTK_VALUE_POINTER (args[3]),
|
|
GTK_VALUE_POINTER (args[4]),
|
|
func_data);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_marshal_NONE__POINTER_POINTER_POINTER_POINTER_POINTER_POINTER (GtkObject *object,
|
|
GtkSignalFunc func,
|
|
gpointer func_data,
|
|
GtkArg *args)
|
|
{
|
|
(* (void (*)(GtkObject *, gpointer, gpointer, gpointer,
|
|
gpointer, gpointer, gpointer, gpointer)) func)
|
|
(object,
|
|
GTK_VALUE_POINTER (args[0]),
|
|
GTK_VALUE_POINTER (args[1]),
|
|
GTK_VALUE_POINTER (args[2]),
|
|
GTK_VALUE_POINTER (args[3]),
|
|
GTK_VALUE_POINTER (args[4]),
|
|
GTK_VALUE_POINTER (args[5]),
|
|
func_data);
|
|
}
|
|
|
|
gboolean
|
|
nautilus_point_in_allocation (const GtkAllocation *allocation,
|
|
int x, int y)
|
|
{
|
|
g_return_val_if_fail (allocation != NULL, FALSE);
|
|
return x >= allocation->x
|
|
&& y >= allocation->y
|
|
&& x < allocation->x + allocation->width
|
|
&& y < allocation->y + allocation->height;
|
|
}
|
|
|
|
gboolean
|
|
nautilus_point_in_widget (GtkWidget *widget,
|
|
int x, int y)
|
|
{
|
|
if (widget == NULL) {
|
|
return FALSE;
|
|
}
|
|
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
|
|
return nautilus_point_in_allocation (&widget->allocation, x, y);
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_object_list_ref
|
|
*
|
|
* Ref all the objects in a list.
|
|
* @list: GList of objects.
|
|
**/
|
|
GList *
|
|
nautilus_gtk_object_list_ref (GList *list)
|
|
{
|
|
g_list_foreach (list, (GFunc) gtk_object_ref, NULL);
|
|
return list;
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_object_list_unref
|
|
*
|
|
* Unref all the objects in a list.
|
|
* @list: GList of objects.
|
|
**/
|
|
void
|
|
nautilus_gtk_object_list_unref (GList *list)
|
|
{
|
|
nautilus_g_list_safe_for_each (list, (GFunc) gtk_object_unref, NULL);
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_object_list_free
|
|
*
|
|
* Free a list of objects after unrefing them.
|
|
* @list: GList of objects.
|
|
**/
|
|
void
|
|
nautilus_gtk_object_list_free (GList *list)
|
|
{
|
|
nautilus_gtk_object_list_unref (list);
|
|
g_list_free (list);
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_object_list_copy
|
|
*
|
|
* Copy the list of objects, ref'ing each one.
|
|
* @list: GList of objects.
|
|
**/
|
|
GList *
|
|
nautilus_gtk_object_list_copy (GList *list)
|
|
{
|
|
return g_list_copy (nautilus_gtk_object_list_ref (list));
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_style_set_font
|
|
*
|
|
* Sets the font in a style object, managing the ref. counts.
|
|
* @style: The style to change.
|
|
* @font: The new font.
|
|
**/
|
|
void
|
|
nautilus_gtk_style_set_font (GtkStyle *style, GdkFont *font)
|
|
{
|
|
g_return_if_fail (style != NULL);
|
|
g_return_if_fail (font != NULL);
|
|
|
|
gdk_font_ref (font);
|
|
gdk_font_unref (style->font);
|
|
style->font = font;
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_widget_set_font
|
|
*
|
|
* Sets the font for a widget's style, managing the style objects.
|
|
* @widget: The widget.
|
|
* @font: The font.
|
|
**/
|
|
void
|
|
nautilus_gtk_widget_set_font (GtkWidget *widget, GdkFont *font)
|
|
{
|
|
GtkStyle *new_style;
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
g_return_if_fail (font != NULL);
|
|
|
|
new_style = gtk_style_copy (gtk_widget_get_style (widget));
|
|
|
|
nautilus_gtk_style_set_font (new_style, font);
|
|
|
|
gtk_widget_set_style (widget, new_style);
|
|
gtk_style_unref (new_style);
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_widget_set_font_by_name
|
|
*
|
|
* Sets the font for a widget, managing the font and style objects.
|
|
* @widget: The widget
|
|
**/
|
|
void
|
|
nautilus_gtk_widget_set_font_by_name (GtkWidget *widget, const char *font_name)
|
|
{
|
|
GdkFont *font;
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
g_return_if_fail (font_name != NULL);
|
|
|
|
font = gdk_fontset_load (font_name);
|
|
nautilus_gtk_widget_set_font (widget, font);
|
|
gdk_font_unref (font);
|
|
}
|
|
|
|
/* This stuff is stolen from Gtk. */
|
|
|
|
typedef struct DisconnectInfo {
|
|
GtkObject *object1;
|
|
guint disconnect_handler1;
|
|
guint signal_handler;
|
|
GtkObject *object2;
|
|
guint disconnect_handler2;
|
|
} DisconnectInfo;
|
|
|
|
static guint
|
|
alive_disconnecter (GtkObject *object, DisconnectInfo *info)
|
|
{
|
|
g_assert (info != NULL);
|
|
g_assert (GTK_IS_OBJECT (info->object1));
|
|
g_assert (info->disconnect_handler1 != 0);
|
|
g_assert (info->signal_handler != 0);
|
|
g_assert (GTK_IS_OBJECT (info->object2));
|
|
g_assert (info->disconnect_handler2 != 0);
|
|
g_assert (object == info->object1 || object == info->object2);
|
|
|
|
gtk_signal_disconnect (info->object1, info->disconnect_handler1);
|
|
gtk_signal_disconnect (info->object1, info->signal_handler);
|
|
gtk_signal_disconnect (info->object2, info->disconnect_handler2);
|
|
|
|
g_free (info);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_signal_connect_full_while_alive
|
|
*
|
|
* Like gtk_signal_connect_while_alive, but works with full parameters.
|
|
**/
|
|
void
|
|
nautilus_gtk_signal_connect_full_while_alive (GtkObject *object,
|
|
const gchar *name,
|
|
GtkSignalFunc func,
|
|
GtkCallbackMarshal marshal,
|
|
gpointer data,
|
|
GtkDestroyNotify destroy_func,
|
|
gboolean object_signal,
|
|
gboolean after,
|
|
GtkObject *alive_object)
|
|
{
|
|
DisconnectInfo *info;
|
|
|
|
g_return_if_fail (GTK_IS_OBJECT (object));
|
|
g_return_if_fail (name != NULL);
|
|
g_return_if_fail (func != NULL);
|
|
g_return_if_fail (object_signal == FALSE || object_signal == TRUE);
|
|
g_return_if_fail (after == FALSE || after == TRUE);
|
|
g_return_if_fail (GTK_IS_OBJECT (alive_object));
|
|
|
|
info = g_new (DisconnectInfo, 1);
|
|
info->object1 = object;
|
|
info->object2 = alive_object;
|
|
|
|
info->signal_handler =
|
|
gtk_signal_connect_full (object,
|
|
name,
|
|
func,
|
|
marshal,
|
|
data,
|
|
destroy_func,
|
|
object_signal,
|
|
after);
|
|
|
|
info->disconnect_handler1 =
|
|
gtk_signal_connect (object,
|
|
"destroy",
|
|
GTK_SIGNAL_FUNC (alive_disconnecter),
|
|
info);
|
|
info->disconnect_handler2 =
|
|
gtk_signal_connect (alive_object,
|
|
"destroy",
|
|
GTK_SIGNAL_FUNC (alive_disconnecter),
|
|
info);
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_container_get_first_child.
|
|
*
|
|
* Returns the first child of a container.
|
|
* @container: The container.
|
|
**/
|
|
|
|
static void
|
|
get_first_callback (GtkWidget *widget, gpointer callback_data)
|
|
{
|
|
GtkWidget **first_child_slot;
|
|
|
|
g_assert (GTK_IS_WIDGET (widget));
|
|
g_assert (callback_data != NULL);
|
|
|
|
first_child_slot = callback_data;
|
|
|
|
if (*first_child_slot == NULL) {
|
|
*first_child_slot = widget;
|
|
/* We'd stop the iterating now if we could. */
|
|
} else {
|
|
g_assert (GTK_IS_WIDGET (*first_child_slot));
|
|
}
|
|
}
|
|
|
|
GtkWidget *
|
|
nautilus_gtk_container_get_first_child (GtkContainer *container)
|
|
{
|
|
GtkWidget *first_child;
|
|
|
|
g_return_val_if_fail (GTK_IS_CONTAINER (container), NULL);
|
|
|
|
first_child = NULL;
|
|
gtk_container_foreach (container, get_first_callback, &first_child);
|
|
g_assert (first_child == NULL || GTK_IS_WIDGET (first_child));
|
|
return first_child;
|
|
}
|
|
|
|
/* We have to supply a dummy pixmap to avoid the return_if_fail in gtk_pixmap_new. */
|
|
GtkPixmap *
|
|
nautilus_gtk_pixmap_new_empty (void)
|
|
{
|
|
GtkPixmap *pixmap;
|
|
|
|
/* Make a GtkPixmap with a dummy GdkPixmap. The
|
|
* gdk_pixmap_new call will fail if passed 0 for height or
|
|
* width, or if passed a bad depth.
|
|
*/
|
|
pixmap = GTK_PIXMAP (gtk_pixmap_new (gdk_pixmap_new (NULL, 1, 1, gdk_visual_get_best_depth ()), NULL));
|
|
|
|
/* Clear out the dummy pixmap. */
|
|
gtk_pixmap_set (pixmap, NULL, NULL);
|
|
|
|
return pixmap;
|
|
}
|
|
|
|
/* The standard gtk_adjustment_set_value ignores page size, which
|
|
* disagrees with the logic used by scroll bars, for example.
|
|
*/
|
|
void
|
|
nautilus_gtk_adjustment_set_value (GtkAdjustment *adjustment,
|
|
float value)
|
|
{
|
|
float upper_page_start, clamped_value;
|
|
|
|
g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
|
|
|
|
upper_page_start = MAX (adjustment->upper - adjustment->page_size, adjustment->lower);
|
|
clamped_value = CLAMP (value, adjustment->lower, upper_page_start);
|
|
if (clamped_value != adjustment->value) {
|
|
adjustment->value = clamped_value;
|
|
gtk_adjustment_value_changed (adjustment);
|
|
}
|
|
}
|
|
|
|
/* Clamp a value if the minimum or maximum has changed. */
|
|
void
|
|
nautilus_gtk_adjustment_clamp_value (GtkAdjustment *adjustment)
|
|
{
|
|
g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
|
|
|
|
nautilus_gtk_adjustment_set_value (adjustment, adjustment->value);
|
|
}
|
|
|
|
/**
|
|
* nautilus_gtk_label_make_bold.
|
|
*
|
|
* Switches the font of label to a bold equivalent.
|
|
* @label: The label.
|
|
**/
|
|
|
|
void
|
|
nautilus_gtk_label_make_bold (GtkLabel *label)
|
|
{
|
|
GtkStyle *style;
|
|
GdkFont *bold_font;
|
|
|
|
g_return_if_fail (GTK_IS_LABEL (label));
|
|
|
|
style = gtk_widget_get_style (GTK_WIDGET (label));
|
|
|
|
bold_font = nautilus_gdk_font_get_bold (style->font);
|
|
if (bold_font == NULL) {
|
|
return;
|
|
}
|
|
nautilus_gtk_widget_set_font (GTK_WIDGET (label), bold_font);
|
|
gdk_font_unref (bold_font);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_widget_set_background_color (GtkWidget *widget,
|
|
const char *color_spec)
|
|
{
|
|
GtkStyle *style;
|
|
GdkColor color;
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
style = gtk_widget_get_style (widget);
|
|
|
|
/* Make a copy of the style. */
|
|
style = gtk_style_copy (style);
|
|
|
|
nautilus_gdk_color_parse_with_white_default (color_spec, &color);
|
|
style->bg[GTK_STATE_NORMAL] = color;
|
|
style->base[GTK_STATE_NORMAL] = color;
|
|
style->bg[GTK_STATE_ACTIVE] = color;
|
|
style->base[GTK_STATE_ACTIVE] = color;
|
|
|
|
/* Put the style in the widget. */
|
|
gtk_widget_set_style (widget, style);
|
|
gtk_style_unref (style);
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_widget_set_foreground_color (GtkWidget *widget,
|
|
const char *color_spec)
|
|
{
|
|
GtkStyle *style;
|
|
GdkColor color;
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
style = gtk_widget_get_style (widget);
|
|
|
|
/* Make a copy of the style. */
|
|
style = gtk_style_copy (style);
|
|
|
|
nautilus_gdk_color_parse_with_white_default (color_spec, &color);
|
|
style->fg[GTK_STATE_NORMAL] = color;
|
|
style->fg[GTK_STATE_ACTIVE] = color;
|
|
|
|
/* Put the style in the widget. */
|
|
gtk_widget_set_style (widget, style);
|
|
gtk_style_unref (style);
|
|
}
|
|
|
|
GtkWidget *
|
|
nautilus_gtk_widget_find_windowed_ancestor (GtkWidget *widget)
|
|
{
|
|
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
|
|
|
|
while (widget && GTK_WIDGET_NO_WINDOW (widget)) {
|
|
widget = widget->parent;
|
|
}
|
|
|
|
return widget;
|
|
}
|
|
|
|
|
|
|
|
/*following code shamelessly stolen from gtk*/
|
|
static void
|
|
rgb_to_hls (gdouble *r,
|
|
gdouble *g,
|
|
gdouble *b)
|
|
{
|
|
gdouble min;
|
|
gdouble max;
|
|
gdouble red;
|
|
gdouble green;
|
|
gdouble blue;
|
|
gdouble h, l, s;
|
|
gdouble delta;
|
|
|
|
red = *r;
|
|
green = *g;
|
|
blue = *b;
|
|
|
|
if (red > green) {
|
|
if (red > blue)
|
|
max = red;
|
|
else
|
|
max = blue;
|
|
|
|
if (green < blue)
|
|
min = green;
|
|
else
|
|
min = blue;
|
|
} else {
|
|
if (green > blue)
|
|
max = green;
|
|
else
|
|
max = blue;
|
|
|
|
if (red < blue)
|
|
min = red;
|
|
else
|
|
min = blue;
|
|
}
|
|
|
|
l = (max + min) / 2;
|
|
s = 0;
|
|
h = 0;
|
|
|
|
if (max != min) {
|
|
if (l <= 0.5)
|
|
s = (max - min) / (max + min);
|
|
else
|
|
s = (max - min) / (2 - max - min);
|
|
|
|
delta = max -min;
|
|
if (red == max)
|
|
h = (green - blue) / delta;
|
|
else if (green == max)
|
|
h = 2 + (blue - red) / delta;
|
|
else if (blue == max)
|
|
h = 4 + (red - green) / delta;
|
|
|
|
h *= 60;
|
|
if (h < 0.0)
|
|
h += 360;
|
|
}
|
|
|
|
*r = h;
|
|
*g = l;
|
|
*b = s;
|
|
}
|
|
|
|
static void
|
|
hls_to_rgb (gdouble *h,
|
|
gdouble *l,
|
|
gdouble *s)
|
|
{
|
|
gdouble hue;
|
|
gdouble lightness;
|
|
gdouble saturation;
|
|
gdouble m1, m2;
|
|
gdouble r, g, b;
|
|
|
|
lightness = *l;
|
|
saturation = *s;
|
|
|
|
if (lightness <= 0.5)
|
|
m2 = lightness * (1 + saturation);
|
|
else
|
|
m2 = lightness + saturation - lightness * saturation;
|
|
m1 = 2 * lightness - m2;
|
|
|
|
if (saturation == 0) {
|
|
*h = lightness;
|
|
*l = lightness;
|
|
*s = lightness;
|
|
} else {
|
|
hue = *h + 120;
|
|
while (hue > 360)
|
|
hue -= 360;
|
|
while (hue < 0)
|
|
hue += 360;
|
|
|
|
if (hue < 60)
|
|
r = m1 + (m2 - m1) * hue / 60;
|
|
else if (hue < 180)
|
|
r = m2;
|
|
else if (hue < 240)
|
|
r = m1 + (m2 - m1) * (240 - hue) / 60;
|
|
else
|
|
r = m1;
|
|
|
|
hue = *h;
|
|
while (hue > 360)
|
|
hue -= 360;
|
|
while (hue < 0)
|
|
hue += 360;
|
|
|
|
if (hue < 60)
|
|
g = m1 + (m2 - m1) * hue / 60;
|
|
else if (hue < 180)
|
|
g = m2;
|
|
else if (hue < 240)
|
|
g = m1 + (m2 - m1) * (240 - hue) / 60;
|
|
else
|
|
g = m1;
|
|
|
|
hue = *h - 120;
|
|
while (hue > 360)
|
|
hue -= 360;
|
|
while (hue < 0)
|
|
hue += 360;
|
|
|
|
if (hue < 60)
|
|
b = m1 + (m2 - m1) * hue / 60;
|
|
else if (hue < 180)
|
|
b = m2;
|
|
else if (hue < 240)
|
|
b = m1 + (m2 - m1) * (240 - hue) / 60;
|
|
else
|
|
b = m1;
|
|
|
|
*h = r;
|
|
*l = g;
|
|
*s = b;
|
|
}
|
|
}
|
|
|
|
void
|
|
nautilus_gtk_style_shade (GdkColor *a,
|
|
GdkColor *b,
|
|
gdouble k)
|
|
{
|
|
|
|
gdouble red;
|
|
gdouble green;
|
|
gdouble blue;
|
|
|
|
red = (gdouble) a->red / 65535.0;
|
|
green = (gdouble) a->green / 65535.0;
|
|
blue = (gdouble) a->blue / 65535.0;
|
|
|
|
rgb_to_hls (&red, &green, &blue);
|
|
|
|
green *= k;
|
|
if (green > 1.0)
|
|
green = 1.0;
|
|
else if (green < 0.0)
|
|
green = 0.0;
|
|
|
|
blue *= k;
|
|
if (blue > 1.0)
|
|
blue = 1.0;
|
|
else if (blue < 0.0)
|
|
blue = 0.0;
|
|
|
|
hls_to_rgb (&red, &green, &blue);
|
|
|
|
b->red = red * 65535.0;
|
|
b->green = green * 65535.0;
|
|
b->blue = blue * 65535.0;
|
|
}
|