1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
* filename: ximages.c *
4
* UTIL C-source: Medical Image Conversion Utility *
6
* purpose : image routines *
8
* project : (X)MedCon by Erik Nolf *
10
* Functions : XMdcRemovePreviousImages() - Remove old X images *
11
* XMdcImagesSetCursor() - Set cursor over X images *
12
* XMdcImagesCallbackExpose() - Images Expose callback *
13
* XMdcImagesCallbackClicked() - Images Clicked callback *
14
* XMdcBuildCurrentImages() - Build images for display *
15
* XMdcDisplayImages() - Display the images *
16
* XMdcImagesView() - Show the images (viewer) *
18
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
19
/* $Id: ximages.c,v 1.17 2004/05/09 22:48:04 enlf Exp $
23
Copyright (C) 1997-2004 by Erik Nolf
25
This program is free software; you can redistribute it and/or modify it
26
under the terms of the GNU General Public License as published by the
27
Free Software Foundation; either version 2, or (at your option) any later
30
This program is distributed in the hope that it will be useful, but
31
WITHOUT ANY WARRANTY; without even the implied warranty of
32
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
33
Public License for more details.
35
You should have received a copy of the GNU General Public License along
36
with this program; if not, write to the Free Software Foundation, Inc.,
37
59 Place - Suite 330, Boston, MA 02111-1307, USA. */
39
/****************************************************************************
41
****************************************************************************/
47
/****************************************************************************
49
****************************************************************************/
51
#ifdef MDC_USE_SIGNAL_BLOCKER
53
* MARK: dirty fix of bad button-press-event behaviour in _WIN32
55
* The button-press-events of our image's drawing areas seems to be
56
* "propagated" over all our widgets ... We got for example zoom or info
57
* windows by clicking on places we wouldn't expect this to happen.
59
* So we 're blocking this button-press-event whenever we leave the
60
* corresponding drawing area (and ofcourse, reallowing when entering)
62
* However, the gtk_signal_handler_block() function increments a number
63
* instead of using a simple boolean. Whenever the "enter_notify_event"
64
* is missed ... this number will never drop to zero again. And it does
65
* happen when widgets come in front of our drawing areas which are rebuild
66
* because of a color correction or colormap change.
68
* Our SignalBlocker struct should prevent the gtk_signal_handler_block()
69
* function being called several times ...
71
* Actual struct defined in xdefs.h:
72
typedef struct SignalBlocker_t{
81
static gboolean XMdcSignalBlock(GtkWidget *widget, gpointer data)
83
SignalBlocker *signal;
85
signal = (SignalBlocker *)gtk_object_get_data(GTK_OBJECT(widget),"signal");
87
if (!signal->blocked) {
88
gtk_signal_handler_block(GTK_OBJECT(widget),signal->id);
89
signal->blocked = TRUE;
96
static gboolean XMdcSignalUnblock(GtkWidget *widget, gpointer data)
98
SignalBlocker *signal;
100
signal = (SignalBlocker *)gtk_object_get_data(GTK_OBJECT(widget),"signal");
102
if (signal->blocked) {
103
gtk_signal_handler_unblock(GTK_OBJECT(widget),signal->id);
104
signal->blocked = FALSE;
112
void XMdcRemovePreviousImages(void)
116
for (i=0; i<my.real_images_on_page; i++) {
117
gtk_widget_hide(my.image[i]);
118
gdk_pixbuf_unref(my.im[i]); my.im[i] = NULL;
122
void XMdcImagesSetCursor(GtkWidget *widget, gpointer data)
124
if (widget->window != NULL)
125
gdk_window_set_cursor (widget->window, handcursor);
129
gboolean XMdcImagesCallbackExpose(GtkWidget *widget, GdkEventExpose *event, Uint32 *nr)
131
GdkGC *gc = widget->style->white_gc;
132
Uint32 i = (Uint32)(*nr);
133
gint ex, ey, ew, eh, iw, ih, rw, rh;
135
if ( my.im[i] == NULL ) return(TRUE);
137
/* repaint the polluted drawable */
138
iw = gdk_pixbuf_get_width(my.im[i]);
139
ih = gdk_pixbuf_get_height(my.im[i]);
141
ex = event->area.x; ey = event->area.y;
142
ew = event->area.width; eh = event->area.height;
144
if ((ex < iw) && (ey < ih)) {
145
rw = iw - ex; rh = ih - ey;
146
gdk_pixbuf_render_to_drawable(my.im[i], widget->window, gc,
147
ex, ey, ex, ey, rw, rh,
148
sRenderSelection.Dither, 0, 0);
151
if ((ex + ew) > iw) {
152
rw = (ex + ew) - iw; rh = eh;
153
gdk_window_clear_area(widget->window, iw, ey, rw, rh);
156
if ((ey + eh) > ih) {
157
rh = (ey + eh) - ih; rw = ew;
158
gdk_window_clear_area(widget->window, ex, ih, rw, rh);
161
if (sLabelSelection.CurState == MDC_YES) {
162
XMdcPrintImageLabelIndex(widget,i);
163
XMdcPrintImageLabelTimes(widget,i);
169
gboolean XMdcImagesCallbackClicked(GtkWidget *widget, GdkEventButton *button, Uint32 *nr)
172
if (button->button == 1) {
174
XMdcImagesZoom(widget,(Uint32)(*nr));
177
if (button->button == 2) {
178
/* print image info */
179
XMdcImagesInfo(widget,(Uint32)(*nr));
182
if (button->button == 3) {
183
/* color correction */
184
XMdcColGbcCorrectSel(widget,(Uint32)(*nr));
191
void XMdcBuildCurrentImages(void)
197
MdcDebugPrint("Building current images ...");
199
real_images = XMdcPagesGetNrImages();
201
/* get real_images_per_page and number of the beginning image */
202
if (real_images < my.images_per_page) {
203
/* always lesser images on page */
204
my.real_images_on_page = real_images;
205
my.startimage = my.curpage * real_images;
207
if (my.curpage == my.number_of_pages - 1) {
208
/* last page, probably less images on it */
209
my.real_images_on_page = my.fi->number - (my.curpage*my.images_per_page);
210
my.startimage = my.curpage * my.images_per_page;
212
/* other pages completely filled out */
213
my.real_images_on_page = my.images_per_page;
214
my.startimage = my.curpage * my.images_per_page;
218
progress = 1./(float)(my.real_images_on_page + 1);
220
/* build the images */
221
i = my.startimage; ri=0;
222
for (r=0; r<my.images_vertical; r++)
223
for (c=0; c<my.images_horizontal; c++,i++, ri++) {
225
#ifdef MDC_USE_SIGNAL_BLOCKER
226
SignalBlocker *signal = (SignalBlocker *)&my.sblkr[ri];
229
progress += 1./(float)(my.real_images_on_page + 1);
231
if (ri == my.real_images_on_page) break; /* get OUT, got all images */
233
my.realnumber[ri] = i;
235
my.im[ri] = XMdcBuildGdkPixbufFI(my.fi,i,sGbc.mod.vgbc,MDC_YES);
237
if (my.image[ri] == NULL) {
239
my.image[ri] = gtk_drawing_area_new();
241
gtk_drawing_area_size(GTK_DRAWING_AREA(my.image[ri])
242
,(gint)(XMdcResize(my.fi->mwidth) + XMDC_IMAGE_BORDER)
243
,(gint)(XMdcResize(my.fi->mheight) + XMDC_IMAGE_BORDER));
245
gtk_widget_set_events (my.image[ri], GDK_EXPOSURE_MASK
246
| GDK_BUTTON_PRESS_MASK
247
#ifdef MDC_USE_SIGNAL_BLOCKER
248
| GDK_ENTER_NOTIFY_MASK
249
| GDK_LEAVE_NOTIFY_MASK
253
gtk_table_attach(GTK_TABLE(my.imgstable),my.image[ri],c,c+1,r,r+1,
254
GTK_FILL,GTK_FILL, 0, 0);
256
#ifdef MDC_USE_SIGNAL_BLOCKER
259
gtk_signal_connect (GTK_OBJECT(my.image[ri]), "button_press_event",
260
GTK_SIGNAL_FUNC(XMdcImagesCallbackClicked),
261
(Uint32 *)&my.imagenumber[ri]);
263
gtk_signal_connect (GTK_OBJECT(my.image[ri]),"expose_event",
264
GTK_SIGNAL_FUNC(XMdcImagesCallbackExpose),
265
(Uint32 *)&my.imagenumber[ri]);
267
#ifdef MDC_USE_SIGNAL_BLOCKER
268
gtk_signal_connect (GTK_OBJECT(my.image[ri]),"enter_notify_event",
269
GTK_SIGNAL_FUNC(XMdcSignalUnblock), NULL);
271
gtk_signal_connect (GTK_OBJECT(my.image[ri]),"leave_notify_event",
272
GTK_SIGNAL_FUNC(XMdcSignalBlock), NULL);
274
gtk_object_set_data(GTK_OBJECT(my.image[ri]),"signal",signal);
276
XMdcSignalBlock(my.image[ri],NULL);
279
XMdcImagesSetCursor(my.image[ri],NULL);
283
gtk_widget_show(my.image[ri]);
286
if (GTK_WIDGET_VISIBLE(my.viewwindow)) {
287
if (my.images_horizontal < 10) {
288
/* update after each two rows */
289
if (((ri+1)%(my.images_horizontal*2)) == 0)
290
XMdcProgressBar(MDC_PROGRESS_SET,progress,NULL);
292
/* update after each five rows */
293
if (((ri+1)%(my.images_horizontal*5)) == 0)
294
XMdcProgressBar(MDC_PROGRESS_SET,progress,NULL);
297
/* update after each image */
298
XMdcProgressBar(MDC_PROGRESS_SET,progress,NULL);
303
void XMdcDisplayImages(void)
305
XMdcProgressBar(MDC_PROGRESS_BEGIN,0.,"Preparing Viewer:");
306
XMdcGetBoardDimensions();
307
XMdcHandleBoardDimensions();
308
XMdcBuildViewerWindow();
310
XMdcBuildCurrentImages();
312
gtk_container_foreach(GTK_CONTAINER(my.imgstable),
313
(GtkCallback)XMdcImagesSetCursor,NULL);
316
void XMdcImagesView(GtkWidget *widget, gpointer data)
318
if (XMdcNoFileOpened()) return;