diff options
Diffstat (limited to 'src/ui/draw-workspace.c')
-rw-r--r-- | src/ui/draw-workspace.c | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/src/ui/draw-workspace.c b/src/ui/draw-workspace.c new file mode 100644 index 00000000..b1a7c733 --- /dev/null +++ b/src/ui/draw-workspace.c @@ -0,0 +1,229 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* Draw a workspace */ + +/* This file should not be modified to depend on other files in + * libwnck or marco, 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, + GtkStateType state) +{ + cairo_t *cr; + GdkPixbuf *icon; + int icon_x, icon_y, icon_w, icon_h; + gboolean is_active; + GdkColor *color; + GtkStyle *style; + + is_active = win->is_active; + + cr = gdk_cairo_create (drawable); + cairo_rectangle (cr, winrect->x, winrect->y, winrect->width, winrect->height); + cairo_clip (cr); + + style = gtk_widget_get_style (widget); + if (is_active) + color = &style->light[state]; + else + color = &style->bg[state]; + cairo_set_source_rgb (cr, + color->red / 65535., + color->green / 65535., + color->blue / 65535.); + + cairo_rectangle (cr, + winrect->x + 1, winrect->y + 1, + MAX (0, winrect->width - 2), MAX (0, winrect->height - 2)); + cairo_fill (cr); + + + 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; + + cairo_save (cr); + gdk_cairo_set_source_pixbuf (cr, icon, icon_x, icon_y); + cairo_rectangle (cr, icon_x, icon_y, icon_w, icon_h); + cairo_clip (cr); + cairo_paint (cr); + cairo_restore (cr); + } + + if (is_active) + color = &style->fg[state]; + else + color = &style->fg[state]; + + cairo_set_source_rgb (cr, + color->red / 65535., + color->green / 65535., + color->blue / 65535.); + cairo_set_line_width (cr, 1.0); + cairo_rectangle (cr, + winrect->x + 0.5, winrect->y + 0.5, + MAX (0, winrect->width - 1), MAX (0, winrect->height - 1)); + cairo_stroke (cr); + + cairo_destroy (cr); +} + +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; + GtkStateType state; + cairo_t *cr; + + workspace_rect.x = x; + workspace_rect.y = y; + workspace_rect.width = width; + workspace_rect.height = height; + + if (is_active) + state = GTK_STATE_SELECTED; + else if (workspace_background) + state = GTK_STATE_PRELIGHT; + else + state = GTK_STATE_NORMAL; + + cr = gdk_cairo_create (drawable); + + if (workspace_background) + { + gdk_cairo_set_source_pixbuf (cr, workspace_background, x, y); + cairo_paint (cr); + } + else + { + gdk_cairo_set_source_color (cr, >k_widget_get_style (widget)->dark[state]); + cairo_rectangle (cr, x, y, width, height); + cairo_fill (cr); + } + + cairo_destroy (cr); + + 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, + state); + + ++i; + } +} |