1 /*
2 * Copyright(c) 1992 Bell Communications Research, Inc. (Bellcore)
3 * Copyright(c) 1995-99 Andrew Lister
4 * Copyright � 1999, 2000, 2001, 2002, 2003, 2004 by the LessTif Developers.
5 *
6 * All rights reserved
7 * Permission to use, copy, modify and distribute this material for
8 * any purpose and without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies, and that the name of Bellcore not be used in advertising
11 * or publicity pertaining to this material without the specific,
12 * prior written permission of an authorized representative of
13 * Bellcore.
14 *
15 * BELLCORE MAKES NO REPRESENTATIONS AND EXTENDS NO WARRANTIES, EX-
16 * PRESS OR IMPLIED, WITH RESPECT TO THE SOFTWARE, INCLUDING, BUT
17 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 * FITNESS FOR ANY PARTICULAR PURPOSE, AND THE WARRANTY AGAINST IN-
19 * FRINGEMENT OF PATENTS OR OTHER INTELLECTUAL PROPERTY RIGHTS. THE
20 * SOFTWARE IS PROVIDED "AS IS", AND IN NO EVENT SHALL BELLCORE OR
21 * ANY OF ITS AFFILIATES BE LIABLE FOR ANY DAMAGES, INCLUDING ANY
22 * LOST PROFITS OR OTHER INCIDENTAL OR CONSEQUENTIAL DAMAGES RELAT-
23 * ING TO THE SOFTWARE.
24 *
25 * $Id: Shadow.c,v 1.29 2005/04/06 23:13:14 tobiasoed Exp $
26 */
27
28 /*
29 * Shadow.c created by Andrew Lister (30 October, 1995)
30 */
31
32
33 #ifdef HAVE_CONFIG_H
34 #include <XbaeConfig.h>
35 #endif
36
37 #include <stdio.h>
38
39 #include <Xm/Xm.h>
40 #include <Xm/XmP.h>
41 #include <Xm/DrawP.h>
42 #include <Xbae/MatrixP.h>
43 #include <Xbae/Shadow.h>
44 #include <Xbae/Draw.h>
45 #include <Xbae/Utils.h>
46
47 #include <XbaeDebug.h>
48
49 static void DrawRowShadow(XbaeMatrixWidget, Window, int, int, int, int, int, int, GC, GC, unsigned char shadow);
50 static void DrawColumnShadow(XbaeMatrixWidget, Window, int, int, int, int, int, int, GC, GC, unsigned char shadow);
51
52 static void DrawRowHighlight(XbaeMatrixWidget, Window, GC, int, int, int, int, int, int);
53 static void DrawColumnHighlight(XbaeMatrixWidget, Window, GC, int, int, int, int, int, int);
54
55 void
xbaeDrawLabelShadow(XbaeMatrixWidget mw,Window win,int x,int y,int width,int height,Boolean pressed)56 xbaeDrawLabelShadow(XbaeMatrixWidget mw, Window win, int x, int y, int width, int height,
57 Boolean pressed)
58 {
59 if (mw->matrix.cell_shadow_thickness == 0) {
60 return;
61 }
62
63 /*
64 * Surround the label with a shadow.
65 */
66
67 DRAW_SHADOW(XtDisplay(mw), win, "win",
68 mw->manager.top_shadow_GC, mw->manager.bottom_shadow_GC,
69 mw->matrix.cell_shadow_thickness, x, y, width, height,
70 pressed ? XmSHADOW_IN : XmSHADOW_OUT);
71 }
72
73 void
xbaeDrawCellShadow(XbaeMatrixWidget mw,Window win,int row,int column,int x,int y,int width,int height)74 xbaeDrawCellShadow(XbaeMatrixWidget mw, Window win, int row, int column, int x, int y, int width, int height)
75 {
76 GC top_shadow_gc = mw->manager.top_shadow_GC;
77 GC bottom_shadow_gc = mw->manager.bottom_shadow_GC;
78 GC grid_line_gc = mw->matrix.grid_line_gc;
79
80 unsigned char shadow = mw->matrix.cell_shadow_type;
81 unsigned char grid_type = mw->matrix.grid_type;
82
83 /* amai, that's too verbose ...*/
84 DEBUGOUT(_XbaeDebug
85 (__FILE__, (Widget) mw, "xbaeDrawCellShadow [%d,%d] wid %d, ht %d\n", row, column,
86 width, height));
87
88 if (mw->matrix.cell_shadow_thickness == 0) {
89 return;
90 }
91
92 if (mw->matrix.per_cell && mw->matrix.per_cell[row][column].shadow_type != 0) {
93 shadow = mw->matrix.per_cell[row][column].shadow_type;
94 grid_type = XmGRID_CELL_SHADOW;
95 } else if (IN_GRID_ROW_MODE(mw) && mw->matrix.row_shadow_types && mw->matrix.row_shadow_types[row] != 0) {
96 shadow = mw->matrix.row_shadow_types[row];
97 grid_type = XmGRID_ROW_SHADOW;
98 } else if (IN_GRID_COLUMN_MODE(mw) && mw->matrix.column_shadow_types && mw->matrix.column_shadow_types[column] != 0) {
99 shadow = mw->matrix.column_shadow_types[column];
100 grid_type = XmGRID_COLUMN_SHADOW;
101 }
102
103 /*
104 * Surround the cell with a shadow.
105 */
106 switch (grid_type) {
107 case XmGRID_NONE:
108 break;
109 case XmGRID_ROW_SHADOW:
110 DrawRowShadow(mw, win, row, column, x, y, width, height,
111 top_shadow_gc, bottom_shadow_gc, shadow);
112 break;
113 case XmGRID_ROW_LINE:
114 DrawRowShadow(mw, win, row, column, x, y, width, height,
115 grid_line_gc, grid_line_gc, shadow);
116 break;
117 case XmGRID_COLUMN_SHADOW:
118 DrawColumnShadow(mw, win, row, column, x, y, width, height,
119 top_shadow_gc, bottom_shadow_gc, shadow);
120 break;
121 case XmGRID_COLUMN_LINE:
122 DrawColumnShadow(mw, win, row, column, x, y, width, height,
123 grid_line_gc, grid_line_gc, shadow);
124 break;
125 case XmGRID_CELL_LINE:
126 DRAW_SHADOW(XtDisplay(mw), win, "win",
127 grid_line_gc, grid_line_gc,
128 mw->matrix.cell_shadow_thickness, x, y, width, height, shadow);
129 break;
130 case XmGRID_CELL_SHADOW:
131 DRAW_SHADOW(XtDisplay(mw), win, "win",
132 top_shadow_gc, bottom_shadow_gc,
133 mw->matrix.cell_shadow_thickness, x, y, width, height, shadow);
134 break;
135
136 /* Deprecated types. To be removed in next version. */
137 case XmGRID_LINE:
138 DRAW_SHADOW(XtDisplay(mw), win, "win",
139 grid_line_gc, grid_line_gc,
140 mw->matrix.cell_shadow_thickness, x, y, width, height, shadow);
141 break;
142 case XmGRID_SHADOW_OUT:
143 DRAW_SHADOW(XtDisplay(mw), win, "win",
144 bottom_shadow_gc, top_shadow_gc,
145 mw->matrix.cell_shadow_thickness, x, y, width, height, shadow);
146 break;
147 case XmGRID_SHADOW_IN:
148 DRAW_SHADOW(XtDisplay(mw), win, "win",
149 top_shadow_gc, bottom_shadow_gc,
150 mw->matrix.cell_shadow_thickness, x, y, width, height, shadow);
151 break;
152 }
153 }
154
155 void
xbaeDrawCellHighlight(XbaeMatrixWidget mw,Window win,GC gc,int row,int column,int x,int y,int width,int height,unsigned char hl)156 xbaeDrawCellHighlight(XbaeMatrixWidget mw, Window win, GC gc, int row, int column,
157 int x, int y, int width, int height, unsigned char hl)
158 {
159 int thick = mw->matrix.cell_shadow_thickness;
160
161 DEBUGOUT(_XbaeDebug
162 (__FILE__, (Widget) mw, "xbaeDrawCellHighlight [%d,%d], wid %d, ht %d\n", row,
163 column, width, height));
164
165 if (IN_GRID_ROW_MODE(mw) && (hl & HighlightRow)) {
166 DrawRowHighlight(mw, win, gc, row, column, x, y, width, height);
167 } else if (IN_GRID_COLUMN_MODE(mw) && (hl & HighlightColumn)) {
168 DrawColumnHighlight(mw, win, gc, row, column, x, y, width, height);
169 } else if (hl) {
170 DRAW_HIGHLIGHT(XtDisplay(mw), win, gc,
171 x + thick, y + thick, width - 2 * thick, height - 2 * thick,
172 mw->matrix.cell_highlight_thickness, LineSolid);
173 }
174 }
175
176 static void
DrawRowHighlight(XbaeMatrixWidget mw,Window win,GC gc,int row,int column,int x,int y,int width,int height)177 DrawRowHighlight(XbaeMatrixWidget mw, Window win, GC gc, int row, int column, int x, int y,
178 int width, int height)
179 {
180 XRectangle rect;
181
182 DEBUGOUT(_XbaeDebug
183 (__FILE__, (Widget) mw, "DrawRowHighlight [%d,%d] wid %d ht %d\n", row, column,
184 width, height));
185
186 rect.x = x;
187 rect.y = y;
188 rect.width = width;
189 rect.height = height;
190
191 XSetClipRectangles(XtDisplay(mw), gc, 0, 0, &rect, 1, Unsorted);
192
193 /*
194 * The highlight is inside the cell shadow
195 */
196 x += mw->matrix.cell_shadow_thickness;
197 y += mw->matrix.cell_shadow_thickness;
198 width -= 2 * mw->matrix.cell_shadow_thickness;
199 height -= 2 * mw->matrix.cell_shadow_thickness;
200
201 /*
202 * Make sure the left/right edge are outside the clipping recangle if this
203 * is not the first/last column
204 */
205 if (column != 0) {
206 x -= mw->matrix.cell_shadow_thickness + mw->matrix.cell_highlight_thickness;
207 width += mw->matrix.cell_shadow_thickness + mw->matrix.cell_highlight_thickness;
208 }
209 if (column != mw->matrix.columns - 1) {
210 width += mw->matrix.cell_shadow_thickness + mw->matrix.cell_highlight_thickness;
211 }
212
213 DRAW_HIGHLIGHT(XtDisplay(mw), win, gc, x, y, width, height,
214 mw->matrix.cell_highlight_thickness, LineSolid);
215
216 XSetClipMask(XtDisplay(mw), gc, None);
217 }
218
219 static void
DrawColumnHighlight(XbaeMatrixWidget mw,Window win,GC gc,int row,int column,int x,int y,int width,int height)220 DrawColumnHighlight(XbaeMatrixWidget mw, Window win, GC gc, int row, int column, int x, int y,
221 int width, int height)
222 {
223 XRectangle rect;
224
225 DEBUGOUT(_XbaeDebug
226 (__FILE__, (Widget) mw, "DrawRowHighlight [%d,%d] wid %d ht %d\n", row, column,
227 width, height));
228
229 rect.x = x;
230 rect.y = y;
231 rect.width = width;
232 rect.height = height;
233
234 XSetClipRectangles(XtDisplay(mw), gc, 0, 0, &rect, 1, Unsorted);
235
236 /*
237 * The highlight is inside the cell shadow
238 */
239 x += mw->matrix.cell_shadow_thickness;
240 y += mw->matrix.cell_shadow_thickness;
241 width -= 2 * mw->matrix.cell_shadow_thickness;
242 height -= 2 * mw->matrix.cell_shadow_thickness;
243
244 /*
245 * Make sure the top/bottom edge are outside the clipping recangle if this
246 * is not the first/last row
247 */
248 if (row != 0) {
249 y -= mw->matrix.cell_shadow_thickness + mw->matrix.cell_highlight_thickness;
250 height += mw->matrix.cell_shadow_thickness + mw->matrix.cell_highlight_thickness;
251 }
252 if (row != mw->matrix.rows - 1) {
253 height += mw->matrix.cell_shadow_thickness + mw->matrix.cell_highlight_thickness;
254 }
255
256 DRAW_HIGHLIGHT(XtDisplay(mw), win, gc, x, y, width, height,
257 mw->matrix.cell_highlight_thickness, LineSolid);
258
259 XSetClipMask(XtDisplay(mw), gc, None);
260 }
261
262 static void
DrawRowShadow(XbaeMatrixWidget mw,Window win,int row,int column,int x,int y,int width,int height,GC topGC,GC bottomGC,unsigned char shadow)263 DrawRowShadow(XbaeMatrixWidget mw, Window win, int row, int column, int x, int y, int width,
264 int height, GC topGC, GC bottomGC, unsigned char shadow)
265 {
266 XRectangle rect;
267
268 /*
269 * Set up a clipping rectangle over the current cell.
270 */
271 rect.x = x;
272 rect.y = y;
273 rect.width = width;
274 rect.height = height;
275
276 XSetClipRectangles(XtDisplay(mw), topGC, 0, 0, &rect, 1, Unsorted);
277 if (topGC != bottomGC)
278 XSetClipRectangles(XtDisplay(mw), bottomGC, 0, 0, &rect, 1, Unsorted);
279
280 /*
281 * Make sure the left/right edge are outside the clipping recangle if this
282 * is not the first/last column
283 */
284 if (column != 0) {
285 x -= mw->matrix.cell_shadow_thickness;
286 width += mw->matrix.cell_shadow_thickness;
287 }
288 if (column != mw->matrix.columns - 1) {
289 width += mw->matrix.cell_shadow_thickness;
290 }
291
292 DRAW_SHADOW(XtDisplay(mw), win, "win", topGC, bottomGC,
293 mw->matrix.cell_shadow_thickness, x, y, width, height, shadow);
294
295 XSetClipMask(XtDisplay(mw), topGC, None);
296 if (topGC != bottomGC)
297 XSetClipMask(XtDisplay(mw), bottomGC, None);
298 }
299
300 static void
DrawColumnShadow(XbaeMatrixWidget mw,Window win,int row,int column,int x,int y,int width,int height,GC topGC,GC bottomGC,unsigned char shadow)301 DrawColumnShadow(XbaeMatrixWidget mw, Window win, int row, int column, int x, int y, int width,
302 int height, GC topGC, GC bottomGC, unsigned char shadow)
303 {
304 XRectangle rect;
305
306 /*
307 * Set up a clipping rectangle over the current cell.
308 */
309 rect.x = x;
310 rect.y = y;
311 rect.width = width;
312 rect.height = height;
313
314 XSetClipRectangles(XtDisplay(mw), topGC, 0, 0, &rect, 1, Unsorted);
315 if (topGC != bottomGC)
316 XSetClipRectangles(XtDisplay(mw), bottomGC, 0, 0, &rect, 1, Unsorted);
317
318 /*
319 * Make sure the top/bottom edge are outside the clipping recangle if this
320 * is not the first/last row
321 */
322 if (row != 0) {
323 y -= mw->matrix.cell_shadow_thickness;
324 height += mw->matrix.cell_shadow_thickness;
325 }
326 if (row != mw->matrix.rows - 1) {
327 height += mw->matrix.cell_shadow_thickness;
328 }
329
330 DRAW_SHADOW(XtDisplay(mw), win, "win", topGC, bottomGC,
331 mw->matrix.cell_shadow_thickness, x, y, width, height, shadow);
332
333 XSetClipMask(XtDisplay(mw), topGC, None);
334 if (topGC != bottomGC)
335 XSetClipMask(XtDisplay(mw), bottomGC, None);
336 }
337