/* Note that this widget depends only on image machinery, and has
no knowledge of Xconq constructs such as units and sides. */
-#include "config.h"
-#include "misc.h"
-#include "lisp.h"
-#include "imf.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For tcltk 8.4.0 source compatibility. */
+#define USE_NON_CONST
+#ifdef MAC
+#include <tclMacCommonPch.h>
+#include <tclMac.h> /* Includes tcl.h. */
+#include <tkMac.h> /* Includes tk.h. */
+#else
#include <tcl.h>
#include <tk.h>
+#endif /* MAC */
-#include <math.h>
-
-#include "tkimf.h"
-
-int imfsample_cmd(ClientData cldata, Tcl_Interp *interp,
- int argc, char *argv[]);
+#ifdef __cplusplus
+}
+#endif
-extern Tcl_Interp *interp;
+#include <math.h>
-/* MAXROWS, MAXCOLS, MINROWS, and MINCOLS can be changed safely */
-#define MAXROWS 50
-#define MAXCOLS 16
-#define MINROWS 2
-#define MINCOLS 8
+#include "config.h"
+#include "misc.h"
+#include "lisp.h"
+#include "imf.h"
-#define MAXFAMS (MAXROWS*MAXCOLS)
+#ifndef MAC
+#include "xlibstuff.h"
+#endif
-extern int tmp_valid;
+#include "tkimf.h"
extern Display *tmp_display;
+extern Tcl_Interp *interp;
+extern int tmp_valid;
-static XColor *black_color;
-static XColor *white_color;
+static XColor *black_color = NULL;
+static XColor *white_color = NULL;
/* Image family list display widget. */
typedef struct {
- Tk_Window tkwin; /* Window that embodies the imfsample. NULL
- * means window has been deleted but
- * widget record hasn't been cleaned up yet. */
- Display *display; /* X's token for the window's display. */
- Tcl_Interp *interp; /* Interpreter associated with widget. */
- Tcl_Command widgetCmd; /* Token for imfsample's widget command. */
- int border_width; /* Width of 3-D border around whole widget. */
- Tk_3DBorder bg_border; /* Used for drawing background. */
- Tk_3DBorder fg_border; /* Used for drawing foreground. */
- int relief; /* Indicates whether window as a whole is
- * raised, sunken, or flat. */
- GC copygc; /* Graphics context for copying from
- * off-screen pixmap onto screen. */
+ Tk_Window tkwin; /* Window that embodies the imfsample. NULL
+ * means window has been deleted but
+ * widget record hasn't been cleaned up yet. */
+ Display *display; /* X's token for the window's display. */
+ Tcl_Interp *interp; /* Interpreter associated with widget. */
+ Tcl_Command widgetCmd; /* Token for imfsample's widget command. */
+ int border_width; /* Width of 3-D border around whole widget. */
+ Tk_3DBorder bg_border; /* Used for drawing background. */
+ Tk_3DBorder fg_border; /* Used for drawing foreground. */
+ Tk_3DBorder cu_border; /* Used for drawing closeups. */
+ int relief; /* Indicates whether window as a whole is
+ * raised, sunken, or flat. */
+ GC copygc; /* Graphics context for copying from
+ * off-screen pixmap onto screen. */
GC gc;
- int double_buffer; /* Non-zero means double-buffer redisplay
- * with pixmap; zero means draw straight
- * onto the display. */
- int update_pending; /* Non-zero means a call to imfsample_display
- * has already been scheduled. */
+ int double_buffer; /* Non-zero means double-buffer redisplay
+ * with pixmap; zero means draw straight
+ * onto the display. */
+ int update_pending; /* Non-zero means a call to imfsample_display
+ * has already been scheduled. */
- int pad; /* Extra space between images. */
+ int pad; /* Extra space between images. */
int iwidth, iheight;
int show_color;
int show_names;
int numimages;
ImageFamily **imf_list;
- int selected;
int with_terrain;
int with_emblem;
int numvisrows;
int firstvisrow;
+
+ /* IMFAapp-specific stuff. */
+ int imfapp; /* True if we are running IMFAapp. */
+ int selected; /* The selected image in IMFAapp. */
+ int previous; /* The previously selected image. */
+ int oldfirst; /* Cache of first visible row. */
+ int redraw; /* True if the widget should be redrawn. */
} Imfsample;
static Tk_ConfigSpec config_specs[] = {
{TK_CONFIG_BORDER, "-background", "background", "Background",
"white", Tk_Offset(Imfsample, bg_border), TK_CONFIG_COLOR_ONLY},
- {TK_CONFIG_BORDER, "-background", "background", "Background",
- "white", Tk_Offset(Imfsample, bg_border), TK_CONFIG_MONO_ONLY},
{TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL,
(char *) NULL, 0, 0},
{TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
{TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL,
(char *) NULL, 0, 0},
{TK_CONFIG_BORDER, "-foreground", "foreground", "Foreground",
- "white", Tk_Offset(Imfsample, fg_border), TK_CONFIG_COLOR_ONLY},
- {TK_CONFIG_BORDER, "-foreground", "foreground", "Foreground",
- "white", Tk_Offset(Imfsample, fg_border), TK_CONFIG_MONO_ONLY},
+ "black", Tk_Offset(Imfsample, fg_border), TK_CONFIG_COLOR_ONLY},
+ {TK_CONFIG_BORDER, "-closeup", "closeup", "Closeup",
+ "white", Tk_Offset(Imfsample, cu_border), TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_PIXELS, "-height", "height", "Height",
- "32", Tk_Offset(Imfsample, height), 0},
+ "0", Tk_Offset(Imfsample, height), 0},
#if 0 /* disabled until we debug */
{TK_CONFIG_STRING, "-imf", "imf", "Imf",
"0", Tk_Offset(Imfsample, main_imf_name), 0},
"1", Tk_Offset(Imfsample, show_masks), 0},
{TK_CONFIG_INT, "-showsolid", "showSolid", "ShowSolid",
"0", Tk_Offset(Imfsample, show_solid), 0},
+ {TK_CONFIG_INT, "-imfapp", "imfApp", "ImfApp",
+ "0", Tk_Offset(Imfsample, imfapp), 0},
{TK_CONFIG_COLOR, "-fillcolor", "fillColor", "FillColor",
"gray", Tk_Offset(Imfsample, fill_color), 0},
{TK_CONFIG_PIXELS, "-width", "width", "Width",
- "32", Tk_Offset(Imfsample, width), 0},
+ "0", Tk_Offset(Imfsample, width), 0},
+ {TK_CONFIG_PIXELS, "-emblem", "emblem", "Emblem",
+ "-1", Tk_Offset(Imfsample, with_emblem), 0},
+ {TK_CONFIG_PIXELS, "-terrain", "terrain", "Terrain",
+ "-1", Tk_Offset(Imfsample, with_terrain), 0},
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
(char *) NULL, 0, 0}
};
/* The command to create an image sample window. */
int
-imfsample_cmd(ClientData cldata, Tcl_Interp *interp, int argc, char **argv)
+imfsample_cmd(ClientData cldata, Tcl_Interp *interp, int argc, char *argv[])
{
Tk_Window mainw = (Tk_Window) cldata;
Imfsample *imfsample;
imfsample->border_width = 0;
imfsample->bg_border = NULL;
imfsample->fg_border = NULL;
+ imfsample->cu_border = NULL;
imfsample->relief = TK_RELIEF_FLAT;
imfsample->copygc = None;
imfsample->gc = None;
imfsample->show_masks = 0;
imfsample->show_grid = 0;
imfsample->fill_color = NULL;
- imfsample->selected = -1;
+
imfsample->with_terrain = -1;
imfsample->with_emblem = -1;
imfsample->main_imf_name = "";
imfsample->numimages = 0;
imfsample->imf_list =
- (ImageFamily **) xmalloc(MAXFAMS * sizeof(ImageFamily *));
+ (ImageFamily **) xmalloc(MAXIMAGEFAMILIES * sizeof(ImageFamily *));
imfsample->numvisrows = 0;
imfsample->firstvisrow = 0;
+ /* IMFApp-specific stuff. */
+ imfsample->imfapp = 0;
+ imfsample->selected = -1;
+ imfsample->previous = -1;
+ imfsample->oldfirst = 0;
+ imfsample->redraw = 0;
+
Tk_CreateEventHandler(imfsample->tkwin, ExposureMask|StructureNotifyMask,
imfsample_event_proc, (ClientData) imfsample);
if (imfsample_configure(interp, imfsample, argc-2, argv+2, 0) != TCL_OK) {
}
static int
-imfsample_widget_cmd(cldata, interp, argc, argv)
-ClientData cldata;
-Tcl_Interp *interp;
-int argc;
-char **argv;
+imfsample_widget_cmd(ClientData cldata, Tcl_Interp *interp, int argc, char **argv)
{
Imfsample *imfsample = (Imfsample *) cldata;
int result = TCL_OK;
- size_t length;
+ size_t cmdlength;
char c;
int x, y, col, row, n;
+ char tclbuf[100];
+ int rslt;
if (argc < 2) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
}
Tcl_Preserve((ClientData) imfsample);
c = argv[1][0];
- length = strlen(argv[1]);
- if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0)
- && (length >= 2)) {
+ cmdlength = strlen(argv[1]);
+ if ((c == 'c') && (strncmp(argv[1], "cget", cmdlength) == 0)
+ && (cmdlength >= 2)) {
if (argc != 3) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
argv[0], " cget option\"",
}
result = Tk_ConfigureValue(interp, imfsample->tkwin, config_specs,
(char *) imfsample, argv[2], 0);
- } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)
- && (length >= 2)) {
+ } else if ((c == 'c') && (strncmp(argv[1], "configure", cmdlength) == 0)
+ && (cmdlength >= 2)) {
if (argc == 2) {
result = Tk_ConfigureInfo(interp, imfsample->tkwin, config_specs,
(char *) imfsample, (char *) NULL, 0);
result = imfsample_configure(interp, imfsample, argc-2, argv+2,
TK_CONFIG_ARGV_ONLY);
}
- } else if ((c == 'c') && (strncmp(argv[1], "curselection", length) == 0)
- && (length >= 2)) {
+ } else if ((c == 'c') && (strncmp(argv[1], "curselection", cmdlength) == 0)
+ && (cmdlength >= 2)) {
sprintf(interp->result, "%d", imfsample->selected);
- } else if ((c == 'a') && (strncmp(argv[1], "add", length) == 0)
- && (length >= 2)) {
+ } else if ((c == 'a') && (strncmp(argv[1], "add", cmdlength) == 0)
+ && (cmdlength >= 2)) {
if (strcmp(argv[2], "imf") == 0) {
imfsample_add_imf(imfsample, argv[3]);
} else if (strcmp(argv[2], "all") == 0) {
imfsample_add_imf(imfsample, "-all");
}
- } else if ((c == 'e') && (strncmp(argv[1], "emblem", length) == 0)
- && (length >= 2)) {
+ } else if ((c == 'e') && (strncmp(argv[1], "emblem", cmdlength) == 0)
+ && (cmdlength >= 2)) {
n = strtol(argv[2], NULL, 10);
imfsample->with_emblem = n;
- } else if ((c == 'r') && (strncmp(argv[1], "replace", length) == 0)
- && (length >= 2)) {
+ } else if ((c == 'r') && (strncmp(argv[1], "redraw", cmdlength) == 0)
+ && (cmdlength >= 2)) {
+ imfsample->redraw = TRUE;
+ if (!imfsample->update_pending) {
+ Tcl_DoWhenIdle(imfsample_display, cldata);
+ imfsample->update_pending = 1;
+ }
+ } else if ((c == 'r') && (strncmp(argv[1], "replace", cmdlength) == 0)
+ && (cmdlength >= 2)) {
if (strcmp(argv[2], "imf") == 0) {
imfsample_replace_imf(imfsample, argv[3]);
} else if (strcmp(argv[2], "emblem") == 0) {
imfsample_replace_emblem(imfsample, argv[3]);
}
- } else if ((c == 'r') && (strncmp(argv[1], "remove", length) == 0)
- && (length >= 2)) {
+ } else if ((c == 'r') && (strncmp(argv[1], "remove", cmdlength) == 0)
+ && (cmdlength >= 2)) {
if (strcmp(argv[2], "imf") == 0) {
imfsample_remove_imf(imfsample, argv[3]);
} else if (strcmp(argv[2], "emblem") == 0) {
imfsample->numimages = 1;
} else if (strcmp(argv[2], "all") == 0) {
- imfsample->numimages = 0;
+ imfsample_remove_imf(imfsample, "-all");
+ if (imfsample->imfapp) {
+ imfsample->selected = -1;
+ imfsample->previous = -1;
+ /* Turn off the scrollbar. */
+ sprintf(tclbuf, ".images.scroll set 0 1");
+ rslt = Tcl_Eval(interp, tclbuf);
+ if (rslt == TCL_ERROR) {
+ fprintf(stderr, "Error: %s\n", interp->result);
+ }
+ }
+ }
+ } else if ((c == 's') && (strncmp(argv[1], "select", cmdlength) == 0)
+ && (cmdlength >= 2)) {
+ if (imfsample->numimages) {
+ x = strtol(argv[2], NULL, 10);
+ y = strtol(argv[3], NULL, 10);
+ col = x / imfsample->eltw;
+ row = y / imfsample->elth + imfsample->firstvisrow;
+ n = row * imfsample->cols + col;
+ if (n < 0
+ || n >= imfsample->numimages
+ || col >= imfsample->cols) {
+ n = -1;
+ }
+ /* This rather complicated scheme is to ensure that we can both select
+ images and then deselect them by clicking a second time on the image or
+ by clicking in an empty region. */
+ if (imfsample->selected != n) {
+ imfsample->previous = imfsample->selected;
+ imfsample->selected = n;
+ } else if (n == -1) {
+ imfsample->selected = -1;
+ } else {
+ imfsample->previous = n;
+ imfsample->selected = -1;
+ }
}
- } else if ((c == 's') && (strncmp(argv[1], "select", length) == 0)
- && (length >= 2)) {
- x = strtol(argv[2], NULL, 10);
- y = strtol(argv[3], NULL, 10);
- col = x / imfsample->eltw;
- row = y / imfsample->elth + imfsample->firstvisrow;
- n = row * imfsample->cols + col;
- if (n < 0 || n >= imfsample->numimages)
- n = -1;
- imfsample->selected = n;
- } else if ((c == 't') && (strncmp(argv[1], "terrain", length) == 0)
- && (length >= 2)) {
+ } else if ((c == 't') && (strncmp(argv[1], "terrain", cmdlength) == 0)
+ && (cmdlength >= 2)) {
n = strtol(argv[2], NULL, 10);
imfsample->with_terrain = n;
- } else if ((c == 'x') && (strncmp(argv[1], "xview", length) == 0)) {
- } else if ((c == 'y') && (strncmp(argv[1], "yview", length) == 0)) {
+ } else if ((c == 'x') && (strncmp(argv[1], "xview", cmdlength) == 0)) {
+ } else if ((c == 'y') && (strncmp(argv[1], "yview", cmdlength) == 0)) {
int count, type, nrow = imfsample->firstvisrow;
double fraction, fraction2;
- if (argc == 2) {
- fraction = 0;
- fraction2 = 1;
- printf("imfsample yview %g %g\n", fraction, fraction2);
- sprintf(interp->result, "%g %g", fraction, fraction2);
- } else {
- type = Tk_GetScrollInfo(interp, argc, argv, &fraction, &count);
- switch (type) {
- case TK_SCROLL_ERROR:
+ type = Tk_GetScrollInfo(interp, argc, argv, &fraction, &count);
+ switch (type) {
+ case TK_SCROLL_ERROR:
goto error;
- case TK_SCROLL_MOVETO:
- /* nsy = ((mapw->vp->symax - mapw->vp->symin) * fraction); */
+ case TK_SCROLL_MOVETO:
+ nrow = fraction * imfsample->rows;
break;
- case TK_SCROLL_PAGES:
+ case TK_SCROLL_PAGES:
nrow += (count * imfsample->numvisrows * 4) / 5;
break;
- case TK_SCROLL_UNITS:
+ case TK_SCROLL_UNITS:
nrow += count;
break;
- }
- imfsample->firstvisrow = nrow;
+ }
+ /* Don't allow negative row numbers. */
+ imfsample->firstvisrow = max(0, nrow);
+ /* Compute the bounds of the visible window. */
+ fraction = (double) imfsample->firstvisrow / imfsample->rows;
+ fraction2 = (double) (imfsample->firstvisrow + imfsample->numvisrows) / imfsample->rows;
+ if (imfsample->imfapp) {
+ /* We must set the scrollbar explicitly since the imfsample widget
+ lacks a built-in yscrollcommand. */
+ sprintf(tclbuf, ".images.scroll set %f %f", fraction, fraction2);
+ rslt = Tcl_Eval(interp, tclbuf);
+ if (rslt == TCL_ERROR) {
+ fprintf(stderr, "Error: %s\n", interp->result);
+ }
}
} else {
Tcl_AppendResult(interp, "bad option \"", argv[1],
{
int i;
ImageFamily *imf = NULL;
+ char tclbuf[100];
+ int rslt;
if (strcmp(imfname, "-all") == 0) {
imfsample->numimages = 0;
for (i = 0; i < numimages; ++i) {
+ if (imfsample->imfapp) {
+ sprintf(tclbuf,
+".closeup.content itemconfigure status -text \"Loading %s\"",
+ images[i]->name);
+ rslt = Tcl_Eval(interp, tclbuf);
+ if (rslt == TCL_ERROR) {
+ fprintf(stderr, "Error: %s\n", interp->result);
+ }
+ sprintf(tclbuf, "update idletasks");
+ rslt = Tcl_Eval(interp, tclbuf);
+ if (rslt == TCL_ERROR) {
+ fprintf(stderr, "Error: %s\n", interp->result);
+ }
+ }
+ imf = tk_find_imf(images[i]->name);
+ if (imf == NULL) {
+ fprintf(stderr, "Missing imf %s\n", imfname);
+ return;
+ }
imfsample->imf_list[imfsample->numimages++] = images[i];
}
return;
{
ImageFamily *imf = NULL;
+ if (empty_string(imfname)) {
+ imfsample->imf_list[0] = NULL;
+ return;
+ }
if (imfsample->numimages == 0) {
imfsample_add_imf(imfsample, imfname);
return;
imfsample->imf_list[1] = imf;
}
+extern int numtkimages;
+
static void
imfsample_remove_imf(Imfsample *imfsample, char *imfname)
{
- /* (should look for specific imf) */
+ if (imfsample->imfapp) {
+ if (strcmp(imfname, "-all") == 0) {
+ numtkimages = 0;
+ numimages = 0;
+ }
+ }
imfsample->numimages = 0;
}
Tk_3DBorderColor(imfsample->fg_border)->pixel);
Tk_SetWindowBackground(imfsample->tkwin,
Tk_3DBorderColor(imfsample->bg_border)->pixel);
+ Tk_SetWindowBackground(imfsample->tkwin,
+ Tk_3DBorderColor(imfsample->cu_border)->pixel);
if ((imfsample->copygc == None) && 1/*imfsample->double_buffer*/) {
XGCValues gcValues;
the window to be redisplayed. */
Tk_GeometryRequest(imfsample->tkwin, imfsample->width, imfsample->height);
Tk_SetInternalBorder(imfsample->tkwin, imfsample->border_width);
+ /* Make sure the resized widget is redrawn. */
+ imfsample->redraw = TRUE;
if (!imfsample->update_pending) {
Tcl_DoWhenIdle(imfsample_display, (ClientData) imfsample);
imfsample->update_pending = 1;
}
static void
-imfsample_event_proc(cldata, eventPtr)
-ClientData cldata;
-XEvent *eventPtr;
+imfsample_event_proc(ClientData cldata, XEvent *eventPtr)
{
Imfsample *imfsample = (Imfsample *) cldata;
if (eventPtr->type == Expose) {
if (!imfsample->update_pending) {
- Tcl_DoWhenIdle(imfsample_display, cldata);
- imfsample->update_pending = 1;
+ Tcl_DoWhenIdle(imfsample_display, cldata);
+ imfsample->update_pending = 1;
}
} else if (eventPtr->type == ConfigureNotify) {
if (!imfsample->update_pending) {
- Tcl_DoWhenIdle(imfsample_display, cldata);
- imfsample->update_pending = 1;
+ Tcl_DoWhenIdle(imfsample_display, cldata);
+ imfsample->update_pending = 1;
}
} else if (eventPtr->type == DestroyNotify) {
if (imfsample->tkwin != NULL) {
}
static void
-imfsample_cmd_deleted_proc(cldata)
-ClientData cldata;
+imfsample_cmd_deleted_proc(ClientData cldata)
{
Imfsample *imfsample = (Imfsample *) cldata;
Tk_Window tkwin = imfsample->tkwin;
}
}
+/* Needed for drawing directly to the screen on the Mac. */
+static Tk_3DBorder black_border = NULL;
+static Tk_3DBorder white_border = NULL;
+
static void
imfsample_display(ClientData cldata)
{
char *str;
- int row, col, namex, namey, n, sx, sy;
+ int row, col, namex, namey, n, sx, sy, update = FALSE, done;
Imfsample *imfsample = (Imfsample *) cldata;
Display *dpy = imfsample->display;
Tk_Window tkwin = imfsample->tkwin;
Pixmap pm = None;
Drawable d;
Tk_Font tkfont;
- int winwidth = Tk_Width(tkwin), winheight = Tk_Height(tkwin);
-
+ int winwidth = Tk_Width(Tk_Parent(tkwin));
+ int winheight = Tk_Height(Tk_Parent(tkwin));
+ char tclbuf[100];
+ int rslt;
+
imfsample->update_pending = 0;
- if (!Tk_IsMapped(tkwin))
- return;
+ if (!Tk_IsMapped(tkwin)) {
+ return;
+ }
+ /* Check if we need to redraw the entire imfsample. */
+ if (imfsample->imfapp) {
+ if (imfsample->oldfirst != imfsample->firstvisrow
+ || imfsample->redraw) {
+ imfsample->oldfirst = imfsample->firstvisrow;
+ update = TRUE;
+ }
+ }
/* Create a pixmap for double-buffering if necessary. */
if (imfsample->double_buffer) {
+ update = TRUE;
pm = Tk_GetPixmap(imfsample->display, Tk_WindowId(tkwin),
Tk_Width(tkwin), Tk_Height(tkwin),
DefaultDepthOfScreen(Tk_Screen(tkwin)));
} else {
d = Tk_WindowId(tkwin);
}
- if (black_color == NULL)
- black_color = Tk_GetColor(interp, tkwin, Tk_GetUid("black"));
- if (white_color == NULL)
- white_color = Tk_GetColor(interp, tkwin, Tk_GetUid("white"));
+ if (black_color == NULL) {
+ black_color = Tk_GetColor(interp, tkwin, Tk_GetUid("black"));
+ }
+ if (white_color == NULL) {
+ white_color = Tk_GetColor(interp, tkwin, Tk_GetUid("white"));
+ }
+ if (black_border == NULL) {
+ black_border = Tk_Get3DBorder(interp, tkwin, "black");
+ }
+ if (white_border == NULL) {
+ white_border = Tk_Get3DBorder(interp, tkwin, "white");
+ }
/* Collect GC and font for subsequent work. */
gc = imfsample->gc;
XSetClipMask(dpy, gc, None);
if (imfsample->show_names) {
- tkfont = Tk_GetFont(interp, tkwin, "-size 10");
+#ifdef WIN32
+ tkfont = Tk_GetFont(interp, tkwin, "-family arial -size 8");
+#elif defined (MAC)
+ tkfont = Tk_GetFont(interp, tkwin, "-family helvetica -size 11");
+#else
+ tkfont = Tk_GetFont(interp, tkwin, "-family helvetica -size 12");
+#endif
XSetFont(imfsample->display, gc, Tk_FontId(tkfont));
}
- /* Redraw the widget's background/border. */
- if (imfsample->with_terrain >= 0) {
- ImageFamily *timf = imfsample->imf_list[imfsample->with_terrain];
- Image *timg;
- TkImage *tkimg;
-
- timg = best_image(timf, 64, 64);
- if (timg != NULL) {
- tkimg = (TkImage *) timg->hook;
- if (tkimg != NULL) {
- XSetFillStyle(dpy, gc, FillTiled);
- XSetTile(dpy, gc, tkimg->colr);
- XFillRectangle(dpy, d, gc, 0, 0,
- Tk_Width(tkwin), Tk_Height(tkwin));
+ /* Redraw the entire widget background/border, but not if we
+ are just updating the selected image. */
+ if (imfsample->selected == imfsample->previous
+ /* Always redraw if we have only one image (e.g. closeups). */
+ || (imfsample->numimages == 1 && imfsample->selected == -1)
+ || update) {
+ done = FALSE;
+ if (imfsample->with_terrain >= 0
+ /* Terrain tiles are not supported on Windows yet. */
+ && use_clip_mask) {
+ ImageFamily *timf =
+ imfsample->imf_list[imfsample->with_terrain];
+ Image *timg;
+ TkImage *tkimg;
+
+ timg = best_image(timf, 64, 64);
+ if (timg) {
+ tkimg = (TkImage *) timg->hook;
+ if (tkimg && tkimg->colr) {
+ XSetFillStyle(dpy, gc, FillTiled);
+ XSetTile(dpy, gc, tkimg->colr);
+ XFillRectangle(dpy, d, gc, 0, 0,
+ Tk_Width(tkwin), Tk_Height(tkwin));
+ done = TRUE;
+ }
+ }
+ }
+ if (!done) {
+ Tk_Fill3DRectangle(tkwin, d, imfsample->bg_border, 0, 0,
+ Tk_Width(tkwin), Tk_Height(tkwin),
+ imfsample->border_width, imfsample->relief);
}
- }
- } else {
- Tk_Fill3DRectangle(tkwin, d, imfsample->bg_border, 0, 0,
- Tk_Width(tkwin), Tk_Height(tkwin),
- imfsample->border_width, imfsample->relief);
}
#if 0
for (i = 0; i < imfsample->numimages; i++) {
imfsample->numvisrows = min(1, imfsample->rows);
if (imfsample->firstvisrow + imfsample->numvisrows > imfsample->rows)
imfsample->firstvisrow = imfsample->rows - imfsample->numvisrows;
+ /* Imfapp-specific code that adjusts the canvas content to fit a resized
+ window and also sets the canvas scrollregion correctly. */
+ if (imfsample->imfapp
+ && imfsample->redraw) {
+ imfsample->width = Tk_Width(Tk_Parent(tkwin));
+ imfsample->height = imfsample->rows * imfsample->elth + 7;
+ Tk_GeometryRequest(tkwin, imfsample->width, imfsample->height);
+ /* There must be a better way to do this ... */
+ sprintf(tclbuf,
+ ".images.canvas configure -scrollregion [ list 0 0 0 %d ]",
+ imfsample->height);
+ rslt = Tcl_Eval(interp, tclbuf);
+ if (rslt == TCL_ERROR) {
+ fprintf(stderr, "Error: %s\n", interp->result);
+ }
+ /* Force a redraw of the scrollbar if the window was resized. */
+ if (imfsample->numimages) {
+ sprintf(tclbuf, ".images.canvas.content yview scroll 0 units");
+ } else {
+ sprintf(tclbuf, ".images.scroll set 0 1");
+ }
+ rslt = Tcl_Eval(interp, tclbuf);
+ if (rslt == TCL_ERROR) {
+ fprintf(stderr, "Error: %s\n", interp->result);
+ }
+ }
/* Now iterate through all the images we want to draw. */
for (row = imfsample->firstvisrow;
- row < (imfsample->firstvisrow + imfsample->numvisrows);
+ row <= (imfsample->firstvisrow + imfsample->numvisrows);
++row) {
+ if (row < 0)
+ continue;
for (col = 0; col < imfsample->cols; ++col) {
n = row * imfsample->cols + col;
if (n >= imfsample->numimages)
break;
sx = col * imfsample->eltw;
sy = (row - imfsample->firstvisrow) * imfsample->elth;
- if (imfsample->show_grid)
- Tk_Fill3DRectangle(tkwin, d, imfsample->fg_border,
- sx + 2, sy + 2,
- imfsample->iwidth, imfsample->iheight,
- imfsample->border_width, imfsample->relief);
- draw_one_main_image(imfsample, d, gc, imfsample->imf_list[n],
- sx + imfsample->pad, sy + imfsample->pad,
- imfsample->iwidth, imfsample->iheight);
- if (imfsample->show_names && !imfsample->show_grid) {
- namex = sx + imfsample->pad + imfsample->iwidth + 2;
- namey = sy + (imfsample->elth / 2) + 5;
- XSetClipMask(dpy, gc, None);
- XSetFillStyle(dpy, gc, FillSolid);
- /* Draw the text in black only. */
- /* (should invent a way to make show up when black bg; an
- offset version in white is semi-OK, but hard on eyes) */
- XSetForeground(dpy, gc, black_color->pixel);
- str = imfsample->imf_list[n]->name;
- Tk_DrawChars(dpy, d, gc, tkfont, str, strlen(str),
- namex, namey);
+ /* Erase the old selected imf if we picked a new one. */
+ if (n == imfsample->previous && n != imfsample->selected) {
+ done = FALSE;
+ if (imfsample->with_terrain >= 0
+ /* Terrain tiles are not supported on Windows yet. */
+ && use_clip_mask) {
+ ImageFamily *timf =
+ imfsample->imf_list[imfsample->with_terrain];
+ Image *timg;
+ TkImage *tkimg;
+
+ timg = best_image(timf, 64, 64);
+ if (timg) {
+ tkimg = (TkImage *) timg->hook;
+ if (tkimg && tkimg->colr) {
+ XSetFillStyle(dpy, gc, FillTiled);
+ XSetTile(dpy, gc, tkimg->colr);
+ if (imfsample->show_grid) {
+ XFillRectangle(dpy, d, gc, sx, sy + 2,
+ imfsample->eltw,
+ imfsample->elth);
+ } else {
+ XFillRectangle(dpy, d, gc, sx, sy + 7,
+ imfsample->eltw,
+ imfsample->elth);
+ }
+ done = TRUE;
+ }
+ }
+ }
+ if (!done) {
+ if (imfsample->show_grid) {
+ Tk_Fill3DRectangle(tkwin, d, imfsample->bg_border,
+ sx, sy + 2,
+ imfsample->eltw, imfsample->elth,
+ imfsample->border_width,
+ imfsample->relief);
+ } else {
+ Tk_Fill3DRectangle(tkwin, d, imfsample->bg_border,
+ sx, sy + 7,
+ imfsample->eltw, imfsample->elth,
+ imfsample->border_width,
+ imfsample->relief);
+ }
+ }
}
- /* Indicate the selected imf. */
+ /* Just draw the old erased image if we selected a new one, else
+ draw every image. */
+ if (imfsample->selected == imfsample->previous
+ || n == imfsample->previous
+ || update) {
+ if (imfsample->show_grid) {
+ Tk_Fill3DRectangle(tkwin, d, imfsample->cu_border,
+ sx + 2, sy + 2,
+ imfsample->iwidth, imfsample->iheight,
+ imfsample->border_width, imfsample->relief);
+ draw_one_main_image(imfsample, d, gc,
+ imfsample->imf_list[n],
+ sx + 2, sy + 2,
+ imfsample->iwidth,
+ imfsample->iheight);
+ } else {
+ draw_one_main_image(imfsample, d, gc,
+ imfsample->imf_list[n],
+ sx + imfsample->pad,
+ sy + imfsample->pad,
+ imfsample->iwidth,
+ imfsample->iheight);
+ }
+ if (imfsample->show_names && !imfsample->show_grid) {
+ namex = sx + 5;
+ namey = sy + imfsample->elth + 3;
+ XSetClipMask(dpy, gc, None);
+ XSetFillStyle(dpy, gc, FillSolid);
+ XSetForeground(dpy, gc,
+ Tk_3DBorderColor(
+ imfsample->fg_border)->pixel);
+ str = imfsample->imf_list[n]->name;
+ Tk_DrawChars(dpy, d, gc, tkfont, str, strlen(str),
+ namex, namey);
+ }
+ }
+ /* Box the selected imf. */
if (n == imfsample->selected) {
XSetClipMask(dpy, gc, None);
XSetFillStyle(dpy, gc, FillSolid);
- XSetForeground(dpy, gc, black_color->pixel);
- XDrawRectangle(dpy, d, gc, sx, sy,
- imfsample->eltw, imfsample->elth);
+ XSetForeground(dpy, gc, Tk_3DBorderColor(imfsample->fg_border)->pixel);
+ if (imfsample->show_grid) {
+ /* A rectangle on the Mac is 1 pixel smaller in both directions. */
+#ifdef MAC
+ XDrawRectangle(dpy, d, gc, sx + 2, sy + 2,
+ imfsample->eltw - 2, imfsample->elth - 2);
+#else
+ XDrawRectangle(dpy, d, gc, sx + 2, sy + 2,
+ imfsample->eltw - 3, imfsample->elth - 3);
+#endif
+ } else {
+#ifdef MAC
+ XDrawRectangle(dpy, d, gc, sx, sy + 7,
+ imfsample->eltw, imfsample->elth);
+#else
+ XDrawRectangle(dpy, d, gc, sx, sy + 7,
+ imfsample->eltw - 1, imfsample->elth - 1);
+#endif
+ }
}
}
}
+ /* Reset the old selected image to the new one if it exists. */
+ if (imfsample->selected != -1) {
+ imfsample->previous = imfsample->selected;
+ }
+ /* Reset the redraw flag. */
+ imfsample->redraw = FALSE;
/* If double-buffered, copy to the screen and release the pixmap. */
if (imfsample->double_buffer) {
XCopyArea(imfsample->display, pm, Tk_WindowId(tkwin),
0, 0, (unsigned) winwidth, (unsigned) winheight, 0, 0);
Tk_FreePixmap(imfsample->display, pm);
}
- if (imfsample->show_names)
- Tk_FreeFont(tkfont);
+ if (imfsample->show_names) {
+ Tk_FreeFont(tkfont);
+ }
/* In theory this shouldn't be necessary, but in practice the
interface widgets (esp. the progress bar fill color) are
affected by the last value of the foreground left over from
eimf = imfsample->imf_list[imfsample->with_emblem];
if (eimf != NULL
&& emblem_position(img, eimf->name, eimf, sw, sh,
- &ex, &ey, &ew, &eh)) {
+ sh, sh, &ex, &ey, &ew, &eh)) {
eimg = best_image(eimf, ew, eh);
if (eimg == NULL)
return;
if (!img->istile) {
/* Offset the image to draw in the middle of its area,
whether larger or smaller than the given area. */
- sx2 = sx + (sw - img->w) / 2; sy2 = sy + (sh - img->h) / 2;
+ sx2 = sx + (sw - img->w) / 2;
+ sy2 = sy + (sh - img->h) / 2;
/* Only change the size of the rectangle being drawn if it's
smaller than what was passed in. */
if (img->w < sw) {
XFillRectangle(dpy, d, gc, sx, sy, sw, sh);
} else if (tkimg->mono != None || tkimg->mask != None) {
if (use_clip_mask) {
- XSetFillStyle(dpy, gc, FillSolid);
- /* Set the color we're going to use for the mask; use the
- imagecolor if we'll be using the mask as the only image. */
- XSetForeground(dpy, gc,
- (tkimg->mono == None ? imagecolor : maskcolor)->pixel);
- XSetClipOrigin(dpy, gc, sx2, sy2);
- /* Set the clip mask to be explicit mask or unit's image. */
- if (tkimg->mask && imfsample->show_masks)
- XSetClipMask(dpy, gc, tkimg->mask);
- else
- XSetClipMask(dpy, gc, tkimg->mono);
- /* Draw the mask. */
- XFillRectangle(dpy, d, gc, sx, sy, sw, sh);
- /* Draw the image proper. */
- if (tkimg->mono != None) {
- XSetForeground(dpy, gc, imagecolor->pixel);
- XSetClipMask(dpy, gc, tkimg->mono);
- XFillRectangle(dpy, d, gc, sx, sy, sw, sh);
+ /* The XFillRectangle code below does not work when we draw
+ directly to the screen on the Mac, so we use XCopyArea with a
+ small colored offscreen pixmap instead (this method does not
+ work on Unix or during double buffered drawing on the Mac). */
+#ifdef MAC
+ if (!imfsample->double_buffer) {
+ Pixmap pm =
+ Tk_GetPixmap(dpy, Tk_WindowId(tkwin), sw, sh,
+ DefaultDepthOfScreen(Tk_Screen(tkwin)));
+
+ /* Draw the mask. */
+ if (tkimg->mask && imfsample->show_masks) {
+ XSetClipMask(dpy, gc, tkimg->mask);
+ } else {
+ XSetClipMask(dpy, gc, tkimg->mono);
+ }
+ if (tkimg->mono != None) {
+ Tk_Fill3DRectangle(tkwin, pm, white_border, 0, 0,
+ sw, sh, 0, 0);
+ } else {
+ Tk_Fill3DRectangle(tkwin, pm, black_border, 0, 0,
+ sw, sh, 0, 0);
+ }
+ XCopyArea(dpy, pm, Tk_WindowId(tkwin), gc, 0, 0,
+ sw, sh, sx, sy);
+ /* Draw the image proper. */
+ if (tkimg->mono != None) {
+ XSetClipMask(dpy, gc, tkimg->mono);
+ Tk_Fill3DRectangle(tkwin, pm, black_border, 0, 0,
+ sw, sh, 0, 0);
+ XCopyArea(dpy, pm, Tk_WindowId(tkwin), gc, 0, 0,
+ sw, sh, sx, sy);
+ }
+ Tk_FreePixmap(dpy, pm);
+ return;
}
+#endif
+
+ XSetFillStyle(dpy, gc, FillSolid);
+ /* Set the color we're going to use for the mask; use the
+ imagecolor if we'll be using the mask as the only image. */
+ XSetForeground(dpy, gc,
+ (tkimg->mono == None ? imagecolor : maskcolor)->pixel);
+ XSetClipOrigin(dpy, gc, sx2, sy2);
+ /* Set the clip mask to be explicit mask or unit's image. */
+ if (tkimg->mask && imfsample->show_masks) {
+ XSetClipMask(dpy, gc, tkimg->mask);
+ } else {
+ XSetClipMask(dpy, gc, tkimg->mono);
+ }
+ /* Draw the mask. */
+ XFillRectangle(dpy, d, gc, sx, sy, sw, sh);
+ /* Draw the image proper. */
+ if (tkimg->mono != None) {
+ XSetForeground(dpy, gc, imagecolor->pixel);
+ XSetClipMask(dpy, gc, tkimg->mono);
+ XFillRectangle(dpy, d, gc, sx, sy, sw, sh);
+ }
+ /* The Win32 case. */
} else {
if (tkimg->mask != None && imfsample->show_masks) {
XSetFunction(dpy, gc, GXand);