diff options
Diffstat (limited to 'eel/eel-art-gtk-extensions.c')
-rw-r--r-- | eel/eel-art-gtk-extensions.c | 346 |
1 files changed, 346 insertions, 0 deletions
diff --git a/eel/eel-art-gtk-extensions.c b/eel/eel-art-gtk-extensions.c new file mode 100644 index 00000000..f3ccef3c --- /dev/null +++ b/eel/eel-art-gtk-extensions.c @@ -0,0 +1,346 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-eel-gtk-extensions.c - Access gtk/gdk attributes as libeel rectangles. + + Copyright (C) 2000 Eazel, Inc. + + The Mate 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 Mate 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 PEELICULAR 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 Mate 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: Ramiro Estrugo <[email protected]> +*/ + +#include <config.h> + +#include "eel-art-gtk-extensions.h" +#include <gdk/gdkx.h> + +/** + * eel_gdk_rectangle_to_eel_irect: + * @gdk_rectangle: The source GdkRectangle. + * + * Return value: An EelIRect representation of the GdkRectangle. + * + * This is a very simple conversion of rectangles from the Gdk to the Libeel + * universe. This is useful in code that does clipping (or other operations) + * using libeel and has a GdkRectangle to work with - for example expose_event() + * in GtkWidget's. + */ +EelIRect +eel_gdk_rectangle_to_eel_irect (GdkRectangle gdk_rectangle) +{ + EelIRect rectangle; + + rectangle.x0 = gdk_rectangle.x; + rectangle.y0 = gdk_rectangle.y; + rectangle.x1 = rectangle.x0 + (int) gdk_rectangle.width; + rectangle.y1 = rectangle.y0 + (int) gdk_rectangle.height; + + return rectangle; +} + +/** + * eel_screen_get_dimensions: + * + * Return value: The screen dimensions. + * + */ +EelDimensions +eel_screen_get_dimensions (void) +{ + EelDimensions screen_dimensions; + + screen_dimensions.width = gdk_screen_width (); + screen_dimensions.height = gdk_screen_height (); + + g_assert (screen_dimensions.width > 0); + g_assert (screen_dimensions.height > 0); + + return screen_dimensions; +} + +/** + * eel_gdk_window_get_bounds: + * @gdk_window: The source GdkWindow. + * + * Return value: An EelIRect representation of the given GdkWindow's geometry + * relative to its parent in the Gdk window hierarchy. + * + */ +EelIRect +eel_gdk_window_get_bounds (GdkWindow *gdk_window) +{ + EelIRect bounds; + int width; + int height; + + g_return_val_if_fail (gdk_window != NULL, eel_irect_empty); + + gdk_window_get_position (gdk_window, &bounds.x0, &bounds.y0); + +#if GTK_CHECK_VERSION(3, 0, 0) + width = gdk_window_get_width(gdk_window); + height = gdk_window_get_height(gdk_window); +#else + gdk_drawable_get_size (gdk_window, &width, &height); +#endif + + + bounds.x1 = bounds.x0 + width; + bounds.y1 = bounds.y0 + height; + + return bounds; +} + +/** + * eel_gdk_window_get_bounds: + * @gdk_window: The source GdkWindow. + * + * Return value: An EelIRect representation of the given GdkWindow's geometry + * relative to the screen. + * + */ +EelIRect +eel_gdk_window_get_screen_relative_bounds (GdkWindow *gdk_window) +{ + EelIRect screen_bounds; + int width; + int height; + + g_return_val_if_fail (gdk_window != NULL, eel_irect_empty); + + if (!gdk_window_get_origin (gdk_window, + &screen_bounds.x0, + &screen_bounds.y0)) + { + return eel_irect_empty; + } + +#if GTK_CHECK_VERSION(3, 0, 0) + width = gdk_window_get_width(gdk_window); + height = gdk_window_get_height(gdk_window); +#else + gdk_drawable_get_size(gdk_window, &width, &height); +#endif + + screen_bounds.x1 = screen_bounds.x0 + width; + screen_bounds.y1 = screen_bounds.y0 + height; + + return screen_bounds; +} + +/** + * eel_gtk_widget_get_bounds: + * @gtk_widget: The source GtkWidget. + * + * Return value: An EelIRect representation of the given GtkWidget's geometry + * relative to its parent. In the Gtk universe this is known as "allocation." + * + */ +EelIRect +eel_gtk_widget_get_bounds (GtkWidget *gtk_widget) +{ + GtkAllocation allocation; + g_return_val_if_fail (GTK_IS_WIDGET (gtk_widget), eel_irect_empty); + + gtk_widget_get_allocation (gtk_widget, &allocation); + return eel_irect_assign (allocation.x, + allocation.y, + (int) allocation.width, + (int) allocation.height); +} + +/** + * eel_gtk_widget_get_dimensions: + * @gtk_widget: The source GtkWidget. + * + * Return value: The widget's dimensions. The returned dimensions are only valid + * after the widget's geometry has been "allocated" by its container. + */ +EelDimensions +eel_gtk_widget_get_dimensions (GtkWidget *gtk_widget) +{ + EelDimensions dimensions; + GtkAllocation allocation; + + g_return_val_if_fail (GTK_IS_WIDGET (gtk_widget), eel_dimensions_empty); + + gtk_widget_get_allocation (gtk_widget, &allocation); + dimensions.width = (int) allocation.width; + dimensions.height = (int) allocation.height; + + return dimensions; +} + +/** + * eel_gtk_widget_get_preferred_dimensions: + * @gtk_widget: The source GtkWidget. + * + * Return value: The widget's preferred dimensions. The preferred dimensions are + * computed by calling the widget's 'size_request' method and thus + * could potentially be expensive for complicated widgets. + */ +EelDimensions +eel_gtk_widget_get_preferred_dimensions (GtkWidget *gtk_widget) +{ + GtkRequisition requisition; + EelDimensions preferred_dimensions; + + g_return_val_if_fail (GTK_IS_WIDGET (gtk_widget), eel_dimensions_empty); + + gtk_widget_size_request (gtk_widget, &requisition); + + preferred_dimensions.width = (int) requisition.width; + preferred_dimensions.height = (int) requisition.height; + + return preferred_dimensions; +} + +/** + * eel_gdk_window_clip_dirty_area_to_screen: + * @gdk_window: The GdkWindow that the damage occured on. + * @dirty_area: The dirty area as an EelIRect. + * + * Return value: An EelIRect of the dirty area clipped to the screen. + * + * This function is useful to do less work in expose_event() GtkWidget methods. + * It also ensures that any drawing that the widget does is actually onscreen. + */ +EelIRect +eel_gdk_window_clip_dirty_area_to_screen (GdkWindow *gdk_window, + EelIRect dirty_area) +{ + EelIRect clipped; + EelDimensions screen_dimensions; + EelIRect screen_relative_bounds; + int dirty_width; + int dirty_height; + + g_return_val_if_fail (gdk_window != NULL, eel_irect_empty); + + dirty_width = dirty_area.x1 - dirty_area.x0; + dirty_height = dirty_area.y1 - dirty_area.y0; + + g_return_val_if_fail (dirty_width > 0, eel_irect_empty); + g_return_val_if_fail (dirty_height > 0, eel_irect_empty); + + screen_dimensions = eel_screen_get_dimensions (); + screen_relative_bounds = eel_gdk_window_get_screen_relative_bounds (gdk_window); + + /* Window is obscured by left edge of screen */ + if ((screen_relative_bounds.x0 + dirty_area.x0) < 0) + { + int clipped_width = screen_relative_bounds.x0 + dirty_area.x0 + dirty_width; + clipped.x0 = dirty_area.x0 + dirty_width - clipped_width; + clipped.x1 = clipped.x0 + clipped_width; + } + else + { + clipped.x0 = dirty_area.x0; + clipped.x1 = clipped.x0 + dirty_width; + } + + /* Window is obscured by right edge of screen */ + if (screen_relative_bounds.x1 > screen_dimensions.width) + { + int obscured_width; + + obscured_width = + screen_relative_bounds.x0 + dirty_area.x0 + dirty_width - screen_dimensions.width; + + if (obscured_width > 0) + { + clipped.x1 -= obscured_width; + } + } + + /* Window is obscured by top edge of screen */ + if ((screen_relative_bounds.y0 + dirty_area.y0) < 0) + { + int clipped_height = screen_relative_bounds.y0 + dirty_area.y0 + dirty_height; + clipped.y0 = dirty_area.y0 + dirty_height - clipped_height; + clipped.y1 = clipped.y0 + clipped_height; + } + else + { + clipped.y0 = dirty_area.y0; + clipped.y1 = clipped.y0 + dirty_height; + } + + /* Window is obscured by bottom edge of screen */ + if (screen_relative_bounds.y1 > screen_dimensions.height) + { + int obscured_height; + + obscured_height = + screen_relative_bounds.y0 + dirty_area.y0 + dirty_height - screen_dimensions.height; + + if (obscured_height > 0) + { + clipped.y1 -= obscured_height; + } + } + + if (eel_irect_is_empty (&clipped)) + { + clipped = eel_irect_empty; + } + + return clipped; +} + +GdkRectangle +eel_irect_to_gdk_rectangle (EelIRect rectangle) +{ + GdkRectangle gdk_rect; + + gdk_rect.x = rectangle.x0; + gdk_rect.y = rectangle.y0; + gdk_rect.width = eel_irect_get_width (rectangle); + gdk_rect.height = eel_irect_get_height (rectangle); + + return gdk_rect; +} + +EelDimensions +eel_gdk_window_get_dimensions (GdkWindow *gdk_window) +{ + EelDimensions dimensions; + + g_return_val_if_fail (gdk_window != NULL, eel_dimensions_empty); + +#if GTK_CHECK_VERSION(3, 0, 0) + dimensions.width = gdk_window_get_width(gdk_window); + dimensions.height = gdk_window_get_height(gdk_window); +#else + gdk_drawable_get_size (gdk_window, &dimensions.width, &dimensions.height); +#endif + + return dimensions; +} + +EelIPoint +eel_gdk_get_pointer_position (void) +{ + + EelIPoint position; + + gdk_window_get_pointer (gdk_get_default_root_window (), + &position.x, + &position.y, + NULL); + + return position; +} |