gucharmap r1682 - trunk/gucharmap
- From: chpe svn gnome org
- To: svn-commits-list gnome org
- Subject: gucharmap r1682 - trunk/gucharmap
- Date: Fri, 21 Mar 2008 10:55:40 +0000 (GMT)
Author: chpe
Date: Fri Mar 21 10:55:39 2008
New Revision: 1682
URL: http://svn.gnome.org/viewvc/gucharmap?rev=1682&view=rev
Log:
Improve zoom popup positioning code to cope with screen borders.
Modified:
trunk/gucharmap/gucharmap-chartable.c
Modified: trunk/gucharmap/gucharmap-chartable.c
==============================================================================
--- trunk/gucharmap/gucharmap-chartable.c (original)
+++ trunk/gucharmap/gucharmap-chartable.c Fri Mar 21 10:55:39 2008
@@ -145,6 +145,177 @@
g_signal_emit (chartable, signals[STATUS_MESSAGE], 0, message);
}
+/**
+ * position_rectangle:
+ * @rect: the rectangle to position
+ * @reference_point: point to position on
+ * @gravity: how to position @rect wrt. @reference_rect
+ * @direction: the text direction
+ * @keepout_rect: a rectangle to avoid. @reference_point must be one of its corners
+ * @bounding_rect: the bounding rectangle
+ *
+ * Returns: %TRUE if @rect could be positioned on @reference_point
+ * with positioning according to @gravity inside @bounding_rect
+ */
+static gboolean
+position_rectangle (GdkRectangle *position_rect,
+ GdkPoint *reference_point,
+ GdkGravity gravity,
+ GtkTextDirection direction,
+ GdkRectangle *keepout_rect,
+ GdkRectangle *bounding_rect)
+{
+ GdkRectangle rect;
+ gboolean is_rtl = direction == GTK_TEXT_DIR_RTL;
+
+ rect.x = reference_point->x;
+ rect.y = reference_point->y;
+ rect.width = position_rect->width;
+ rect.height = position_rect->height;
+
+ /* First position the rect on the reference point */
+ switch (gravity) {
+ case GDK_GRAVITY_NORTH_WEST:
+ case GDK_GRAVITY_NORTH:
+ case GDK_GRAVITY_NORTH_EAST:
+ rect.y -= rect.height;
+ break;
+ default:
+ break;
+ }
+
+ switch (gravity) {
+ case GDK_GRAVITY_NORTH_WEST:
+ case GDK_GRAVITY_WEST:
+ case GDK_GRAVITY_SOUTH_WEST:
+ if (!is_rtl)
+ rect.x -= rect.width;
+ break;
+
+ case GDK_GRAVITY_EAST:
+ case GDK_GRAVITY_SOUTH_EAST:
+ case GDK_GRAVITY_NORTH_EAST:
+ case GDK_GRAVITY_NORTH:
+ case GDK_GRAVITY_SOUTH:
+ if (is_rtl)
+ rect.x -= rect.width;
+ break;
+
+ default:
+ break;
+ }
+
+ /* If the rect intersects with @keepout_rect, we push it out */
+ if (gdk_rectangle_intersect (&rect, keepout_rect, NULL)) {
+ switch (gravity) {
+ case GDK_GRAVITY_NORTH_WEST:
+ case GDK_GRAVITY_NORTH:
+ case GDK_GRAVITY_NORTH_EAST:
+ rect.y -= keepout_rect->height;
+ break;
+
+ case GDK_GRAVITY_SOUTH_WEST:
+ case GDK_GRAVITY_SOUTH:
+ case GDK_GRAVITY_SOUTH_EAST:
+ rect.y += keepout_rect->height;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (gravity) {
+ case GDK_GRAVITY_NORTH_WEST:
+ case GDK_GRAVITY_SOUTH_WEST:
+ case GDK_GRAVITY_WEST:
+ if (!is_rtl)
+ rect.x -= keepout_rect->width;
+ break;
+
+ case GDK_GRAVITY_NORTH_EAST:
+ case GDK_GRAVITY_EAST:
+ case GDK_GRAVITY_SOUTH_EAST:
+ if (!is_rtl)
+ rect.x += keepout_rect->width;
+ break;
+
+ case GDK_GRAVITY_NORTH:
+ case GDK_GRAVITY_SOUTH:
+/* if (is_rtl)
+ rect.x -= keepout_rect->width;
+ else
+ rect.x += keepout_rect->width;*/
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (gdk_rectangle_intersect (&rect, keepout_rect, NULL)) {
+ g_warning ("Still intersecting with the keepout rect!\n");
+ }
+
+ *position_rect = rect;
+
+ return rect.x >= bounding_rect->x &&
+ rect.y >= bounding_rect->y &&
+ rect.x + rect.width <= bounding_rect->x + bounding_rect->width &&
+ rect.y + rect.height <= bounding_rect->y + bounding_rect->height;
+}
+
+static gboolean
+position_rectangle_on_screen (GtkWidget *widget,
+ GdkRectangle *rectangle,
+ GdkRectangle *keepout_rect)
+{
+ GtkTextDirection direction;
+ GdkRectangle monitor;
+ int monitor_num;
+ GdkPoint point;
+ GdkScreen *screen;
+
+ direction = gtk_widget_get_direction (widget);
+ screen = gtk_widget_get_screen (widget);
+ monitor_num = gdk_screen_get_monitor_at_window (screen, widget->window);
+ if (monitor_num < 0)
+ monitor_num = 0;
+ gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+
+ point.x = keepout_rect->x;
+ point.y = keepout_rect->y;
+
+ if (position_rectangle (rectangle,
+ &point,
+ GDK_GRAVITY_SOUTH,
+ direction,
+ keepout_rect,
+ &monitor))
+ return TRUE;
+ if (position_rectangle (rectangle,
+ &point,
+ GDK_GRAVITY_NORTH,
+ direction,
+ keepout_rect,
+ &monitor))
+ return TRUE;
+ if (position_rectangle (rectangle,
+ &point,
+ GDK_GRAVITY_EAST,
+ direction,
+ keepout_rect,
+ &monitor))
+ return TRUE;
+ if (position_rectangle (rectangle,
+ &point,
+ GDK_GRAVITY_WEST,
+ direction,
+ keepout_rect,
+ &monitor))
+ return TRUE;
+
+ return FALSE;
+}
static void
get_root_coords_at_active_char (GucharmapChartable *chartable,
@@ -164,26 +335,18 @@
*y_root = y + _gucharmap_chartable_y_offset (chartable, row);
}
-/* retunrs the coords of the innermost corner of the square */
static void
-get_appropriate_active_char_corner_xy (GucharmapChartable *chartable, gint *x, gint *y)
+get_active_cell_rect (GucharmapChartable *chartable, GdkRectangle *rect)
{
- gint x0, y0;
- gint row, col;
+ int row, col;
- get_root_coords_at_active_char (chartable, &x0, &y0);
+ get_root_coords_at_active_char (chartable, &rect->x, &rect->y);
row = (chartable->active_cell - chartable->page_first_cell) / chartable->cols;
col = _gucharmap_chartable_cell_column (chartable, chartable->active_cell);
- *x = x0;
- *y = y0;
-
- if (row < chartable->rows / 2)
- *y += _gucharmap_chartable_row_height (chartable, row);
-
- if (col < chartable->cols / 2)
- *x += _gucharmap_chartable_column_width (chartable, col);
+ rect->width = _gucharmap_chartable_column_width (chartable, col);
+ rect->height = _gucharmap_chartable_row_height (chartable, row);
}
static void
@@ -505,6 +668,30 @@
}
static void
+place_zoom_window_on_active_cell (GucharmapChartable *chartable)
+{
+ GdkPixmap *pixmap;
+ GdkRectangle rect, keepout_rect;
+
+ if (!chartable->zoom_window)
+ return;
+
+ gtk_image_get_pixmap (GTK_IMAGE (chartable->zoom_image), &pixmap, NULL);
+ if (!pixmap)
+ return;
+
+ get_active_cell_rect (chartable, &keepout_rect);
+
+ rect.x = rect.y = 0;
+ gdk_drawable_get_size (GDK_DRAWABLE (pixmap), &rect.width, &rect.height);
+
+ position_rectangle_on_screen (GTK_WIDGET (chartable),
+ &rect,
+ &keepout_rect);
+ gtk_window_move (GTK_WINDOW (chartable->zoom_window), rect.x, rect.y);
+}
+
+static void
update_zoom_window (GucharmapChartable *chartable)
{
GdkPixmap *pixmap;
@@ -557,17 +744,13 @@
static void
gucharmap_chartable_show_zoom (GucharmapChartable *chartable)
{
- gint x, y;
-
if (!chartable->zoom_mode_enabled)
return;
-
make_zoom_window (chartable);
update_zoom_window (chartable);
- get_appropriate_active_char_corner_xy (chartable, &x, &y);
- place_zoom_window (chartable, x, y);
+ place_zoom_window_on_active_cell (chartable);
gtk_widget_show (chartable->zoom_window);
@@ -1016,10 +1199,7 @@
if (move_zoom && chartable->zoom_window)
{
- gint x, y;
-
- get_appropriate_active_char_corner_xy (chartable, &x, &y);
- place_zoom_window (chartable, x, y);
+ place_zoom_window_on_active_cell (chartable);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]