/* * Author: William Chia-Wei Cheng (bill.cheng@acm.org) * * Copyright (C) 2001-2006, William Chia-Wei Cheng. * * This file may be distributed under the terms of the Q Public License * as defined by Trolltech AS of Norway and appearing in the file * LICENSE.QPL included in the packaging of this file. * * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * @(#)$Header: /mm2/home/cvs/bc-src/tgif/choice.c,v 1.3 2006/02/10 23:21:18 william Exp $ */ #define _INCLUDE_FROM_CHOICE_C_ #include "tgifdefs.h" #include "expfdefs.h" #include "align.e" #include "arc.e" #include "auxtext.e" #include "box.e" #include "choice.e" #include "color.e" #include "cursor.e" #include "dialog.e" #include "drawing.e" #include "edit.e" #include "file.e" #include "font.e" #include "grid.e" #include "inmethod.e" #include "mainloop.e" #include "mainmenu.e" #include "mark.e" #include "menu.e" #include "menuinfo.e" #include "miniline.e" #include "msg.e" #include "navigate.e" #include "oval.e" #include "page.e" #include "pattern.e" #include "poly.e" #include "polygon.e" #include "raster.e" #include "rcbox.e" #include "rect.e" #include "select.e" #include "setup.e" #include "shape.e" #include "special.e" #include "stretch.e" #include "strtbl.e" #include "text.e" #include "util.e" #include "wb.e" #include "xbitmap.e" #include "xprtfltr.e" #define FILE_ROW 0 #define ZOOM_ROW 0 #define RADIUS_ROW 0 #define PAGE_ROW 0 #define HORI_ALIGN_ROW 0 #define FONT_ROW 0 #define VSPACE_ROW 0 #define SHAPE_ROW 0 #define DASH_ROW 0 #define LINE_TYPE_ROW 0 #define FILL_ROW 0 #define COLOR_ROW 0 #define PRINT_ROW 1 #define MOVE_MODE_ROW 1 #define ROTATE_ROW 1 #define PAGELAYOUT_ROW 1 #define VERT_ALIGN_ROW 1 #define TEXT_SIZE_ROW 1 #define JUST_ROW 1 #define STRETCHTEXT_ROW 1 #define LINE_STYLE_ROW 1 #define LINE_WIDTH_ROW 1 #define PEN_ROW 1 #define TRANSPAT_ROW 1 #define FILE_COL 0 #define ZOOM_COL 1 #define RADIUS_COL 2 #define PAGE_COL 3 #define HORI_ALIGN_COL 4 #define FONT_COL 5 #define VSPACE_COL 6 #define SHAPE_COL 7 #define DASH_COL 8 #define LINE_TYPE_COL 9 #define FILL_COL 10 #define COLOR_COL 11 #define PRINT_COL 0 #define MOVE_MODE_COL 1 #define ROTATE_COL 2 #define PAGELAYOUT_COL 3 #define VERT_ALIGN_COL 4 #define TEXT_SIZE_COL 5 #define JUST_COL 6 #define STRETCHTEXT_COL 7 #define LINE_STYLE_COL 8 #define LINE_WIDTH_COL 9 #define PEN_COL 10 #define TRANSPAT_COL 11 #define CHOICE_SHIFT 4 #define CHOICE_COLOR ((COLOR_COL<fid; choiceGC = XCreateGC(mainDisplay, choiceWindow, GCForeground | GCBackground | GCFillStyle | GCFont, &values); memset(&rotatedAbcBBox, 0, sizeof(struct BBRec)); abcBitmap = XCreateBitmapFromData(mainDisplay, choiceWindow, (char *)abc_bits, abc_width, abc_height); if (abcBitmap == None) FailAllocPixmapMessage(abc_width, abc_height); abcImage = XGetImage(mainDisplay, abcBitmap, 0, 0, abc_width, abc_height, 1, ZPixmap); if (abcImage == NULL) FailAllocMessage(); } void CleanUpChoices() { XFreeGC(mainDisplay, choiceGC); choiceGC = (GC)0; XFreePixmap(mainDisplay, abcBitmap); XDestroyImage(abcImage); abcImage = NULL; if (rotatedAbcBitmap != None) XFreePixmap(mainDisplay, rotatedAbcBitmap); abcBitmap = rotatedAbcBitmap = None; } static void ShowStipple(dpy, win, gc, bitmap, col, row, w, h) Display *dpy; Window win; GC gc; Pixmap bitmap; int col, row, w, h; { if (threeDLook) { int x=1+windowPadding+col*(choiceImageW+windowPadding); int y=1+windowPadding+row*(choiceImageH+windowPadding); XGCValues values; values.stipple = bitmap; values.ts_x_origin = x; values.ts_y_origin = y; XChangeGC(dpy, gc, GCStipple | GCTileStipXOrigin | GCTileStipYOrigin, &values); XFillRectangle(dpy, win, gc, x, y, w, h); XSetTSOrigin(dpy, gc, 0, 0); } else { int x=col*choiceImageW, y=row*choiceImageH; XSetStipple(dpy, gc, bitmap); XFillRectangle(dpy, win, gc, x, y, w, h); } } static void HighLightThreeDButton(choice, highlight) int choice, highlight; { struct BBRec bbox; int col=0, row=0; if (!threeDLook) return; col = (choice>>CHOICE_SHIFT); row = choice-(col<>1); for (r=0; r < abcRotatedBitmapSize; r++) { int c, y=r-half_sz; double dy=((double)y)+0.5; for (c=0; c < abcRotatedBitmapSize; c++) { int x=c-half_sz; double dx=((double)x)+0.5; double new_dx=(double)0, new_dy=(double)0; ReverseTransformDoublePointThroughCTM(dx, dy, &ctm, &new_dx, &new_dy); if (new_dx >= ((double)0) && new_dx < ((double)abc_width) && new_dy >= ((double)0) && new_dy < ((double)abc_height)) { int new_x=(int)new_dx, new_y=(int)new_dy; if (new_x < 0) new_x = 0; if (new_x >= abc_width) new_x = abc_width-1; if (new_y < 0) new_y = 0; if (new_y >= abc_height) new_y = abc_height-1; if (XGetPixel(abcImage, new_x, new_y) == 1) { XPutPixel(image, c, r, 1); if (c < ltx) ltx = c; if (r < lty) lty = r; if (c > rbx) rbx = c; if (r > rby) rby = r; } } } } XPutImage(mainDisplay, rotatedAbcBitmap, xbmGC, image, 0, 0, 0, 0, abcRotatedBitmapSize, abcRotatedBitmapSize); XDestroyImage(image); rotatedAbcBBox.ltx = ltx; rotatedAbcBBox.lty = lty; rotatedAbcBBox.rbx = rbx; rotatedAbcBBox.rby = rby; } void ShowWhereToPrint() { if (colorDump) { XSetForeground(mainDisplay, rasterGC, colorPixels[colorIndex]); } ShowStipple(mainDisplay, choiceWindow, rasterGC, whereToPrintPixmap[whereToPrint], PRINT_COL, PRINT_ROW, choiceImageW, choiceImageH); if (colorDump) XSetForeground(mainDisplay, rasterGC, myFgPixel); } void ShowColor(PropagateWhereToPrint) int PropagateWhereToPrint; { XGCValues values; if (colorDisplay) { int x=COLOR_COL*choiceImageW, y=COLOR_ROW*choiceImageH; if (threeDLook) { x = 1+windowPadding+COLOR_COL*(choiceImageW+windowPadding); y = 1+windowPadding+COLOR_ROW*(choiceImageH+windowPadding); } values.foreground = colorPixels[colorIndex]; values.function = GXcopy; values.fill_style = FillOpaqueStippled; values.stipple = patPixmap[1]; XChangeGC(mainDisplay, patGC, GCForeground | GCFunction | GCFillStyle | GCStipple, &values); XFillRectangle(mainDisplay, choiceWindow, patGC, x, y, choiceImageW, choiceImageH); } if (PropagateWhereToPrint) ShowWhereToPrint(); } void ShowHoriAlign() { ShowStipple(mainDisplay, choiceWindow, rasterGC, alignHoriPixmap[horiAlign], HORI_ALIGN_COL, HORI_ALIGN_ROW, choiceImageW, choiceImageH); } void ShowVertAlign() { ShowStipple(mainDisplay, choiceWindow, rasterGC, alignVertPixmap[vertAlign], VERT_ALIGN_COL, VERT_ALIGN_ROW, choiceImageW, choiceImageH); } void ShowJust() { ShowStipple(mainDisplay, choiceWindow, rasterGC, justPixmap[textJust], JUST_COL, JUST_ROW, choiceImageW, choiceImageH); } void ShowCurFont() { static int snPrevShowDoubleByteFont=INVALID; char *choice_char=GetShowFontChar(curFont); int x, y, w, h, choice_len=(choice_char==NULL ? 0 : strlen(choice_char)); XRectangle recs[1]; XGCValues values; int image_x=FONT_COL*choiceImageW, image_y=FONT_ROW*choiceImageH; int saved_sz_unit=curSzUnit; if (threeDLook) { image_x = 1+windowPadding+FONT_COL*(choiceImageW+windowPadding); image_y = 1+windowPadding+FONT_ROW*(choiceImageH+windowPadding); } recs[0].x = image_x; recs[0].y = image_y; recs[0].width = choiceImageW; recs[0].height = choiceImageH; if (curChoice == DRAWTEXT && textCursorShown && editTextSize != 0) { curSzUnit = GetCurSzUnit(); SetCanvasFont(); } if (choice_char != NULL && canvasFontDoubleByte && canvasFontDoubleByteModBytes) { choice_char[0] |= 0x80; choice_char[1] |= 0x80; } if (choice_char == NULL) { /* do not translate -- the string is used to measure things */ w = XTextWidth(canvasFontPtr, "W", 1); } else { w = MyTextWidth(canvasFontPtr, choice_char, choice_len); } h = canvasFontHeight; XClearArea(mainDisplay, choiceWindow, image_x-windowPadding, image_y-windowPadding, choiceImageW+(windowPadding<<1), choiceImageH+(windowPadding<<1), FALSE); XSetFont(mainDisplay, choiceGC, canvasFontPtr->fid); XSetClipRectangles(mainDisplay, choiceGC, 0, 0, recs, 1, YXBanded); values.foreground = myFgPixel; values.background = myBgPixel; XChangeGC(mainDisplay, choiceGC, GCForeground | GCBackground, &values); x = (w > choiceImageW) ? image_x - (w-choiceImageW)/2 : image_x + (choiceImageW-w)/2; y = (h > choiceImageH) ? image_y + (canvasFontAsc-(h-choiceImageH)/2) : image_y + (canvasFontAsc+(choiceImageH-h)/2); if (canvasFontDoubleByte && canvasFontDoubleByteVertical) { Pixmap bitmap=None; TextExtentsInfo stTextExtents; memset(&stTextExtents, 0, sizeof(TextExtentsInfo)); /* choice_char cannot be NULL */ stTextExtents.buf = choice_char; stTextExtents.len = choice_len; bitmap = PaintVertChar(&stTextExtents, ROTATE270); if (bitmap == None) { return; } x = image_x + ((choiceImageW-stTextExtents.bbox_h)>>1); y = image_y + ((choiceImageH-stTextExtents.bbox_w)>>1); values.clip_mask = bitmap; values.clip_x_origin = x; values.clip_y_origin = y; XChangeGC(mainDisplay, choiceGC, GCClipMask | GCClipXOrigin | GCClipYOrigin, &values); XFillRectangle(mainDisplay, choiceWindow, choiceGC, (x>image_x ? x : image_x), (y>image_y ? y: image_y), (x>image_x ? stTextExtents.bbox_w : choiceImageW), (y>image_y ? stTextExtents.bbox_h : choiceImageH)); values.clip_mask = None; values.clip_x_origin = 0; values.clip_y_origin = 0; XChangeGC(mainDisplay, choiceGC, GCClipMask | GCClipXOrigin | GCClipYOrigin, &values); y += stTextExtents.bbox_w; w = stTextExtents.bbox_h; } else { if (choice_char == NULL) { /* do not translate -- the string is used to measure things */ XDrawString(mainDisplay, choiceWindow, choiceGC, x, y, "W", 1); } else { MyDrawString(mainDisplay, choiceWindow, choiceGC, mainDepth, x, y, choice_char, choice_len); } } if (curUnderlineOn) { XDrawLine(mainDisplay, choiceWindow, choiceGC, x, y+curUnderlineYOffset, x+w, y+curUnderlineYOffset); } values.foreground = xorOne; values.background = xorZero; XChangeGC(mainDisplay, choiceGC, GCForeground | GCBackground, &values); recs[0].x = 0; recs[0].y = 0; recs[0].width = choiceWindowW; recs[0].height = choiceWindowH; XSetClipRectangles(mainDisplay, choiceGC, 0, 0, recs, 1, YXBanded); /* * The following code was added so that when you move the text cursor * from a double-byte font to a single-byte font, we can close * the double-byte input method. */ if (gnInputMethod != TGIM_NONE) { if (snPrevShowDoubleByteFont != INVALID && snPrevShowDoubleByteFont && !canvasFontDoubleByte && tgIMDeactiveOnCreateText(mainDisplay, drawWindow)) { if (tgIMHandleCreateText(mainDisplay, drawWindow)) { } } snPrevShowDoubleByteFont = canvasFontDoubleByte; } if (curChoice == DRAWTEXT && textCursorShown && editTextSize != 0) { curSzUnit = saved_sz_unit; SetCanvasFont(); } } void ShowTextVSpace() { int len, x, y; char s[80]; XGCValues values; int image_x=VSPACE_COL*choiceImageW, image_y=VSPACE_ROW*choiceImageH; if (threeDLook) { image_x = 1+windowPadding+VSPACE_COL*(choiceImageW+windowPadding); image_y = 1+windowPadding+VSPACE_ROW*(choiceImageH+windowPadding); } ShowStipple(mainDisplay, choiceWindow, rasterGC, vspacePixmap, VSPACE_COL, VSPACE_ROW, choiceImageW, choiceImageH); sprintf(s, "%1d", textVSpace); len = strlen(s); if (threeDLook) { x = image_x+(choiceImageW>>1)-1; y = image_y+((choiceImageH-rulerFontAsc)>>1)+rulerFontAsc; } else { x = (int)((VSPACE_COL+0.5)*choiceImageW-2); y = VSPACE_ROW*choiceImageH+((choiceImageH-rulerFontAsc)>>1)+rulerFontAsc; } values.foreground = myFgPixel; values.background = myBgPixel; values.font = rulerFontPtr->fid; XChangeGC(mainDisplay, choiceGC, GCForeground | GCBackground | GCFont, &values); XDrawString(mainDisplay, choiceWindow, choiceGC, x, y, s, len); values.foreground = xorOne; values.background = xorZero; XChangeGC(mainDisplay, choiceGC, GCForeground | GCBackground, &values); } void ShowZoom() { int len, x, y, w, x_w, one_w; char s[80]; XGCValues values; int image_x=ZOOM_COL*choiceImageW, image_y=ZOOM_ROW*choiceImageH; if (threeDLook) { image_x = 1+windowPadding+ZOOM_COL*(choiceImageW+windowPadding); image_y = 1+windowPadding+ZOOM_ROW*(choiceImageH+windowPadding); } XClearArea(mainDisplay, choiceWindow, image_x-windowPadding, image_y-windowPadding, choiceImageW+(windowPadding<<1), choiceImageH+(windowPadding<<1), FALSE); sprintf(s, "x%1d", 1<>1); y = image_y+((choiceImageH-rulerFontAsc)>>1)+rulerFontAsc; values.foreground = myFgPixel; values.background = myBgPixel; values.font = rulerFontPtr->fid; XChangeGC(mainDisplay, choiceGC, GCForeground | GCBackground | GCFont, &values); /* do not translate -- program constants */ XDrawString(mainDisplay, choiceWindow, choiceGC, x, y, "x", 1); x += x_w; sprintf(s, "%1d", 1<>1) + windowPadding + 1; /* do not translate -- program constants */ XDrawString(mainDisplay, choiceWindow, choiceGC, x+((w-x_w-one_w)>>1), y-2, "1", 1); XDrawLine(mainDisplay, choiceWindow, choiceGC, x, y, x+(w-x_w-1), y); XDrawString(mainDisplay, choiceWindow, choiceGC, x, y+rulerFontAsc, s, len); } values.foreground = xorOne; values.background = xorZero; XChangeGC(mainDisplay, choiceGC, GCForeground | GCBackground, &values); } void ShowTextSize() { int len, x, y, w; char s[80]; XGCValues values; int image_x=TEXT_SIZE_COL*choiceImageW, image_y=TEXT_SIZE_ROW*choiceImageH; int sz_unit=GetCurSzUnit(); if (threeDLook) { image_x = 1+windowPadding+TEXT_SIZE_COL*(choiceImageW+windowPadding); image_y = 1+windowPadding+TEXT_SIZE_ROW*(choiceImageH+windowPadding); } XClearArea(mainDisplay, choiceWindow, image_x-windowPadding, image_y-windowPadding, choiceImageW+(windowPadding<<1), choiceImageH+(windowPadding<<1), FALSE); if (showFontSizeInPoints) { sprintf(s, "%1dpt", SzUnitToPointSize(sz_unit)); } else { sprintf(s, "%1d", SzUnitToFontSize(sz_unit)); } len = strlen(s); w = XTextWidth(defaultFontPtr, s, len); x = image_x + ((choiceImageW-w)>>1); y = image_y + ((choiceImageH-defaultFontAsc)>>1) + defaultFontAsc; values.foreground = myFgPixel; values.background = myBgPixel; values.font = defaultFontPtr->fid; XChangeGC(mainDisplay, choiceGC, GCForeground | GCBackground | GCFont, &values); XDrawString(mainDisplay, choiceWindow, choiceGC, x, y, s, len); values.foreground = xorOne; values.background = xorZero; XChangeGC(mainDisplay, choiceGC, GCForeground | GCBackground, &values); } void ShowRotate() { int ltx, lty, w, h, rbx, rby, x, y; XGCValues values; Pixmap bitmap=None; int image_x=ROTATE_COL*choiceImageW, image_y=ROTATE_ROW*choiceImageH; if (threeDLook) { image_x = 1+windowPadding+ROTATE_COL*(choiceImageW+windowPadding); image_y = 1+windowPadding+ROTATE_ROW*(choiceImageH+windowPadding); } UpdateAbcBitmap(); XClearArea(mainDisplay, choiceWindow, image_x-windowPadding, image_y-windowPadding, choiceImageW+(windowPadding<<1), choiceImageH+(windowPadding<<1), FALSE); if (textRotation == 0) { bitmap = abcBitmap; x = 0; y = 0; w = abc_width; h = abc_height; } else { bitmap = rotatedAbcBitmap; x = rotatedAbcBBox.ltx; y = rotatedAbcBBox.lty; w = rotatedAbcBBox.rbx-x; h = rotatedAbcBBox.rby-y; } ltx = ((choiceImageW-w)>>1); lty = ((choiceImageH-h)>>1); rbx = ltx + w; rby = lty + h; if (ltx < 0) { x = (-ltx); w -= x; ltx = 0; } if (lty < 0) { y = (-lty); h -= y; lty = 0; } if (rbx > choiceImageW) { w -= (rbx-choiceImageW); rbx = choiceImageW; } if (rby > choiceImageH) { h -= (rbx-choiceImageH); rby = choiceImageH; } values.foreground = myFgPixel; values.background = myBgPixel; values.function = GXcopy; values.fill_style = FillStippled; values.ts_x_origin = image_x+ltx-x; values.ts_y_origin = image_y+lty-y; values.stipple = bitmap; XChangeGC(mainDisplay, patGC, GCForeground | GCBackground | GCFunction | GCFillStyle | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin, &values); XFillRectangle(mainDisplay, choiceWindow, patGC, image_x+ltx, image_y+lty, rbx-ltx, rby-lty); XSetTSOrigin(mainDisplay, patGC, 0, 0); } void ShowLineWidth() { char s[40]; int x, y, len, w; XGCValues values; int image_x=LINE_WIDTH_COL*choiceImageW, image_y=LINE_WIDTH_ROW*choiceImageH; if (threeDLook) { image_x = 1+windowPadding+LINE_WIDTH_COL*(choiceImageW+windowPadding); image_y = 1+windowPadding+LINE_WIDTH_ROW*(choiceImageH+windowPadding); } ShowStipple(mainDisplay, choiceWindow, rasterGC, shortLineWidthPixmap[lineWidth], LINE_WIDTH_COL, LINE_WIDTH_ROW, choiceImageW, choiceImageH); UtilStrCpyN(s, sizeof(s), curWidthOfLineSpec[lineWidth]); len = strlen(s); w = rulerFontWidth * len; x = image_x+((choiceImageW-w)>>1); y = image_y+((choiceImageH-rulerFontAsc)>>1) + rulerFontAsc; values.foreground = (threeDLook ? myLtGryPixel : myBgPixel); values.background = (threeDLook ? myLtGryPixel : myBgPixel); values.font = rulerFontPtr->fid; XChangeGC(mainDisplay, choiceGC, GCForeground | GCBackground | GCFont, &values); XFillRectangle(mainDisplay, choiceWindow, choiceGC, x-2, y-rulerFontAsc-2, w+4, rulerFontAsc+4); XSetForeground(mainDisplay, choiceGC, myFgPixel); XDrawString(mainDisplay, choiceWindow, choiceGC, x, y, s, len); values.foreground = xorOne; values.background = xorZero; XChangeGC(mainDisplay, choiceGC, GCForeground | GCBackground, &values); } void ShowLineStyle() { ShowStipple(mainDisplay, choiceWindow, rasterGC, shortLineStylePixmap[lineStyle], LINE_STYLE_COL, LINE_STYLE_ROW, choiceImageW, choiceImageH); } void ShowLineType() { ShowStipple(mainDisplay, choiceWindow, rasterGC, shortLineTypePixmap[curSpline], LINE_TYPE_COL, LINE_TYPE_ROW, choiceImageW, choiceImageH); } void ShowDash() { ShowStipple(mainDisplay, choiceWindow, rasterGC, shortDashPixmap[curDash], DASH_COL, DASH_ROW, choiceImageW, choiceImageH); } void ShowFile() { switch (pageStyle) { case PORTRAIT: ShowStipple(mainDisplay, choiceWindow, rasterGC, filePixmap, FILE_COL, FILE_ROW, choiceImageW, choiceImageH); break; case LANDSCAPE: ShowStipple(mainDisplay, choiceWindow, rasterGC, landscapePixmap, FILE_COL, FILE_ROW, choiceImageW, choiceImageH); break; } } void ShowRCBRadius() { int len, x, y; char s[80]; XGCValues values; int image_x=RADIUS_COL*choiceImageW, image_y=RADIUS_ROW*choiceImageH; if (threeDLook) { image_x = 1+windowPadding+RADIUS_COL*(choiceImageW+windowPadding); image_y = 1+windowPadding+RADIUS_ROW*(choiceImageH+windowPadding); } ShowStipple(mainDisplay, choiceWindow, rasterGC, rcbRadiusPixmap, RADIUS_COL, RADIUS_ROW, choiceImageW, choiceImageH); sprintf(s, "%1d", rcbRadius); len = strlen(s); if (threeDLook) { x = image_x+(choiceImageW>>1)-1; y = image_y+((choiceImageH-rulerFontAsc)>>1)+rulerFontAsc; } else { x = (int)((RADIUS_COL+0.5)*choiceImageW-2); y = (((RADIUS_ROW+1)*choiceImageH-rulerFontAsc)>>1)+rulerFontAsc; } values.foreground = myFgPixel; values.background = myBgPixel; values.font = rulerFontPtr->fid; XChangeGC(mainDisplay, choiceGC, GCForeground | GCBackground | GCFont, &values); XDrawString(mainDisplay, choiceWindow, choiceGC, x, y, s, len); values.foreground = xorOne; values.background = xorZero; XChangeGC(mainDisplay, choiceGC, GCForeground | GCBackground, &values); } void ShowMoveMode() { ShowStipple(mainDisplay, choiceWindow, rasterGC, moveModePixmap[moveMode], MOVE_MODE_COL, MOVE_MODE_ROW, choiceImageW, choiceImageH); } void ShowShape() { ShowStipple(mainDisplay, choiceWindow, rasterGC, shapePixmap[SHAPE_STAR], SHAPE_COL, SHAPE_ROW, choiceImageW, choiceImageH); } void ShowStretchableTextMode() { ShowStipple(mainDisplay, choiceWindow, rasterGC, stretchableModePixmap[stretchableText], STRETCHTEXT_COL, STRETCHTEXT_ROW, choiceImageW, choiceImageH); } void ShowFill() { XGCValues values; int image_x=FILL_COL*choiceImageW, image_y=FILL_ROW*choiceImageH; if (threeDLook) { image_x = 1+windowPadding+FILL_COL*(choiceImageW+windowPadding); image_y = 1+windowPadding+FILL_ROW*(choiceImageH+windowPadding); } values.foreground = myFgPixel; values.background = (threeDLook ? myLtGryPixel : myBgPixel); values.function = GXcopy; values.fill_style = FillOpaqueStippled; values.stipple = patPixmap[objFill]; values.ts_x_origin = image_x; values.ts_y_origin = image_y; XChangeGC(mainDisplay, patGC, GCForeground | GCBackground | GCFunction | GCFillStyle | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin, &values); XFillRectangle(mainDisplay, choiceWindow, patGC, image_x, image_y, choiceImageW, choiceImageH); XSetTSOrigin(mainDisplay, patGC, 0, 0); } void ShowTransPatMode() { ShowStipple(mainDisplay, choiceWindow, rasterGC, transPatPixmap[transPat], TRANSPAT_COL, TRANSPAT_ROW, choiceImageW, choiceImageH); } void ShowPen() { XGCValues values; int image_x=PEN_COL*choiceImageW, image_y=PEN_ROW*choiceImageH; if (threeDLook) { image_x = 1+windowPadding+PEN_COL*(choiceImageW+windowPadding); image_y = 1+windowPadding+PEN_ROW*(choiceImageH+windowPadding); } values.foreground = myFgPixel; values.background = (threeDLook ? myLtGryPixel : myBgPixel); values.function = GXcopy; values.fill_style = FillOpaqueStippled; values.stipple = patPixmap[penPat]; values.ts_x_origin = image_x; values.ts_y_origin = image_y; XChangeGC(mainDisplay, patGC, GCForeground | GCBackground | GCFunction | GCFillStyle | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin, &values); XFillRectangle(mainDisplay, choiceWindow, patGC, image_x, image_y, choiceImageW, choiceImageH); XSetTSOrigin(mainDisplay, patGC, 0, 0); if (penPat != NONEPAT) { XClearArea(mainDisplay, choiceWindow, image_x+(choiceImageW>>2), image_y+(choiceImageH>>2), (choiceImageW>>1), (choiceImageH>>1), FALSE); } } void ShowPage() { int len, x, y, w; char s[80]; XGCValues values; int image_x=PAGE_COL*choiceImageW, image_y=PAGE_ROW*choiceImageH; if (threeDLook) { image_x = 1+windowPadding+PAGE_COL*(choiceImageW+windowPadding); image_y = 1+windowPadding+PAGE_ROW*(choiceImageH+windowPadding); } XClearArea(mainDisplay, choiceWindow, image_x-windowPadding, image_y-windowPadding, choiceImageW+(windowPadding<<1), choiceImageH+(windowPadding<<1), FALSE); switch (pageLayoutMode) { case PAGE_STACK: sprintf(s, "%1d/%1d", curPageNum, lastPageNum); break; case PAGE_TILE: sprintf(s, "%1dx%1d", paperCol, paperRow); break; } len = strlen(s); w = XTextWidth(rulerFontPtr, s, len); x = image_x+((choiceImageW-w)>>1); y = image_y+((choiceImageH-rulerFontAsc)>>1) + rulerFontAsc; values.foreground = myFgPixel; values.background = myBgPixel; values.font = rulerFontPtr->fid; XChangeGC(mainDisplay, choiceGC, GCForeground | GCBackground | GCFont, &values); XDrawString(mainDisplay, choiceWindow, choiceGC, x, y, s, len); values.foreground = xorOne; values.background = xorZero; XChangeGC(mainDisplay, choiceGC, GCForeground | GCBackground, &values); RedrawPageWindow(); } void ShowPageLayout() { int image_x=PAGELAYOUT_COL*choiceImageW, image_y=PAGELAYOUT_ROW*choiceImageH; if (threeDLook) { image_x = 1+windowPadding+PAGELAYOUT_COL*(choiceImageW+windowPadding); image_y = 1+windowPadding+PAGELAYOUT_ROW*(choiceImageH+windowPadding); } XClearArea(mainDisplay, choiceWindow, image_x-windowPadding, image_y-windowPadding, choiceImageW+(windowPadding<<1), choiceImageH+(windowPadding<<1), FALSE); ShowStipple(mainDisplay, choiceWindow, rasterGC, pageLayoutPixmap[pageLayoutMode], PAGELAYOUT_COL, PAGELAYOUT_ROW, choiceImageW, choiceImageH); } static int NeedSelectTopObject(Choice, VertexTypeObj) int Choice, VertexTypeObj; { if (VertexTypeObj) { return (Choice==NOTHING || Choice==VERTEXMODE || Choice==ROTATEMODE); } else { return (Choice==NOTHING || Choice==ROTATEMODE); } } void ShowCurChoiceMouseStatus(choice, state, cur_text_under_mouse) int choice, cur_text_under_mouse; unsigned int state; /* 0 or ControlMask */ { if (choice == INVALID) { SetMouseStatus(TgLoadCachedString(CSTID_PARANED_NONE), TgLoadCachedString(CSTID_MAIN_MENU), TgLoadCachedString(CSTID_PARANED_NONE)); } else if (choice == NOTHING && inHyperSpace) { SetCurChoiceMouseStatusStrings(choice, TRUE, NULL, cur_text_under_mouse, state); } else { SetCurChoiceMouseStatusStrings(choice, FALSE, NULL, cur_text_under_mouse, state); } } void SetCurChoice(NewChoice) int NewChoice; { struct ObjRec *selected_single_text_obj=NULL; if (curChoice == NewChoice) return; if (gstWBInfo.do_whiteboard && (serializingFile || deserializingFile)) { return; } if (inSlideShow) { if (NewChoice == NOTHING || NewChoice == DRAWTEXT || NewChoice == VERTEXMODE || NewChoice == ROTATEMODE) { /* these modes are not allowed in slideshow */ return; } } switch (curChoice) { case NOTHING: if (topSel != NULL) { if (NewChoice == VERTEXMODE) { UnSelNonVertexObjs(TRUE, TRUE); /* with highlight */ UpdSelBBox(); } else if (NewChoice != ROTATEMODE) { if (NewChoice == DRAWTEXT && topSel != NULL && topSel == botSel && topSel->obj->type == OBJ_TEXT) { selected_single_text_obj = topSel->obj; } HighLightReverse(); RemoveAllSel(); } } break; case DRAWTEXT: CreateTextObj(TRUE, TRUE); if (NeedSelectTopObject(NewChoice, FALSE) && textDrawn) { HighLightJustDrawnText(); } textDrawn = FALSE; textCursorShown = FALSE; break; case DRAWBOX: if (NeedSelectTopObject(NewChoice, FALSE) && boxDrawn) { SelectTopObj(); } boxDrawn = FALSE; break; case DRAWCORNEROVAL: case DRAWCENTEROVAL: case DRAWEDGECIRCLE: if (NeedSelectTopObject(NewChoice, FALSE) && ovalDrawn) { SelectTopObj(); } ovalDrawn = FALSE; break; case DRAWPOLY: if (NeedSelectTopObject(NewChoice, TRUE) && polyDrawn) { SelectTopObj(); } polyDrawn = FALSE; break; case DRAWPOLYGON: if (NeedSelectTopObject(NewChoice, TRUE) && polygonDrawn) { SelectTopObj(); } polygonDrawn = FALSE; break; case DRAWARC: case DRAWEDGEARC: if (NeedSelectTopObject(NewChoice, FALSE) && arcDrawn) { SelectTopObj(); } arcDrawn = FALSE; break; case DRAWRCBOX: if (NeedSelectTopObject(NewChoice, FALSE) && rcBoxDrawn) { SelectTopObj(); } rcBoxDrawn = FALSE; break; case FREEHAND: if (NeedSelectTopObject(NewChoice, TRUE) && polyDrawn) { SelectTopObj(); } polyDrawn = FALSE; break; case VERTEXMODE: if (NewChoice == NOTHING || NewChoice == ROTATEMODE) { HighLightReverse(); JustRemoveAllVSel(); HighLightForward(); } else { HighLightReverse(); RemoveAllSel(); } break; case ROTATEMODE: if (topSel != NULL) { if (NewChoice == VERTEXMODE) { UnSelNonVertexObjs(TRUE, TRUE); /* with highlight */ UpdSelBBox(); } else if (NewChoice != NOTHING) { if (NewChoice == DRAWTEXT && topSel != NULL && topSel == botSel && topSel->obj->type == OBJ_TEXT) { selected_single_text_obj = topSel->obj; } HighLightReverse(); RemoveAllSel(); } } break; } curChoice = NewChoice; switch (curChoice) { case DRAWTEXT: case DRAWBOX: case DRAWCORNEROVAL: case DRAWCENTEROVAL: case DRAWEDGECIRCLE: case DRAWPOLY: case DRAWPOLYGON: case DRAWARC: case DRAWEDGEARC: case DRAWRCBOX: case FREEHAND: if (colorLayers && !colorLayerOn[colorIndex]) { sprintf(gszMsgBox, TgLoadString(STID_INVISIBLE_COLOR_SELECTED_YNC), colorIndex, colorMenuItems[colorIndex]); if (MsgBox(gszMsgBox, TOOL_NAME, YNC_MB) == MB_ID_YES) { colorLayerOn[colorIndex] = TRUE; RedrawColorWindow(); ClearAndRedrawDrawWindow(); } } break; case NOTHING: break; case VERTEXMODE: break; case ROTATEMODE: break; } if (!setCurChoiceDontUpdateUI) { ShowCursor(); RedrawModeWindow(); UpdatePinnedMenu(MENU_MODE); ShowCurChoiceMouseStatus(curChoice, 0, FALSE); } textCursorShown = FALSE; if (inHyperSpace && curChoice != NOTHING) { ToggleHyperSpace(FALSE); } else if (!inHyperSpace && selected_single_text_obj != NULL) { CleanOuterInnerSel(); CleanOuterInnerSelForFind(); HighLightText(selected_single_text_obj, NULL, INVALID, NULL, INVALID); } } static int prevChoice=NOTHING; void PushCurChoice() /* Kouichi Matsuda's modification */ { if (curChoice == NOTHING) { SetCurChoice(prevChoice); } else { prevChoice = curChoice; SetCurChoice(NOTHING); } } static void TextVSpaceLoop(button_ev) XButtonEvent *button_ev; { int saved_text_vspace=textVSpace, res=8, done=FALSE, need_to_restore=FALSE; int orig_x=button_ev->x, orig_y=button_ev->y, saved_change=0; XEvent ev; if (!debugNoPointerGrab) { XGrabPointer(mainDisplay, choiceWindow, False, PointerMotionMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, handCursor, CurrentTime); } while (!done) { XNextEvent(mainDisplay, &ev); if (ev.type == Expose || ev.type == VisibilityNotify) { ExposeEventHandler(&ev, TRUE); } else if (ev.type == ButtonRelease) { XUngrabPointer(mainDisplay, CurrentTime); done = TRUE; } else if (ev.type == MotionNotify) { int dx=ev.xmotion.x-orig_x, dy=ev.xmotion.y-orig_y; int change=((abs(dx)>abs(dy)) ? (int)(dx/res) : (int)(dy/res)); if (change != saved_change) { textVSpace = saved_text_vspace+change; ShowTextVSpace(); saved_change = change; } while (XCheckMaskEvent(mainDisplay, PointerMotionMask, &ev)) ; } } ShowTextVSpace(); if ((topSel == NULL || stickyMenuSelection) && (textCursorH+textVSpace <= 0)) { need_to_restore = TRUE; } ChangeVSpace(textVSpace); if (need_to_restore) { textVSpace = saved_text_vspace; ShowTextVSpace(); } } static void RCBRadiusLoop(button_ev) XButtonEvent *button_ev; { int saved_rcb_radius = rcbRadius, res=8, done=FALSE; int orig_x=button_ev->x, orig_y=button_ev->y, saved_change=0; XEvent ev; if (!debugNoPointerGrab) { XGrabPointer(mainDisplay, choiceWindow, False, PointerMotionMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, handCursor, CurrentTime); } while (!done) { XNextEvent(mainDisplay, &ev); if (ev.type == Expose || ev.type == VisibilityNotify) { ExposeEventHandler(&ev, TRUE); } else if (ev.type == ButtonRelease) { XUngrabPointer(mainDisplay, CurrentTime); done = TRUE; } else if (ev.type == MotionNotify) { int dx=ev.xmotion.x-orig_x, dy=ev.xmotion.y-orig_y; int change=((abs(dx)>abs(dy)) ? (int)(dx/res) : (int)(dy/res)); if (change != saved_change) { rcbRadius = max(MIN_RCB_RADIUS, saved_rcb_radius+change); ShowRCBRadius(); saved_change = change; } while (XCheckMaskEvent(mainDisplay, PointerMotionMask, &ev)) ; } } if (topSel != NULL) ChangeAllSelRCBRadius(rcbRadius); } static void ZoomLoop(button_ev) XButtonEvent *button_ev; { int saved_zoomed_in=zoomedIn, saved_zoom_scale=zoomScale, res=8; int new_zoomed_in, new_zoom_scale, done=FALSE, saved_change=0; int initial_zoom, zoom, max_zoom, win_w, win_h; int orig_x=button_ev->x, orig_y=button_ev->y; XEvent ev; initial_zoom = (zoomedIn) ? (MAX_ZOOMED_IN-zoomScale) : (MAX_ZOOMED_IN+zoomScale); win_w = drawWinW; win_h = drawWinH; new_zoomed_in = zoomedIn; new_zoom_scale = zoomScale; while ((win_w>>1) >= paperWidth && (win_h>>1) >= paperHeight) { if (new_zoomed_in) { new_zoom_scale++; } else if (new_zoom_scale == 0) { new_zoomed_in = TRUE; new_zoom_scale++; } else { new_zoom_scale--; } win_w >>= 1; win_h >>= 1; } while (win_w < paperWidth || win_h < paperHeight) { if (!new_zoomed_in) { new_zoom_scale++; } else if (new_zoom_scale == 1) { new_zoomed_in = FALSE; new_zoom_scale--; } else { new_zoom_scale--; } win_w <<= 1; win_h <<= 1; } max_zoom = (new_zoomed_in) ? (MAX_ZOOMED_IN-new_zoom_scale) : (MAX_ZOOMED_IN+new_zoom_scale); if (!debugNoPointerGrab) { XGrabPointer(mainDisplay, choiceWindow, False, PointerMotionMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, handCursor, CurrentTime); } while (!done) { XNextEvent(mainDisplay, &ev); if (ev.type == Expose || ev.type == VisibilityNotify) { ExposeEventHandler(&ev, TRUE); } else if (ev.type == ButtonRelease) { XUngrabPointer(mainDisplay, CurrentTime); done = TRUE; } else if (ev.type == MotionNotify) { int dx=ev.xmotion.x-orig_x, dy=ev.xmotion.y-orig_y; int change=((abs(dx)>abs(dy)) ? (int)(dx/res) : (int)(dy/res)); if (change != saved_change) { zoom = initial_zoom+change; if (zoom < 0) zoom = 0; if (zoom > max_zoom) zoom = max_zoom; zoomedIn = (zoom < MAX_ZOOMED_IN); zoomScale = (zoomedIn) ? (MAX_ZOOMED_IN-zoom) : (zoom-MAX_ZOOMED_IN); ShowZoom(); saved_change = change; } while (XCheckMaskEvent(mainDisplay, PointerMotionMask, &ev)) ; } } if (saved_zoomed_in==zoomedIn && saved_zoom_scale==zoomScale) return; new_zoomed_in = zoomedIn; new_zoom_scale = zoomScale; zoomedIn = saved_zoomed_in; zoomScale = saved_zoom_scale; PreciseZoom(new_zoomed_in, new_zoom_scale, FALSE); } void FormatFloat(pfval, buf) float *pfval; char *buf; { char int_buf[80], frac_buf[4]; float fval=((*pfval)*1000.0); int ival=round(fval), len; *buf = '\0'; if (ival == 0) { strcpy(buf, "0"); return; } sprintf(int_buf, "%04d", ival); len = strlen(int_buf); if (strcmp(&int_buf[len-3], "000") == 0) { *frac_buf = '\0'; } else if (strcmp(&int_buf[len-2], "00") == 0) { int_buf[len-2] = '\0'; strcpy(frac_buf, &int_buf[len-3]); } else if (strcmp(&int_buf[len-1], "0") == 0) { int_buf[len-1] = '\0'; strcpy(frac_buf, &int_buf[len-3]); } else { strcpy(frac_buf, &int_buf[len-3]); } int_buf[len-3] = '\0'; if (*frac_buf == '\0') { strcpy(buf, int_buf); } else { sprintf(buf, "%s.%s", int_buf, frac_buf); } } void FormatAngle(angle, buf) int angle; /* degrees*64 */ char *buf; { float fval=(((float)angle)/64.0); FormatFloat(&fval, buf); } static void ShowRotateMouseStatus() { char left_buf[MAXSTRING], right_buf[MAXSTRING], tmp_buf[MAXSTRING]; if (rotationIncrement == 0) { SetMouseStatus(TgLoadCachedString(CSTID_PARANED_NONE), TgLoadCachedString(CSTID_PARANED_NONE), TgLoadCachedString(CSTID_PARANED_NONE)); return; } FormatAngle(rotationIncrement, tmp_buf); sprintf(left_buf, TgLoadCachedString(CSTID_ROTATE_DEGREES_CW), tmp_buf); sprintf(right_buf, TgLoadCachedString(CSTID_ROTATE_DEGREES_CCW), tmp_buf); SetMouseStatus(left_buf, TgLoadCachedString(CSTID_PARANED_NONE), right_buf); } static int ValidChoice(choice) int choice; { switch (choice) { case CHOICE_COLOR: case CHOICE_HORI_ALIGN: case CHOICE_VERT_ALIGN: case CHOICE_PAGE: case CHOICE_PAGELAYOUT: case CHOICE_JUST: case CHOICE_FONT: case CHOICE_VSPACE: case CHOICE_TEXT_SIZE: case CHOICE_ROTATE: case CHOICE_LINE_WIDTH: case CHOICE_LINE_STYLE: case CHOICE_LINE_TYPE: case CHOICE_DASH: case CHOICE_RADIUS: case CHOICE_ZOOM: case CHOICE_MOVE_MODE: case CHOICE_SHAPE: case CHOICE_STRETCHTEXT: case CHOICE_TRANSPAT: case CHOICE_PRINT: case CHOICE_FILE: case CHOICE_FILL: case CHOICE_PEN: return TRUE; } return FALSE; } int ChoiceEventHandler(input) XEvent *input; { XEvent ev; int xindex, yindex, x=0, y=0, choice; if (input->type == Expose) { XSync(mainDisplay, False); while (XCheckWindowEvent(mainDisplay, choiceWindow, ExposureMask, &ev)) ; RedrawChoiceWindow(); } else if (input->type == EnterNotify || input->type == LeaveNotify) { SetMouseStatus("", "", ""); if (curRaisedChoice != INVALID) { HighLightThreeDButton(curRaisedChoice, FALSE); curRaisedChoice = INVALID; } } else if (input->type == MotionNotify) { int nIndex=0; char szLeft[MAXSTRING], szRight[MAXSTRING]; if (threeDLook) { xindex = (int)((input->xmotion.x-1) / (choiceImageW+windowPadding)); yindex = (int)((input->xmotion.y-1) / (choiceImageH+windowPadding)); choice = (xindex<xmotion.x / choiceImageW); yindex = (int)(input->xmotion.y / choiceImageH); choice = (xindex<type == ButtonPress) { XButtonEvent *button_ev=(&(input->xbutton)); int delta=0, root_x, root_y; Window root_win, child_win; unsigned int status; Msg(""); switch (button_ev->button) { case Button1: delta = 1; break; case Button2: XQueryPointer(mainDisplay, rootWindow, &root_win, &child_win, &root_x, &root_y, &x, &y, &status); break; case Button3: delta = -1; break; default: return INVALID; } if (threeDLook) { xindex = (int)((input->xmotion.x-1) / (choiceImageW+windowPadding)); yindex = (int)((input->xmotion.y-1) / (choiceImageH+windowPadding)); choice = (xindex<xmotion.x / choiceImageW); yindex = (int)(input->xmotion.y / choiceImageH); choice = (xindex<= (360<<6)) textRotation -= (360<<6); ShowRotate(); if (topSel != NULL) { if (delta == 1) { RotateClockWise(); } else { RotateCounter(); } } } ShowRotateMouseStatus(); break; case CHOICE_LINE_WIDTH: if (delta == 0) { LineWidthMenu(x, y, FALSE); } else { lineWidth = (lineWidth+maxLineWidths+delta) % maxLineWidths; ShowLineWidth(); UpdatePinnedMenu(MENU_LINEWIDTH); if (topSel != NULL) { ChangeAllSelLineWidth(lineWidth, TRUE); } else { sprintf(gszMsgBox, TgLoadString(STID_LINE_WIDTH_SET_TO), curWidthOfLineSpec[lineWidth]); Msg(gszMsgBox); } QuickSetMouseStatus(lineWidthMouseStatus, 0); } break; case CHOICE_LINE_STYLE: if (delta == 0) { LineStyleMenu(x, y, FALSE); } else { lineStyle = (lineStyle+MAXLINESTYLES+delta) % MAXLINESTYLES; ShowLineStyle(); UpdatePinnedMenu(MENU_LINESTYLE); if (topSel != NULL) ChangeAllSelLineStyle(lineStyle, TRUE); QuickSetMouseStatus(lineStyleMouseStatus, 0); } break; case CHOICE_LINE_TYPE: if (delta == 0) { LineTypeMenu(x, y, FALSE); } else { curSpline = (curSpline+MAXLINETYPES+delta) % MAXLINETYPES; ShowLineType(); UpdatePinnedMenu(MENU_LINETYPE); if (topSel != NULL) { ChangeAllSelLineType(curSpline, TRUE); } else { *gszMsgBox = '\0'; switch (curSpline) { case LT_STRAIGHT: Msg(TgLoadString(STID_LINE_TYPE_IS_STRAIGHT)); break; case LT_SPLINE: Msg(TgLoadString(STID_LINE_TYPE_IS_SPLINE)); break; case LT_INTSPLINE: Msg(TgLoadString(STID_LINE_TYPE_IS_INTSPLINE)); break; } } QuickSetMouseStatus(lineTypeMouseStatus, 0); } break; case CHOICE_DASH: if (delta == 0) { LineDashMenu(x, y, FALSE); } else { curDash = (curDash+MAXDASHES+delta) % MAXDASHES; ShowDash(); UpdatePinnedMenu(MENU_LINEDASH); if (topSel != NULL) ChangeAllSelLineDash(curDash, TRUE); QuickSetMouseStatus(lineDashMouseStatus, 0); } break; case CHOICE_RADIUS: if (delta == 0) { RCBRadiusLoop(button_ev); } else { if (rcbRadius+delta >= MIN_RCB_RADIUS) { rcbRadius += delta; ShowRCBRadius(); if (topSel != NULL) ChangeAllSelRCBRadius(rcbRadius); } QuickSetMouseStatus(rcbRadiusMouseStatus, 0); } break; case CHOICE_ZOOM: switch (delta) { case -1: ZoomOut(); QuickSetMouseStatus(zoomMouseStatus, 0); break; case 0: ZoomLoop(button_ev); break; case 1: ZoomIn(); break; } break; case CHOICE_MOVE_MODE: if (delta == 0) { MoveModeMenu(x, y, FALSE); } else { ToggleMoveMode(); QuickSetMouseStatus(moveModeMouseStatus, moveMode); } break; case CHOICE_SHAPE: if (delta == 0) ShapeMenu(x, y, FALSE); break; case CHOICE_STRETCHTEXT: if (delta == 0) { StretchableTextModeMenu(x, y, FALSE); } else { ToggleStretchableText(); QuickSetMouseStatus(stretchableTextModeMouseStatus, stretchableText); } break; case CHOICE_TRANSPAT: if (delta == 0) { TransPatModeMenu(x, y, FALSE); } else { transPat = !transPat; ShowTransPatMode(); UpdatePinnedMenu(MENU_TRANSPAT); if (topSel != NULL) ChangeAllSelTransPat(transPat, TRUE); QuickSetMouseStatus(transPatMouseStatus, transPat); } break; case CHOICE_PRINT: if (delta == 0) { ExportFormatMenu(x, y, FALSE); } else { whereToPrint = (whereToPrint+maxWhereToPrint+delta) % maxWhereToPrint-1; ToggleWhereToPrint(); } break; case CHOICE_FILE: if (delta == 0) { PageStyleMenu(x, y, FALSE); } else { switch (pageStyle) { case PORTRAIT: ChangePageStyle(LANDSCAPE); break; case LANDSCAPE: ChangePageStyle(PORTRAIT); break; } QuickSetMouseStatus(fileMouseStatus, pageStyle); } break; case CHOICE_FILL: if (delta == 0) { FillMenu(x, y, FALSE); } else { if (curChoice == DRAWTEXT && !textCursorShown) { if (TieLooseEnds()) { SetCurChoice(NOTHING); HighLightReverse(); } else { SetCurChoice(NOTHING); } RemoveAllSel(); } objFill = (objFill+MAXPATTERNS+delta) % MAXPATTERNS; ShowFill(); UpdatePinnedMenu(MENU_FILL); if (topSel != NULL) { ChangeAllSelFill(objFill, TRUE); } else if (curChoice == DRAWTEXT && textCursorShown) { ChangeAllSelFill(objFill, FALSE); } QuickSetMouseStatus(fillMouseStatus, 0); } break; case CHOICE_PEN: if (delta == 0) { PenMenu(x, y, FALSE); } else { if (curChoice == DRAWTEXT && !textCursorShown) { if (TieLooseEnds()) { SetCurChoice(NOTHING); HighLightReverse(); } else { SetCurChoice(NOTHING); } RemoveAllSel(); } penPat = (penPat+MAXPATTERNS+delta) % MAXPATTERNS; ShowPen(); UpdatePinnedMenu(MENU_PEN); if (topSel != NULL) { ChangeAllSelPen(penPat, TRUE); } else if (curChoice == DRAWTEXT && textCursorShown) { ChangeAllSelPen(penPat, FALSE); } QuickSetMouseStatus(penMouseStatus, 0); } break; } cycleThroughChoice = FALSE; } return INVALID; } static void HighLightModeThreeDButton(mode, highlight) int mode, highlight; { struct BBRec bbox; if (!threeDLook) return; bbox.ltx = (windowPadding>>1); bbox.lty = (windowPadding>>1)+mode*(choiceImageH+(windowPadding<<1)); bbox.rbx = bbox.ltx+choiceImageW+(windowPadding<<1); bbox.rby = bbox.lty+choiceImageH+(windowPadding<<1); if (highlight) { TgDrawThreeDButton(mainDisplay, modeWindow, textMenuGC, &bbox, TGBS_RAISED, 2, FALSE); } else if (mode == curChoice) { TgDrawThreeDButton(mainDisplay, modeWindow, textMenuGC, &bbox, TGBS_LOWRED, 2, FALSE); } else { TgClearThreeDButton(mainDisplay, modeWindow, textMenuGC, &bbox, 2); } } void RedrawModeWindow() { int i, x=(windowPadding>>1), y=(windowPadding>>1); XGCValues values; XClearWindow(mainDisplay, modeWindow); for (i=0; i < MAXCHOICES; i++) { Pixmap bitmap=((i==DRAWPOLY && connectingPortsByWire) ? wireBitmap : choicePixmap[i]); if (threeDLook) { values.stipple = bitmap; values.ts_x_origin = x+windowPadding; values.ts_y_origin = y+windowPadding; XChangeGC(mainDisplay, rasterGC, GCStipple | GCTileStipXOrigin | GCTileStipYOrigin, &values); XFillRectangle(mainDisplay, modeWindow, rasterGC, values.ts_x_origin, values.ts_y_origin, choiceImageW, choiceImageH); XSetTSOrigin(mainDisplay, rasterGC, 0, 0); if (i == curChoice) { struct BBRec bbox; SetBBRec(&bbox, x, y, x+choiceImageW+(windowPadding<<1), y+choiceImageH+(windowPadding<<1)); TgDrawThreeDButton(mainDisplay, modeWindow, textMenuGC, &bbox, TGBS_LOWRED, 2, FALSE); } } else { if (i == curChoice) { XSetForeground(mainDisplay, textMenuGC, myFgPixel); XFillRectangle(mainDisplay, modeWindow, textMenuGC, x+windowPadding, y+windowPadding, choiceImageW, choiceImageH); XSetStipple(mainDisplay, rvPixmapMenuGC, bitmap); XFillRectangle(mainDisplay, modeWindow, rvPixmapMenuGC, x+windowPadding, y+windowPadding, choiceImageW, choiceImageH); } else { XSetStipple(mainDisplay, rasterGC, bitmap); XFillRectangle(mainDisplay, modeWindow, rasterGC, x+windowPadding, y+windowPadding, choiceImageW, choiceImageH); } } y += choiceImageH+(windowPadding<<1); } if (threeDLook) { struct BBRec bbox; SetBBRec(&bbox, 0, 0, modeWindowW, modeWindowH); TgDrawThreeDButton(mainDisplay, modeWindow, textMenuGC, &bbox, TGBS_RAISED, 1, FALSE); } } int ModeEventHandler(input) XEvent *input; { XEvent ev; int mode=INVALID; if (noModeWindow) return INVALID; if (input->type == Expose) { XSync(mainDisplay, False); while (XCheckWindowEvent(mainDisplay, modeWindow, ExposureMask, &ev)) ; RedrawModeWindow(); } else if (input->type == EnterNotify || input->type == LeaveNotify) { if (input->type == EnterNotify) { SetStringStatus(""); } else { SetMouseStatus("", "", ""); } if (curRaisedMode != INVALID) { HighLightModeThreeDButton(curRaisedMode, FALSE); curRaisedMode = INVALID; } } else if (input->type == MotionNotify) { mode = (int)((input->xmotion.y-(windowPadding>>1)) / (choiceImageH+(windowPadding<<1))); if (threeDLook) { if (mode != curRaisedMode) { if (curRaisedMode != INVALID) { HighLightModeThreeDButton(curRaisedMode, FALSE); curRaisedMode = INVALID; } if (mode >= 0 && mode < MAXCHOICES) { HighLightModeThreeDButton(mode, TRUE); curRaisedMode = mode; } } } if (mode >=0 && mode < MAXCHOICES) { TgMenuItemInfo *menu_iteminfos=modeMenuInfo.items; /* the raw status_str is English */ SetStringStatus(_(menu_iteminfos[mode].status_str)); } else { SetStringStatus(""); } } else if (input->type == ButtonPress) { mode = (int)((input->xbutton.y-(windowPadding>>1)) / (choiceImageH+(windowPadding<<1))); if (mode >=0 && mode < MAXCHOICES) { TgMenuItemInfo *menu_iteminfos=modeMenuInfo.items; SetCurChoice(mode); /* the raw status_str is English */ SetStringStatus(_(menu_iteminfos[mode].status_str)); } else if (input->xbutton.button == Button2 && mode >= MAXCHOICES) { return MainMenu(); } } return INVALID; }