diff --git a/ChangeLog b/ChangeLog index 8ad83ee9e..1a8cccfbf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2002-06-15 Havoc Pennington + + * src/draw-workspace.h, src/draw-workspace.c: workspace-drawing + code factored out of libwnck, needs wiring up to tabpopup.c + (which is kind of annoying since you have to get the list of + workspaces and MetaWindow across the barrier between the GDK-aware + and non-GDK-aware sides of metacity) + 2002-06-14 Havoc Pennington * src/window.c (meta_window_show): always focus new windows, diff --git a/src/Makefile.am b/src/Makefile.am index f2c219907..5f22dbbaa 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,6 +10,8 @@ metacity_SOURCES= \ delete.c \ display.c \ display.h \ + draw-workspace.c \ + draw-workspace.h \ effects.c \ effects.h \ errors.c \ diff --git a/src/draw-workspace.c b/src/draw-workspace.c new file mode 100644 index 000000000..a55c10f8f --- /dev/null +++ b/src/draw-workspace.c @@ -0,0 +1,218 @@ +/* Draw a workspace */ + +/* This file should not be modified to depend on other files in + * libwnck or metacity, since it's used in both of them + */ + +/* + * Copyright (C) 2002 Red Hat Inc. + * + * 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 "draw-workspace.h" + + +static void +get_window_rect (const WnckWindowDisplayInfo *win, + int screen_width, + int screen_height, + const GdkRectangle *workspace_rect, + GdkRectangle *rect) +{ + double width_ratio, height_ratio; + int x, y, width, height; + + width_ratio = (double) workspace_rect->width / (double) screen_width; + height_ratio = (double) workspace_rect->height / (double) screen_height; + + x = win->x; + y = win->y; + width = win->width; + height = win->height; + + x *= width_ratio; + y *= height_ratio; + width *= width_ratio; + height *= height_ratio; + + x += workspace_rect->x; + y += workspace_rect->y; + + if (width < 3) + width = 3; + if (height < 3) + height = 3; + + rect->x = x; + rect->y = y; + rect->width = width; + rect->height = height; +} + +static void +draw_window (GtkWidget *widget, + GdkDrawable *drawable, + const WnckWindowDisplayInfo *win, + const GdkRectangle *winrect) +{ + GdkPixbuf *icon; + int icon_x, icon_y, icon_w, icon_h; + + gdk_draw_rectangle (drawable, + win->is_active ? + widget->style->bg_gc[GTK_STATE_SELECTED] : + widget->style->bg_gc[GTK_STATE_NORMAL], + TRUE, + winrect->x + 1, winrect->y + 1, + winrect->width - 2, winrect->height - 2); + + icon = win->icon; + + icon_w = icon_h = 0; + + if (icon) + { + icon_w = gdk_pixbuf_get_width (icon); + icon_h = gdk_pixbuf_get_height (icon); + + /* If the icon is too big, fall back to mini icon. + * We don't arbitrarily scale the icon, because it's + * just too slow on my Athlon 850. + */ + if (icon_w > (winrect->width - 2) || + icon_h > (winrect->height - 2)) + { + icon = win->mini_icon; + if (icon) + { + icon_w = gdk_pixbuf_get_width (icon); + icon_h = gdk_pixbuf_get_height (icon); + + /* Give up. */ + if (icon_w > (winrect->width - 2) || + icon_h > (winrect->height - 2)) + icon = NULL; + } + } + } + + if (icon) + { + icon_x = winrect->x + (winrect->width - icon_w) / 2; + icon_y = winrect->y + (winrect->height - icon_h) / 2; + + { + /* render_to_drawable should take a clip rect to save + * us this mess... + */ + GdkRectangle pixbuf_rect; + GdkRectangle draw_rect; + + pixbuf_rect.x = icon_x; + pixbuf_rect.y = icon_y; + pixbuf_rect.width = icon_w; + pixbuf_rect.height = icon_h; + + if (gdk_rectangle_intersect ((GdkRectangle *)winrect, &pixbuf_rect, + &draw_rect)) + { + gdk_pixbuf_render_to_drawable_alpha (icon, + drawable, + draw_rect.x - pixbuf_rect.x, + draw_rect.y - pixbuf_rect.y, + draw_rect.x, draw_rect.y, + draw_rect.width, + draw_rect.height, + GDK_PIXBUF_ALPHA_FULL, + 128, + GDK_RGB_DITHER_NORMAL, + 0, 0); + } + } + } + + gdk_draw_rectangle (drawable, + win->is_active ? + widget->style->fg_gc[GTK_STATE_SELECTED] : + widget->style->fg_gc[GTK_STATE_NORMAL], + FALSE, + winrect->x, winrect->y, + winrect->width - 1, winrect->height - 1); +} + +void +wnck_draw_workspace (GtkWidget *widget, + GdkDrawable *drawable, + int x, + int y, + int width, + int height, + int screen_width, + int screen_height, + GdkPixbuf *workspace_background, + gboolean is_active, + const WnckWindowDisplayInfo *windows, + int n_windows) +{ + int i; + GdkRectangle workspace_rect; + + workspace_rect.x = x; + workspace_rect.y = y; + workspace_rect.width = width; + workspace_rect.height = height; + + + if (is_active) + gdk_draw_rectangle (drawable, + GTK_WIDGET (widget)->style->dark_gc[GTK_STATE_SELECTED], + TRUE, + x, y, width, height); + else if (workspace_background) + { + gdk_pixbuf_render_to_drawable (workspace_background, + drawable, + GTK_WIDGET (widget)->style->dark_gc[GTK_STATE_SELECTED], + 0, 0, + x, y, + -1, -1, + GDK_RGB_DITHER_MAX, + 0, 0); + } + else + gdk_draw_rectangle (drawable, + GTK_WIDGET (widget)->style->dark_gc[GTK_STATE_NORMAL], + TRUE, + x, y, width, height); + + + i = 0; + while (i < n_windows) + { + const WnckWindowDisplayInfo *win = &windows[i]; + GdkRectangle winrect; + + get_window_rect (win, screen_width, screen_height, &workspace_rect, &winrect); + + draw_window (widget, + drawable, + win, + &winrect); + + ++i; + } +} diff --git a/src/draw-workspace.h b/src/draw-workspace.h new file mode 100644 index 000000000..19b203d9e --- /dev/null +++ b/src/draw-workspace.h @@ -0,0 +1,59 @@ +/* Draw a workspace */ + +/* This file should not be modified to depend on other files in + * libwnck or metacity, since it's used in both of them + */ + +/* + * Copyright (C) 2002 Red Hat Inc. + * + * 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. + */ + +#ifndef WNCK_DRAW_WORKSPACE_H +#define WNCK_DRAW_WORKSPACE_H + +#include +#include +#include + +typedef struct +{ + GdkPixbuf *icon; + GdkPixbuf *mini_icon; + int x; + int y; + int width; + int height; + + guint is_active : 1; + +} WnckWindowDisplayInfo; + +void wnck_draw_workspace (GtkWidget *widget, + GdkDrawable *drawable, + int x, + int y, + int width, + int height, + int screen_width, + int screen_height, + GdkPixbuf *workspace_background, + gboolean is_active, + const WnckWindowDisplayInfo *windows, + int n_windows); + +#endif