233 lines
6.2 KiB
C
233 lines
6.2 KiB
C
/* -*- 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 mutter, 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,
|
|
cairo_t *cr,
|
|
const WnckWindowDisplayInfo *win,
|
|
const GdkRectangle *winrect,
|
|
GtkStateType state)
|
|
{
|
|
GdkPixbuf *icon;
|
|
int icon_x, icon_y, icon_w, icon_h;
|
|
gboolean is_active;
|
|
GdkColor *color;
|
|
GtkStyle *style;
|
|
|
|
is_active = win->is_active;
|
|
|
|
cairo_save (cr);
|
|
|
|
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_restore (cr);
|
|
}
|
|
|
|
void
|
|
wnck_draw_workspace (GtkWidget *widget,
|
|
cairo_t *cr,
|
|
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;
|
|
GtkStyle *style;
|
|
|
|
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;
|
|
|
|
style = gtk_widget_get_style (widget);
|
|
|
|
cairo_save (cr);
|
|
|
|
if (workspace_background)
|
|
{
|
|
gdk_cairo_set_source_pixbuf (cr, workspace_background, x, y);
|
|
cairo_paint (cr);
|
|
}
|
|
else
|
|
{
|
|
gdk_cairo_set_source_color (cr, &style->dark[state]);
|
|
cairo_rectangle (cr, x, y, width, height);
|
|
cairo_fill (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,
|
|
cr,
|
|
win,
|
|
&winrect,
|
|
state);
|
|
|
|
++i;
|
|
}
|
|
|
|
cairo_restore (cr);
|
|
|
|
}
|