From c3b63c96d7180ed4fcae14afcd0e88bae3c2d3c9 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Sat, 15 Jun 2002 22:18:12 +0000 Subject: [PATCH] workspace-drawing code factored out of libwnck, needs wiring up to 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) --- ChangeLog | 8 ++ src/Makefile.am | 2 + src/draw-workspace.c | 218 +++++++++++++++++++++++++++++++++++++++++++ src/draw-workspace.h | 59 ++++++++++++ 4 files changed, 287 insertions(+) create mode 100644 src/draw-workspace.c create mode 100644 src/draw-workspace.h 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