gimp/app/widgets/gimpwidgets-utils.c

656 lines
17 KiB
C
Raw Normal View History

app/Makefile.am app/gimphelp.[ch] new files 1999-09-27 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/gimphelp.[ch] * app/gimpui.[ch]: new files * app/interface.[ch] * app/preferences_dialog.[ch] The GIMP Help System part 1: Press "F1" in any dialog to pop up the help page for this dialog. Moved the widget constructors from preferences_dialog.[ch] and the query boxes from interface.[ch] to gimpui.[ch]. The dialog constructors take a help_func and a help_data parameter and install the "F1" accelerator which emits the new "help" signal. The "help" signal callback calls help_func(help_data) which finally has to call gimp_help() which in turn invokes the help browser. Still have to find a proper way to (1) prevent "F1" being assigned to some menu item and (2) to catch "F1" while browsing the menu trees in order to pop up the help for the selected item. * app/menus.c: a <Toolbox>/File/Help... menu item. * app/commands.[ch]: a command callback for the "Help..." menu item. * app/gimprc.[ch]: new boolean gimprc variable "use_help". * app/info_dialog.[ch]: pass a help function and data to the info dialog constructor. * app/tools.[ch]: store the tools help page names in the tool info structure. Export a special tools_help_func() which shows the help page for the active tool. * app/[all files calling a dialog constructor]: pass the dialog's help page to the constructor. Most dialogs are now created by gimp_dialog_new() which also sets up the action_area and the WM delete event callback, so I removed the resp. code from these files. Fixed some minor bugs and did some other stuff but didn't change any logic except dialog creation. * plug-ins/helpbrowser/helpbrowser.c: don't try to call a running help browser and don't install any menu path (all done in app/gimphelp.[ch] now).
1999-09-27 17:58:10 +00:00
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpwidgets-utils.c
* Copyright (C) 1999-2003 Michael Natterer <mitch@gimp.org>
app/Makefile.am app/gimphelp.[ch] new files 1999-09-27 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/gimphelp.[ch] * app/gimpui.[ch]: new files * app/interface.[ch] * app/preferences_dialog.[ch] The GIMP Help System part 1: Press "F1" in any dialog to pop up the help page for this dialog. Moved the widget constructors from preferences_dialog.[ch] and the query boxes from interface.[ch] to gimpui.[ch]. The dialog constructors take a help_func and a help_data parameter and install the "F1" accelerator which emits the new "help" signal. The "help" signal callback calls help_func(help_data) which finally has to call gimp_help() which in turn invokes the help browser. Still have to find a proper way to (1) prevent "F1" being assigned to some menu item and (2) to catch "F1" while browsing the menu trees in order to pop up the help for the selected item. * app/menus.c: a <Toolbox>/File/Help... menu item. * app/commands.[ch]: a command callback for the "Help..." menu item. * app/gimprc.[ch]: new boolean gimprc variable "use_help". * app/info_dialog.[ch]: pass a help function and data to the info dialog constructor. * app/tools.[ch]: store the tools help page names in the tool info structure. Export a special tools_help_func() which shows the help page for the active tool. * app/[all files calling a dialog constructor]: pass the dialog's help page to the constructor. Most dialogs are now created by gimp_dialog_new() which also sets up the action_area and the WM delete event callback, so I removed the resp. code from these files. Fixed some minor bugs and did some other stuff but didn't change any logic except dialog creation. * plug-ins/helpbrowser/helpbrowser.c: don't try to call a running help browser and don't install any menu path (all done in app/gimphelp.[ch] now).
1999-09-27 17:58:10 +00:00
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
2000-02-02 01:21:36 +00:00
#include <string.h>
2000-02-02 01:21:36 +00:00
#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
#include "libgimpcolor/gimpcolor.h"
Makefile.am configure.in added the new library below. 2001-01-24 Michael Natterer <mitch@gimp.org> * Makefile.am * configure.in * gimptool.in: added the new library below. * libgimpwidgets/Makefile.am * libgimpwidgets/gimpchainbutton.[ch] * libgimpwidgets/gimpcolorarea.[ch] * libgimpwidgets/gimpcolorbutton.[ch] * libgimpwidgets/gimpdialog.[ch] * libgimpwidgets/gimpfileselection.[ch] * libgimpwidgets/gimphelpui.[ch] * libgimpwidgets/gimppatheditor.[ch] * libgimpwidgets/gimppixmap.[ch] * libgimpwidgets/gimpquerybox.[ch] * libgimpwidgets/gimpsizeentry.[ch] * libgimpwidgets/gimpunitmenu.[ch] * libgimpwidgets/gimpwidgets.[ch] * libgimpwidgets/gimpwidgets.def * libgimpwidgets/gimpwidgetstypes.h: new shared library. Currently there are some ugly dependencies into libgimp. These will be removed and go to a "libgimpglue" library which will be a library for functions which share a common interface between plug-ins and the app but have different implementations. Include "libgimp/gimpunit.h" from "libgimpwidgets/gimpwidgetstypes.h" to simulate this upcoming separation. * libgimp/Makefile.am * libgimp/gimpchainbutton.[ch] * libgimp/gimpcolorarea.[ch] * libgimp/gimpcolorbutton.[ch] * libgimp/gimpdialog.[ch] * libgimp/gimpfileselection.[ch] * libgimp/gimphelpui.[ch] * libgimp/gimppatheditor.[ch] * libgimp/gimppixmap.[ch] * libgimp/gimpquerybox.[ch] * libgimp/gimpsizeentry.[ch] * libgimp/gimpunitmenu.[ch] * libgimp/gimpwidgets.[ch]: removed from here. * libgimp/gimpui.h * libgimp/gimpuitypes.h * libgimp/makefile.mingw.in * libgimp/makefile.msc: changed accordingly. * app/[all ui files] * app/pdb/palette_cmds.c * app/pdb/tools_cmds.c * tools/pdbgen/pdb/palette.pdb * tools/pdbgen/pdb/tools.pdb: #include "libgimpwidgets/gimpwidgets.h" and removed useless includes. * app/apptypes.h: #include "libgimpwidgets/gimpwidgetstypes.h" * app/Makefile.am * plug-ins/[all makefiles which link against libgimpui]: link against libgimpwidgets.la * po-libgimp/POTFILES.in: changed file locations.
2001-01-24 22:36:18 +00:00
#include "libgimpwidgets/gimpwidgets.h"
#include "widgets-types.h"
app/Makefile.am app/channel_pvt.h app/drawable_pvt.h app/gdisplayF.h 2000-12-29 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/channel_pvt.h * app/drawable_pvt.h * app/gdisplayF.h * app/gimpdrawableP.h * app/gimpimageP.h * app/layer_pvt.h * app/toolsF.h: removed these files. * app/apptypes.h * tools/pdbgen/enums.pl: added tons of opaque typedefs and enums. * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/channel.pdb * tools/pdbgen/pdb/color.pdb * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/display.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/fileops.pdb * tools/pdbgen/pdb/gradient_select.pdb * tools/pdbgen/pdb/gradients.pdb * tools/pdbgen/pdb/help.pdb * tools/pdbgen/pdb/image.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/pattern_select.pdb * tools/pdbgen/pdb/patterns.pdb * tools/pdbgen/pdb/selection.pdb * tools/pdbgen/pdb/tools.pdb * app/*: chainsaw #include cleanup: - Never (never!!) include stuff in header files except where we need access to structures' contents (like derived objects). - Added prototypes and proper formating in many files. - The #include order in *all* *.c files is as follows: #include "config.h" #include <system stuff> #include <gtk/gtk.h> #include "apptypes.h" #include "gimp stuff" #include "libgimp stuff" #include "libgimp/gimpintl.h" By following this scheme we can easily see a file's dependencies from it's #include's and can grep for the inclusion to find out where a file is used. * tools/pdbgen/app.pl: changed to follow the include scheme above. * libgimp/Makefile.am * libgimp/gimpuitypes.h: new file, included from libgimp/gimpui.h and from app/apptypes.h. * libgimp/gimpcolorbutton.[ch] * libgimp/gimpdialog.[ch] * libgimp/gimphelpui.[ch] * libgimp/gimpparasite.[ch] * libgimp/gimppatheditor.[ch] * libgimp/gimpprotocol.c * libgimp/gimpquerybox.[ch] * libgimp/gimpsizeentry.[ch] * libgimp/gimptypes.h * libgimp/gimpui.h * libgimp/gimpunit.h * libgimp/gimpunitmenu.[ch] * libgimp/gimpwidgets.[ch]: changed accordingly. * plug-ins/FractalExplorer/Dialogs.c * plug-ins/gdyntext/message_window.c * plug-ins/imagemap/imap_default_dialog.c * plug-ins/imagemap/imap_file.c: these files used to include "libgimp/gimpui.h" without including "libgimp/gimp.h". This is no longer possible because the libgimpui headers don't inlcude "libgimp/gimpunit.h" any more.
2000-12-29 15:22:01 +00:00
#include "gimperrordialog.h"
#include "gimpwidgets-utils.h"
app/Makefile.am app/gimphelp.[ch] new files 1999-09-27 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/gimphelp.[ch] * app/gimpui.[ch]: new files * app/interface.[ch] * app/preferences_dialog.[ch] The GIMP Help System part 1: Press "F1" in any dialog to pop up the help page for this dialog. Moved the widget constructors from preferences_dialog.[ch] and the query boxes from interface.[ch] to gimpui.[ch]. The dialog constructors take a help_func and a help_data parameter and install the "F1" accelerator which emits the new "help" signal. The "help" signal callback calls help_func(help_data) which finally has to call gimp_help() which in turn invokes the help browser. Still have to find a proper way to (1) prevent "F1" being assigned to some menu item and (2) to catch "F1" while browsing the menu trees in order to pop up the help for the selected item. * app/menus.c: a <Toolbox>/File/Help... menu item. * app/commands.[ch]: a command callback for the "Help..." menu item. * app/gimprc.[ch]: new boolean gimprc variable "use_help". * app/info_dialog.[ch]: pass a help function and data to the info dialog constructor. * app/tools.[ch]: store the tools help page names in the tool info structure. Export a special tools_help_func() which shows the help page for the active tool. * app/[all files calling a dialog constructor]: pass the dialog's help page to the constructor. Most dialogs are now created by gimp_dialog_new() which also sets up the action_area and the WM delete event callback, so I removed the resp. code from these files. Fixed some minor bugs and did some other stuff but didn't change any logic except dialog creation. * plug-ins/helpbrowser/helpbrowser.c: don't try to call a running help browser and don't install any menu path (all done in app/gimphelp.[ch] now).
1999-09-27 17:58:10 +00:00
#include "gimp-intl.h"
app/Makefile.am app/gimphelp.[ch] new files 1999-09-27 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/gimphelp.[ch] * app/gimpui.[ch]: new files * app/interface.[ch] * app/preferences_dialog.[ch] The GIMP Help System part 1: Press "F1" in any dialog to pop up the help page for this dialog. Moved the widget constructors from preferences_dialog.[ch] and the query boxes from interface.[ch] to gimpui.[ch]. The dialog constructors take a help_func and a help_data parameter and install the "F1" accelerator which emits the new "help" signal. The "help" signal callback calls help_func(help_data) which finally has to call gimp_help() which in turn invokes the help browser. Still have to find a proper way to (1) prevent "F1" being assigned to some menu item and (2) to catch "F1" while browsing the menu trees in order to pop up the help for the selected item. * app/menus.c: a <Toolbox>/File/Help... menu item. * app/commands.[ch]: a command callback for the "Help..." menu item. * app/gimprc.[ch]: new boolean gimprc variable "use_help". * app/info_dialog.[ch]: pass a help function and data to the info dialog constructor. * app/tools.[ch]: store the tools help page names in the tool info structure. Export a special tools_help_func() which shows the help page for the active tool. * app/[all files calling a dialog constructor]: pass the dialog's help page to the constructor. Most dialogs are now created by gimp_dialog_new() which also sets up the action_area and the WM delete event callback, so I removed the resp. code from these files. Fixed some minor bugs and did some other stuff but didn't change any logic except dialog creation. * plug-ins/helpbrowser/helpbrowser.c: don't try to call a running help browser and don't install any menu path (all done in app/gimphelp.[ch] now).
1999-09-27 17:58:10 +00:00
/**
* gimp_menu_position:
* @menu: a #GtkMenu widget
* @x: pointer to horizontal position
* @y: pointer to vertical position
*
* Positions a #GtkMenu so that it pops up on screen. This function
* takes care of the preferred popup direction (taken from the widget
* render direction) and it handles multiple monitors representing a
* single #GdkScreen (Xinerama).
*
* You should call this function with @x and @y initialized to the
* origin of the menu. This is typically the center of the widget the
* menu is popped up from. gimp_menu_position() will then decide if
* and how these initial values need to be changed.
**/
void
gimp_menu_position (GtkMenu *menu,
gint *x,
gint *y)
{
GtkWidget *widget;
GdkScreen *screen;
GtkRequisition requisition;
GdkRectangle rect;
gint monitor;
register the button icons with GTK_ICON_SIZE_BUTTON, but set them as 2001-08-05 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpstock.[ch]: register the button icons with GTK_ICON_SIZE_BUTTON, but set them as scalable fallbacks for themselves so they get scaled for menus. * app/gui/menus.c: set stock icons for much more menu entries. * app/widgets/gimpwidgets-utils.[ch]: new utility function gimp_item_factory_popup_with_data(). * app/disp_callbacks.[ch] * app/gui/brushes-commands.c * app/gui/channels-commands.c * app/gui/gradients-commands.c * app/gui/layers-commands.c * app/gui/palettes-commands.c * app/gui/paths-dialog.c * app/gui/patterns-commands.c: use the new function. * app/tools/gimpcolorbalancetool.c * app/tools/gimpcurvestool.c * app/tools/gimphuesaturationtool.c * app/tools/gimplevelstool.c * app/tools/gimpposterizetool.c: s/_("Reset")/GIMP_STOCK_RESET/ * app/widgets/gimpcontainereditor.[ch] * app/widgets/gimpcontainerview.[ch]: moved the button_box utility functions from the container editor to GimpContainerView itself. * app/widgets/gimpbufferview.c * app/widgets/gimpchannellistview.c * app/widgets/gimpcomponentlistitem.c * app/widgets/gimpcontainergridview.[ch] * app/widgets/gimpdatafactoryview.c * app/widgets/gimpdrawablelistitem.c * app/widgets/gimpdrawablelistview.[ch] * app/widgets/gimplayerlistitem.c * app/widgets/gimplayerlistview.c: changed accordingly. Removed lots of duplicated code and use stock images instead of pixmaps. * libgimpwidgets/gimpfileselection.[ch] * libgimpwidgets/gimppatheditor.c: use stock images instead of pixmaps. * pixmaps/Makefile.am: removed "yes" and "no", added "stroke". * pixmaps/anchor.xpm * pixmaps/delete.xpm * pixmaps/lower.xpm * pixmaps/new.xpm * pixmaps/paste-as-new.xpm * pixmaps/paste-into.xpm * pixmaps/paste.xpm * pixmaps/raise.xpm * pixmaps/refresh.xpm * pixmaps/toselection.xpm: made them all 16x16 so they are scaled nicely in menus. Should probably be 18x18.
2001-08-04 20:38:54 +00:00
app/core/Makefile.am new files: the QMask stuff stripped from GUI code. 2001-11-30 Michael Natterer <mitch@gimp.org> * app/core/Makefile.am * app/core/gimpimage-qmask.[ch]: new files: the QMask stuff stripped from GUI code. Added gimp_image_qmask_invert(). * app/core/gimpimage.[ch]: removed the QMask functions. * app/display/Makefile.am * app/display/gimpdisplayshell-qmask.[ch]: removed. * app/gui/Makefile.am * app/gui/qmask-commands.[ch]: new files for the new QMask item factory callbacks and the qmask query dialog. * app/gui/menus.c: added a context menu for the QMask button. * app/display/gimpdisplayshell.c * app/display/gimpdisplayshell-handlers.c: don't include the qmask stuff. * app/display/gimpdisplayshell-callbacks.[ch]: Moved the 2 qmask callbacks here. Don't popup the dialog on double_click. Show the contect menu on right-click. * app/display/gimpdisplayshell-callbacks.[ch]: gimp_display_shell_canvas_events(): removed the hack of conntecting "key_press_event" to gtk_true() while a tool is active. Instead, check for (event & GDK_BUTTON1_MASK) in the key_press and key_release handlers and stop signal emission. Save the modifier state on "button_press" and restore it after "button_release". Changed the way context menus are updated/shown: - removed GimpContainerContextFunc. - pass around item factory identifiers (e.g. "<Brushes>") - added voodoo to update the menus before showing them. * app/widgets/gimpitemfactory.[ch]: gimp_item_factory_new(): take a GimpItemFactoryUpdateFunc parameter, attach it as data to the factory and use it to update the menu in gimp_item_factory_popup_with_date(). * app/widgets/gimpwidgets-utils.[ch]: removed gimp_item_factory_popup_with_data() here. * app/widgets/gimpbrushfactoryview.[ch] * app/widgets/gimpbufferview.[ch] * app/widgets/gimpcontainereditor.[ch] * app/widgets/gimpdatafactoryview.[ch] * app/widgets/gimpdocumentview.[ch] * app/widgets/gimpdrawablelistview.[ch]: use item_factory identifier strings all over the place. * app/widgets/gimpdockbook.c: removed the menu update code, it's now in gui/dialogs-commands.c. * app/gui/brushes-commands.[ch] * app/gui/buffers-commands.[c] * app/gui/channels-commands.[ch] * app/gui/dialogs-commands.[ch] * app/gui/documents-commands.[ch] * app/gui/gradient-editor-commands.[ch] * app/gui/gradients-commands.[ch] * app/gui/layers-commands.[ch] * app/gui/palettes-commands.[ch] * app/gui/patterns-commands.[ch]: removed all show_context_menu() functions and made the update functions public. Changed all update functions to use the gimp_item_factory_set_foo() methods instead of gimp_menu_item_set_foo(). * app/gui/menus.c: pass the update functions to the gimp_item_factory_new(). * app/gui/dialogs-constructors.c: pass item factory identifiers to all view constructors. * app/gui/gradient-editor.c: show the context menu using the new method. * app/gui/toolbox.c: no need to include "dialogs-commands.h".
2001-11-30 14:41:56 +00:00
g_return_if_fail (GTK_IS_MENU (menu));
register the button icons with GTK_ICON_SIZE_BUTTON, but set them as 2001-08-05 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpstock.[ch]: register the button icons with GTK_ICON_SIZE_BUTTON, but set them as scalable fallbacks for themselves so they get scaled for menus. * app/gui/menus.c: set stock icons for much more menu entries. * app/widgets/gimpwidgets-utils.[ch]: new utility function gimp_item_factory_popup_with_data(). * app/disp_callbacks.[ch] * app/gui/brushes-commands.c * app/gui/channels-commands.c * app/gui/gradients-commands.c * app/gui/layers-commands.c * app/gui/palettes-commands.c * app/gui/paths-dialog.c * app/gui/patterns-commands.c: use the new function. * app/tools/gimpcolorbalancetool.c * app/tools/gimpcurvestool.c * app/tools/gimphuesaturationtool.c * app/tools/gimplevelstool.c * app/tools/gimpposterizetool.c: s/_("Reset")/GIMP_STOCK_RESET/ * app/widgets/gimpcontainereditor.[ch] * app/widgets/gimpcontainerview.[ch]: moved the button_box utility functions from the container editor to GimpContainerView itself. * app/widgets/gimpbufferview.c * app/widgets/gimpchannellistview.c * app/widgets/gimpcomponentlistitem.c * app/widgets/gimpcontainergridview.[ch] * app/widgets/gimpdatafactoryview.c * app/widgets/gimpdrawablelistitem.c * app/widgets/gimpdrawablelistview.[ch] * app/widgets/gimplayerlistitem.c * app/widgets/gimplayerlistview.c: changed accordingly. Removed lots of duplicated code and use stock images instead of pixmaps. * libgimpwidgets/gimpfileselection.[ch] * libgimpwidgets/gimppatheditor.c: use stock images instead of pixmaps. * pixmaps/Makefile.am: removed "yes" and "no", added "stroke". * pixmaps/anchor.xpm * pixmaps/delete.xpm * pixmaps/lower.xpm * pixmaps/new.xpm * pixmaps/paste-as-new.xpm * pixmaps/paste-into.xpm * pixmaps/paste.xpm * pixmaps/raise.xpm * pixmaps/refresh.xpm * pixmaps/toselection.xpm: made them all 16x16 so they are scaled nicely in menus. Should probably be 18x18.
2001-08-04 20:38:54 +00:00
g_return_if_fail (x != NULL);
g_return_if_fail (y != NULL);
widget = GTK_WIDGET (menu);
screen = gtk_widget_get_screen (widget);
monitor = gdk_screen_get_monitor_at_point (screen, *x, *y);
gdk_screen_get_monitor_geometry (screen, monitor, &rect);
gtk_menu_set_screen (menu, screen);
gtk_widget_size_request (widget, &requisition);
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
{
*x -= requisition.width;
if (*x < rect.x)
*x += requisition.width;
}
else
{
if (*x + requisition.width > rect.x + rect.width)
*x -= requisition.width;
}
if (*x < rect.x)
*x = rect.x;
register the button icons with GTK_ICON_SIZE_BUTTON, but set them as 2001-08-05 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpstock.[ch]: register the button icons with GTK_ICON_SIZE_BUTTON, but set them as scalable fallbacks for themselves so they get scaled for menus. * app/gui/menus.c: set stock icons for much more menu entries. * app/widgets/gimpwidgets-utils.[ch]: new utility function gimp_item_factory_popup_with_data(). * app/disp_callbacks.[ch] * app/gui/brushes-commands.c * app/gui/channels-commands.c * app/gui/gradients-commands.c * app/gui/layers-commands.c * app/gui/palettes-commands.c * app/gui/paths-dialog.c * app/gui/patterns-commands.c: use the new function. * app/tools/gimpcolorbalancetool.c * app/tools/gimpcurvestool.c * app/tools/gimphuesaturationtool.c * app/tools/gimplevelstool.c * app/tools/gimpposterizetool.c: s/_("Reset")/GIMP_STOCK_RESET/ * app/widgets/gimpcontainereditor.[ch] * app/widgets/gimpcontainerview.[ch]: moved the button_box utility functions from the container editor to GimpContainerView itself. * app/widgets/gimpbufferview.c * app/widgets/gimpchannellistview.c * app/widgets/gimpcomponentlistitem.c * app/widgets/gimpcontainergridview.[ch] * app/widgets/gimpdatafactoryview.c * app/widgets/gimpdrawablelistitem.c * app/widgets/gimpdrawablelistview.[ch] * app/widgets/gimplayerlistitem.c * app/widgets/gimplayerlistview.c: changed accordingly. Removed lots of duplicated code and use stock images instead of pixmaps. * libgimpwidgets/gimpfileselection.[ch] * libgimpwidgets/gimppatheditor.c: use stock images instead of pixmaps. * pixmaps/Makefile.am: removed "yes" and "no", added "stroke". * pixmaps/anchor.xpm * pixmaps/delete.xpm * pixmaps/lower.xpm * pixmaps/new.xpm * pixmaps/paste-as-new.xpm * pixmaps/paste-into.xpm * pixmaps/paste.xpm * pixmaps/raise.xpm * pixmaps/refresh.xpm * pixmaps/toselection.xpm: made them all 16x16 so they are scaled nicely in menus. Should probably be 18x18.
2001-08-04 20:38:54 +00:00
if (*y + requisition.height > rect.y + rect.height)
*y -= requisition.height;
if (*y < rect.y)
*y = rect.y;
register the button icons with GTK_ICON_SIZE_BUTTON, but set them as 2001-08-05 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpstock.[ch]: register the button icons with GTK_ICON_SIZE_BUTTON, but set them as scalable fallbacks for themselves so they get scaled for menus. * app/gui/menus.c: set stock icons for much more menu entries. * app/widgets/gimpwidgets-utils.[ch]: new utility function gimp_item_factory_popup_with_data(). * app/disp_callbacks.[ch] * app/gui/brushes-commands.c * app/gui/channels-commands.c * app/gui/gradients-commands.c * app/gui/layers-commands.c * app/gui/palettes-commands.c * app/gui/paths-dialog.c * app/gui/patterns-commands.c: use the new function. * app/tools/gimpcolorbalancetool.c * app/tools/gimpcurvestool.c * app/tools/gimphuesaturationtool.c * app/tools/gimplevelstool.c * app/tools/gimpposterizetool.c: s/_("Reset")/GIMP_STOCK_RESET/ * app/widgets/gimpcontainereditor.[ch] * app/widgets/gimpcontainerview.[ch]: moved the button_box utility functions from the container editor to GimpContainerView itself. * app/widgets/gimpbufferview.c * app/widgets/gimpchannellistview.c * app/widgets/gimpcomponentlistitem.c * app/widgets/gimpcontainergridview.[ch] * app/widgets/gimpdatafactoryview.c * app/widgets/gimpdrawablelistitem.c * app/widgets/gimpdrawablelistview.[ch] * app/widgets/gimplayerlistitem.c * app/widgets/gimplayerlistview.c: changed accordingly. Removed lots of duplicated code and use stock images instead of pixmaps. * libgimpwidgets/gimpfileselection.[ch] * libgimpwidgets/gimppatheditor.c: use stock images instead of pixmaps. * pixmaps/Makefile.am: removed "yes" and "no", added "stroke". * pixmaps/anchor.xpm * pixmaps/delete.xpm * pixmaps/lower.xpm * pixmaps/new.xpm * pixmaps/paste-as-new.xpm * pixmaps/paste-into.xpm * pixmaps/paste.xpm * pixmaps/raise.xpm * pixmaps/refresh.xpm * pixmaps/toselection.xpm: made them all 16x16 so they are scaled nicely in menus. Should probably be 18x18.
2001-08-04 20:38:54 +00:00
}
/**
* gimp_button_menu_position:
* @button: a button widget to popup the menu from
* @menu: the menu to position
* @position: the preferred popup direction for the menu (left or right)
* @x: return location for x coordinate
* @y: return location for y coordinate
*
* Utility function to position a menu that pops up from a button.
**/
void
gimp_button_menu_position (GtkWidget *button,
GtkMenu *menu,
GtkPositionType position,
gint *x,
gint *y)
{
GdkScreen *screen;
GtkRequisition menu_requisition;
GdkRectangle rect;
gint monitor;
g_return_if_fail (GTK_WIDGET_REALIZED (button));
g_return_if_fail (GTK_IS_MENU (menu));
g_return_if_fail (x != NULL);
g_return_if_fail (y != NULL);
if (gtk_widget_get_direction (button) == GTK_TEXT_DIR_RTL)
{
switch (position)
{
case GTK_POS_LEFT: position = GTK_POS_RIGHT; break;
case GTK_POS_RIGHT: position = GTK_POS_LEFT; break;
default:
break;
}
}
gdk_window_get_origin (button->window, x, y);
gtk_widget_size_request (GTK_WIDGET (menu), &menu_requisition);
screen = gtk_widget_get_screen (button);
monitor = gdk_screen_get_monitor_at_point (screen, *x, *y);
gdk_screen_get_monitor_geometry (screen, monitor, &rect);
gtk_menu_set_screen (menu, screen);
*x += button->allocation.x;
switch (position)
{
case GTK_POS_LEFT:
*x -= menu_requisition.width;
if (*x < rect.x)
*x += menu_requisition.width + button->allocation.width;
break;
case GTK_POS_RIGHT:
*x += button->allocation.width;
if (*x + menu_requisition.width > rect.x + rect.width)
*x -= button->allocation.width + menu_requisition.width;
break;
default:
g_warning ("%s: unhandled position (%d)", G_STRFUNC, position);
break;
}
*y += button->allocation.y + button->allocation.height / 2;
if (*y + menu_requisition.height > rect.y + rect.height)
*y -= menu_requisition.height;
if (*y < rect.y)
*y = rect.y;
}
void
gimp_table_attach_stock (GtkTable *table,
gint row,
const gchar *label_text,
gdouble yalign,
GtkWidget *widget,
gint colspan,
const gchar *stock_id)
{
GtkWidget *image;
GtkWidget *label;
g_return_if_fail (GTK_IS_TABLE (table));
g_return_if_fail (label_text != NULL);
label = gtk_label_new_with_mnemonic (label_text);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, yalign);
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
gtk_table_attach (table, label, 0, 1, row, row + 1,
GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (label);
if (widget)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
gtk_table_attach (table, widget, 1, 1 + colspan, row, row + 1,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
gtk_widget_show (widget);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
}
image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON);
if (image)
{
gtk_misc_set_alignment (GTK_MISC (image), 0.0, 0.5);
gtk_table_attach (table, image, 1 + colspan, 2 + colspan, row, row + 1,
GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
gtk_widget_show (image);
}
}
GtkIconSize
gimp_get_icon_size (GtkWidget *widget,
const gchar *stock_id,
GtkIconSize max_size,
gint width,
gint height)
{
GtkIconSet *icon_set;
GtkIconSize *sizes;
gint n_sizes;
gint i;
gint width_diff = 1024;
gint height_diff = 1024;
gint max_width;
gint max_height;
GtkIconSize icon_size = GTK_ICON_SIZE_MENU;
GdkScreen *screen;
GtkSettings *settings;
g_return_val_if_fail (GTK_IS_WIDGET (widget), icon_size);
g_return_val_if_fail (stock_id != NULL, icon_size);
g_return_val_if_fail (width > 0, icon_size);
g_return_val_if_fail (height > 0, icon_size);
icon_set = gtk_style_lookup_icon_set (widget->style, stock_id);
if (! icon_set)
return GTK_ICON_SIZE_INVALID;
screen = gtk_widget_get_screen (widget);
settings = gtk_settings_get_for_screen (screen);
if (! gtk_icon_size_lookup_for_settings (settings, max_size,
&max_width, &max_height))
{
max_width = 1024;
max_height = 1024;
}
gtk_icon_set_get_sizes (icon_set, &sizes, &n_sizes);
for (i = 0; i < n_sizes; i++)
{
gint icon_width;
gint icon_height;
if (gtk_icon_size_lookup_for_settings (settings, sizes[i],
&icon_width, &icon_height))
{
if (icon_width <= width &&
icon_height <= height &&
icon_width <= max_width &&
icon_height <= max_height &&
((width - icon_width) < width_diff ||
(height - icon_height) < height_diff))
{
width_diff = width - icon_width;
height_diff = height - icon_height;
icon_size = sizes[i];
}
}
}
g_free (sizes);
return icon_size;
}
/* The format string which is used to display modifier names
* <Shift>, <Ctrl> and <Alt>
*/
#define GIMP_MOD_NAME_FORMAT_STRING N_("<%s>")
const gchar *
gimp_get_mod_name_shift (void)
{
static gchar *mod_name_shift = NULL;
if (! mod_name_shift)
{
GtkAccelLabelClass *accel_label_class;
accel_label_class = g_type_class_ref (GTK_TYPE_ACCEL_LABEL);
mod_name_shift = g_strdup_printf (gettext (GIMP_MOD_NAME_FORMAT_STRING),
accel_label_class->mod_name_shift);
g_type_class_unref (accel_label_class);
}
return (const gchar *) mod_name_shift;
}
const gchar *
gimp_get_mod_name_control (void)
{
static gchar *mod_name_control = NULL;
if (! mod_name_control)
{
GtkAccelLabelClass *accel_label_class;
accel_label_class = g_type_class_ref (GTK_TYPE_ACCEL_LABEL);
mod_name_control = g_strdup_printf (gettext (GIMP_MOD_NAME_FORMAT_STRING),
accel_label_class->mod_name_control);
g_type_class_unref (accel_label_class);
}
return (const gchar *) mod_name_control;
}
const gchar *
gimp_get_mod_name_alt (void)
{
static gchar *mod_name_alt = NULL;
if (! mod_name_alt)
{
GtkAccelLabelClass *accel_label_class;
accel_label_class = g_type_class_ref (GTK_TYPE_ACCEL_LABEL);
mod_name_alt = g_strdup_printf (gettext (GIMP_MOD_NAME_FORMAT_STRING),
accel_label_class->mod_name_alt);
g_type_class_unref (accel_label_class);
}
return (const gchar *) mod_name_alt;
}
const gchar *
gimp_get_mod_separator (void)
{
static gchar *mod_separator = NULL;
if (! mod_separator)
{
GtkAccelLabelClass *accel_label_class;
accel_label_class = g_type_class_ref (GTK_TYPE_ACCEL_LABEL);
mod_separator = g_strdup (accel_label_class->mod_separator);
g_type_class_unref (accel_label_class);
}
return (const gchar *) mod_separator;
}
const gchar *
gimp_get_mod_string (GdkModifierType modifiers)
{
static struct
{
GdkModifierType modifiers;
gchar *name;
}
modifier_strings[] =
{
{ GDK_SHIFT_MASK, NULL },
{ GDK_CONTROL_MASK, NULL },
{ GDK_MOD1_MASK, NULL },
{ GDK_SHIFT_MASK | GDK_CONTROL_MASK, NULL },
{ GDK_SHIFT_MASK | GDK_MOD1_MASK, NULL },
{ GDK_CONTROL_MASK | GDK_MOD1_MASK, NULL },
{ GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK, NULL }
};
gint i;
for (i = 0; i < G_N_ELEMENTS (modifier_strings); i++)
{
if (modifiers == modifier_strings[i].modifiers)
{
if (! modifier_strings[i].name)
{
GString *str = g_string_new ("");
if (modifiers & GDK_SHIFT_MASK)
{
g_string_append (str, gimp_get_mod_name_shift ());
}
if (modifiers & GDK_CONTROL_MASK)
{
if (str->len)
g_string_append (str, gimp_get_mod_separator ());
g_string_append (str, gimp_get_mod_name_control ());
}
if (modifiers & GDK_MOD1_MASK)
{
if (str->len)
g_string_append (str, gimp_get_mod_separator ());
g_string_append (str, gimp_get_mod_name_alt ());
}
modifier_strings[i].name = g_string_free (str, FALSE);
}
return modifier_strings[i].name;
}
}
return NULL;
}
static void
gimp_substitute_underscores (gchar *str)
{
gchar *p;
for (p = str; *p; p++)
if (*p == '_')
*p = ' ';
}
gchar *
gimp_get_accel_string (guint key,
GdkModifierType modifiers)
{
GtkAccelLabelClass *accel_label_class;
GString *gstring;
gunichar ch;
accel_label_class = g_type_class_peek (GTK_TYPE_ACCEL_LABEL);
gstring = g_string_new (gimp_get_mod_string (modifiers));
if (gstring->len > 0)
g_string_append (gstring, gimp_get_mod_separator ());
ch = gdk_keyval_to_unicode (key);
if (ch && (g_unichar_isgraph (ch) || ch == ' ') &&
(ch < 0x80 || accel_label_class->latin1_to_char))
{
switch (ch)
{
case ' ':
g_string_append (gstring, "Space");
break;
case '\\':
g_string_append (gstring, "Backslash");
break;
default:
g_string_append_unichar (gstring, g_unichar_toupper (ch));
break;
}
}
else
{
gchar *tmp;
tmp = gtk_accelerator_name (key, 0);
if (tmp[0] != 0 && tmp[1] == 0)
tmp[0] = g_ascii_toupper (tmp[0]);
gimp_substitute_underscores (tmp);
g_string_append (gstring, tmp);
g_free (tmp);
}
return g_string_free (gstring, FALSE);
}
/**
* gimp_get_screen_resolution:
* @screen: a #GdkScreen or %NULL
* @xres: returns the horizontal screen resolution (in dpi)
* @yres: returns the vertical screen resolution (in dpi)
*
* Retrieves the screen resolution from GDK. If @screen is %NULL, the
* default screen is used.
**/
void
gimp_get_screen_resolution (GdkScreen *screen,
gdouble *xres,
gdouble *yres)
{
gint width, height;
gint width_mm, height_mm;
gdouble x = 0.0;
gdouble y = 0.0;
g_return_if_fail (screen == NULL || GDK_IS_SCREEN (screen));
g_return_if_fail (xres != NULL);
g_return_if_fail (yres != NULL);
if (!screen)
screen = gdk_screen_get_default ();
width = gdk_screen_get_width (screen);
height = gdk_screen_get_height (screen);
width_mm = gdk_screen_get_width_mm (screen);
height_mm = gdk_screen_get_height_mm (screen);
/*
* From xdpyinfo.c:
*
* there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
*
* dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
* = N pixels / (M inch / 25.4)
* = N * 25.4 pixels / M inch
*/
if (width_mm > 0 && height_mm > 0)
{
x = (width * 25.4) / (gdouble) width_mm;
y = (height * 25.4) / (gdouble) height_mm;
}
if (x < GIMP_MIN_RESOLUTION || x > GIMP_MAX_RESOLUTION ||
y < GIMP_MIN_RESOLUTION || y > GIMP_MAX_RESOLUTION)
{
g_warning ("GDK returned bogus values for the screen resolution, "
"using 75 dpi instead.");
x = 75.0;
y = 75.0;
}
/* round the value to full integers to give more pleasant results */
*xres = ROUND (x);
*yres = ROUND (y);
}
/**
* gimp_rgb_get_gdk_color:
* @rgb: the source color as #GimpRGB
* @gdk_color: pointer to a #GdkColor
*
* Initializes @gdk_color from a #GimpRGB. This function does not
* allocate the color for you. Depending on how you want to use it,
* you may have to call gdk_colormap_alloc_color().
**/
void
gimp_rgb_get_gdk_color (const GimpRGB *rgb,
GdkColor *gdk_color)
{
guchar r, g, b;
g_return_if_fail (rgb != NULL);
g_return_if_fail (gdk_color != NULL);
gimp_rgb_get_uchar (rgb, &r, &g, &b);
gdk_color->red = (r << 8) | r;
gdk_color->green = (g << 8) | g;
gdk_color->blue = (b << 8) | b;
}
/**
* gimp_rgb_set_gdk_color:
* @rgb: a #GimpRGB that is to be set
* @gdk_color: pointer to the source #GdkColor
*
* Initializes @rgb from a #GdkColor. This function does not touch
* the alpha value of @rgb.
**/
void
gimp_rgb_set_gdk_color (GimpRGB *rgb,
const GdkColor *gdk_color)
{
guchar r, g, b;
g_return_if_fail (rgb != NULL);
g_return_if_fail (gdk_color != NULL);
r = gdk_color->red >> 8;
g = gdk_color->green >> 8;
b = gdk_color->blue >> 8;
gimp_rgb_set_uchar (rgb, r, g, b);
}
void
gimp_window_set_hint (GtkWindow *window,
GimpWindowHint hint)
{
g_return_if_fail (GTK_IS_WINDOW (window));
switch (hint)
{
case GIMP_WINDOW_HINT_NORMAL:
gtk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_NORMAL);
break;
case GIMP_WINDOW_HINT_UTILITY:
gtk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_UTILITY);
break;
case GIMP_WINDOW_HINT_KEEP_ABOVE:
gtk_window_set_keep_above (window, TRUE);
break;
}
}
void
gimp_dialog_set_sensitive (GtkDialog *dialog,
gboolean sensitive)
{
GList *children;
GList *list;
g_return_if_fail (GTK_IS_DIALOG (dialog));
children = gtk_container_get_children (GTK_CONTAINER (dialog->vbox));
for (list = children; list; list = g_list_next (list))
{
/* skip the last item (the action area) */
if (! g_list_next (list))
break;
gtk_widget_set_sensitive (list->data, sensitive);
}
g_list_free (children);
if (sensitive)
gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_CANCEL, sensitive);
gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, sensitive);
}