XmFontList XmLFontListCopyDefault(Widget widget) { Widget parent; XFontStruct *font; XmFontList fontList, fl; fontList = 0; parent = XtParent(widget); while (parent) { fl = 0; if (XmIsVendorShell(parent) || XmIsMenuShell(parent)) XtVaGetValues(parent, XmNdefaultFontList, &fl, NULL); else if (XmIsBulletinBoard(parent)) XtVaGetValues(parent, XmNbuttonFontList, &fl, NULL); if (fl) { fontList = XmFontListCopy(fl); parent = 0; } if (parent) parent = XtParent(parent); } if (!fontList) { font = XLoadQueryFont(XtDisplay(widget), "fixed"); if (!font) XmLWarning(widget, "FontListCopyDefault() - FATAL ERROR - can't load fixed font"); fontList = XmFontListCreate(font, XmSTRING_DEFAULT_CHARSET); } return fontList; }
static void Initialize(Widget reqW, Widget newW, ArgList args, Cardinal *narg) { XmLTreeWidget t; t = (XmLTreeWidget)newW; if (t->core.width <= 0) t->core.width = 100; if (t->core.height <= 0) t->core.height = 100; t->tree.defaultPixmapsCreated = 0; t->tree.linesData = 0; t->tree.linesSize = 0; t->tree.recalcTreeWidth = 0; if (t->grid.rowCount) { XmLWarning(newW, "Initialize() - can't set XmNrows"); XmLGridDeleteAllRows(newW, XmCONTENT); } XtAddCallback(newW, XmNactivateCallback, Activate, NULL); XtAddEventHandler(newW, ButtonPressMask, True, (XtEventHandler)BtnPress, (XtPointer)0); XtVaSetValues(newW, XmNcellDefaults, True, XmNcolumn, 0, XmNcellType, XmICON_CELL, NULL); }
static XmLTreeWidget WidgetToTree(Widget w, char *funcname) { char buf[256]; if (!XmLIsTree(w)) { sprintf(buf, "%s - widget not an XmLTree", funcname); XmLWarning(w, buf); return 0; } return (XmLTreeWidget)w; }
static Boolean SetValues(Widget curW, Widget reqW, Widget newW, ArgList args, Cardinal *nargs) { XmLTreeWidget t, cur; XmLGridColumn col; Boolean needsResize, needsRedraw; t = (XmLTreeWidget)newW; cur = (XmLTreeWidget)curW; needsResize = False; needsRedraw = False; #define NE(value) (t->value != cur->value) if (NE(grid.rowCount)) XmLWarning(newW, "SetValues() - can't set XmNrows"); if (NE(tree.pmColor) || NE(tree.lineColor)) needsRedraw = True; if (NE(tree.levelSpacing) || t->tree.recalcTreeWidth) { col = XmLGridGetColumn(newW, XmCONTENT, 0); if (col) col->grid.widthInPixelsValid = 0; t->tree.recalcTreeWidth = 0; needsResize = True; needsRedraw = True; } #undef NE if (needsResize) _XmLGridLayout((XmLGridWidget)t); if (needsRedraw) XmLGridRedrawAll((Widget)t); return False; }
static void XmLDrawnBDrawStringCB(Widget w, XtPointer clientData, XtPointer callData) { XmLDrawnBData *dd; XmFontList fontlist; XmString str; XmStringDirection stringDir; unsigned char drawDir, alignment; int width, height, xoff, yoff, drawWidth; Pixel fg; Dimension highlightThickness; Dimension shadowThickness, marginWidth, marginHeight; Dimension marginLeft, marginRight, marginTop, marginBottom; if (!XtIsRealized(w)) return; dd = (XmLDrawnBData *)clientData; XtVaGetValues(w, XmNlabelString, &str, NULL); if (!str && XtName(w)) str = XmStringCreateSimple(XtName(w)); if (!str) return; XtVaGetValues(w, XmNforeground, &fg, XmNfontList, &fontlist, XmNalignment, &alignment, XmNhighlightThickness, &highlightThickness, XmNshadowThickness, &shadowThickness, XmNmarginWidth, &marginWidth, XmNmarginHeight, &marginHeight, XmNmarginLeft, &marginLeft, XmNmarginRight, &marginRight, XmNmarginTop, &marginTop, XmNmarginBottom, &marginBottom, NULL); xoff = highlightThickness + shadowThickness + marginLeft + marginWidth; yoff = highlightThickness + shadowThickness + marginTop + marginHeight; width = XtWidth(w) - xoff - xoff + marginLeft - marginRight; height = XtHeight(w) - yoff - yoff + marginTop - marginBottom; if (XmIsManager(XtParent(w))) XtVaGetValues(XtParent(w), XmNstringDirection, &stringDir, NULL); else stringDir = XmSTRING_DIRECTION_L_TO_R; switch (dd->dir) { case XmDRAWNB_LEFT: drawDir = XmSTRING_LEFT; break; case XmDRAWNB_UP: drawDir = XmSTRING_UP; break; case XmDRAWNB_DOWN: drawDir = XmSTRING_DOWN; break; default: drawDir = XmSTRING_RIGHT; break; } if (drawDir == XmSTRING_LEFT || drawDir == XmSTRING_RIGHT) drawWidth = width; else drawWidth = height; if (!dd->gc) { dd->gc = XCreateGC(XtDisplay(w), XtWindow(w), 0, NULL); dd->fontStruct = XLoadQueryFont(XtDisplay(w), "fixed"); if (!dd->fontStruct) { XmLWarning(w, "DrawnBDrawString() - FATAL can't load fixed font"); return; } XSetFont(XtDisplay(w), dd->gc, dd->fontStruct->fid); } XSetForeground(XtDisplay(w), dd->gc, fg); XmLStringDrawDirection(XtDisplay(w), XtWindow(w), fontlist, str, dd->gc, xoff, yoff, drawWidth, alignment, stringDir, drawDir); XmStringFree(str); }
void XmLDrawnButtonSetType(Widget w, int drawnType, int drawnDir) { XmLDrawnBData *dd; XmDrawnButtonWidget b; XmString str; XmFontList fontlist; XGCValues values; XtGCMask mask; Dimension width, height, dim; Dimension highlightThickness, shadowThickness; Dimension marginWidth, marginHeight; Dimension marginTop, marginBottom, marginLeft, marginRight; if (!XtIsSubclass(w, xmDrawnButtonWidgetClass)) { XmLWarning(w, "DrawnButtonSetType() - not an XmDrawnButton"); return; } XtVaSetValues(w, XmNpushButtonEnabled, True, NULL); XtRemoveAllCallbacks(w, XmNexposeCallback); XtRemoveAllCallbacks(w, XmNresizeCallback); if (drawnType == XmDRAWNB_STRING && drawnDir == XmDRAWNB_RIGHT) { XtVaSetValues(w, XmNlabelType, XmSTRING, NULL); return; } b = (XmDrawnButtonWidget)w; dd = (XmLDrawnBData *)malloc(sizeof(XmLDrawnBData)); dd->type = drawnType; dd->dir = drawnDir; dd->gc = 0; if (dd->type == XmDRAWNB_STRING) { XtVaGetValues(w, XmNlabelString, &str, XmNfontList, &fontlist, XmNhighlightThickness, &highlightThickness, XmNshadowThickness, &shadowThickness, XmNmarginHeight, &marginHeight, XmNmarginWidth, &marginWidth, XmNmarginTop, &marginTop, XmNmarginBottom, &marginBottom, XmNmarginLeft, &marginLeft, XmNmarginRight, &marginRight, NULL); if (!str && XtName(w)) str = XmStringCreateSimple(XtName(w)); if (!str) str = XmStringCreateSimple(""); XmStringExtent(fontlist, str, &width, &height); XmStringFree(str); if (drawnDir == XmDRAWNB_UP || drawnDir == XmDRAWNB_DOWN) { dim = width; width = height; height = dim; } height += (highlightThickness + shadowThickness + marginHeight) * 2 + marginTop + marginBottom; width += (highlightThickness + shadowThickness + marginWidth) * 2 + marginLeft + marginRight; /* change to pixmap type so label string isnt drawn */ XtVaSetValues(w, XmNlabelType, XmPIXMAP, NULL); XtVaSetValues(w, XmNwidth, width, XmNheight, height, NULL); XtAddCallback(w, XmNexposeCallback, XmLDrawnBDrawStringCB, (XtPointer)dd); XtAddCallback(w, XmNresizeCallback, XmLDrawnBDrawStringCB, (XtPointer)dd); } else { mask = GCForeground; values.foreground = b->primitive.foreground; dd->gc = XtGetGC(w, mask, &values); XtAddCallback(w, XmNexposeCallback, XmLDrawnBDrawCB, (XtPointer)dd); XtAddCallback(w, XmNresizeCallback, XmLDrawnBDrawCB, (XtPointer)dd); } XtAddCallback(w, XmNdestroyCallback, XmLDrawnBDestroyCB, (XtPointer)dd); }
static void DrawIconCell(XmLGridCell cell, Widget w, int row, XRectangle *clipRect, XmLGridDrawStruct *ds) { XmLTreeWidget t; XmLTreeRow rowp; XmLGridCellRefValues *cellValues; XmLGridCellIcon *icon; XRectangle *cellRect, rect; Display *dpy; Window win; char *thisLine; int i, clipSet, pixWidth, pixHeight; int xoff, xoff2, midy, oddFlag, x1, y1, x2, y2; Pixmap pixmap, pixmask; t = (XmLTreeWidget)w; rowp = (XmLTreeRow)XmLGridGetRow(w, XmCONTENT, row); dpy = XtDisplay(w); win = XtWindow(w); cellValues = cell->cell.refValues; if (cellValues->type != XmICON_CELL) return; icon = (XmLGridCellIcon *)cell->cell.value; if (!icon) return; cellRect = ds->cellRect; if (!t->tree.linesData) { XmLWarning(w, "DrawIconCell() - no lines data calculated"); return; } /* draw background */ XSetForeground(dpy, ds->gc, cell->cell.refValues->background); XFillRectangle(dpy, win, ds->gc, clipRect->x, clipRect->y, clipRect->width, clipRect->height); if (t->grid.singleColScrollMode) oddFlag = t->grid.singleColScrollPos & 1; else oddFlag = 0; pixWidth = 0; xoff = t->tree.levelSpacing; xoff2 = xoff * 2; y1 = cellRect->y; y2 = cellRect->y + cellRect->height - 1; midy = cellRect->y + cellRect->height / 2; if (midy & 1) midy += 1; /* draw connecting lines and pixmap */ XSetForeground(dpy, ds->gc, t->tree.lineColor); thisLine = &t->tree.linesData[row * (t->tree.linesMaxLevel + 1)]; for (i = 0; i <= t->tree.linesMaxLevel; i++) { x1 = cellRect->x + (xoff2 * i); if (x1 >= clipRect->x + (int)clipRect->width) continue; switch (thisLine[i]) { case 'O': rect.x = x1; rect.y = cellRect->y; rect.width = cellRect->width; rect.height = cellRect->height; if (icon->pix.pixmap != XmUNSPECIFIED_PIXMAP) { pixmap = icon->pix.pixmap; pixmask = icon->pix.pixmask; pixWidth = icon->pix.width; pixHeight = icon->pix.height; } else { if (!t->tree.defaultPixmapsCreated) CreateDefaultPixmaps(t); if (rowp->tree.expands && rowp->tree.isExpanded) { pixmap = t->tree.folderOpenPixmap; pixmask = t->tree.folderOpenPixmask; } else if (rowp->tree.expands) { pixmap = t->tree.folderPixmap; pixmask = t->tree.folderPixmask; } else { pixmap = t->tree.filePixmap; pixmask = t->tree.filePixmask; } pixWidth = 16; pixHeight = 16; } XmLPixmapDraw(w, pixmap, pixmask, pixWidth, pixHeight, XmALIGNMENT_BOTTOM_LEFT, ds->gc, &rect, clipRect); break; case 'I': DrawConnectingLine(dpy, win, ds->gc, clipRect, oddFlag, x1 + xoff, y1, x1 + xoff, y2); break; case 'E': DrawConnectingLine(dpy, win, ds->gc, clipRect, oddFlag, x1 + xoff, y1, x1 + xoff, y2); DrawConnectingLine(dpy, win, ds->gc, clipRect, oddFlag, x1 + xoff, midy, x1 + xoff2, midy); break; case 'L': DrawConnectingLine(dpy, win, ds->gc, clipRect, oddFlag, x1 + xoff, y1, x1 + xoff, midy); DrawConnectingLine(dpy, win, ds->gc, clipRect, oddFlag, x1 + xoff, midy, x1 + xoff2, midy); break; case 'P': DrawConnectingLine(dpy, win, ds->gc, clipRect, oddFlag, x1 + xoff, midy, x1 + xoff, y2); DrawConnectingLine(dpy, win, ds->gc, clipRect, oddFlag, x1 + xoff, midy, x1 + xoff2, midy); break; case '-': DrawConnectingLine(dpy, win, ds->gc, clipRect, oddFlag, x1 + xoff, midy, x1 + xoff2, midy); break; } } clipSet = 0; /* draw expand/collapse graphic */ rect.x = cellRect->x + (rowp->tree.level - 1) * xoff2 + xoff - 5; rect.y = midy - 5; rect.width = 11; rect.height = 11; i = XmLRectIntersect(&rect, clipRect); if (rowp->tree.expands && rowp->tree.level && i != XmLRectOutside) { if (i == XmLRectPartial) { clipSet = 1; XSetClipRectangles(dpy, ds->gc, 0, 0, clipRect, 1, Unsorted); } x1 = rect.x; x2 = rect.x + rect.width - 1; y1 = rect.y; y2 = rect.y + rect.height - 1; XSetForeground(dpy, ds->gc, cellValues->background); XFillRectangle(dpy, win, ds->gc, x1, y1, 11, 11); XSetForeground(dpy, ds->gc, t->tree.lineColor); XDrawLine(dpy, win, ds->gc, x1 + 2, y1 + 1, x2 - 2, y1 + 1); XDrawLine(dpy, win, ds->gc, x2 - 1, y1 + 2, x2 - 1, y2 - 2); XDrawLine(dpy, win, ds->gc, x1 + 2, y2 - 1, x2 - 2, y2 - 1); XDrawLine(dpy, win, ds->gc, x1 + 1, y1 + 2, x1 + 1, y2 - 2); XSetForeground(dpy, ds->gc, t->tree.pmColor); if (!rowp->tree.isExpanded) XDrawLine(dpy, win, ds->gc, x1 + 5, y1 + 3, x1 + 5, y1 + 7); XDrawLine(dpy, win, ds->gc, x1 + 3, y1 + 5, x1 + 7, y1 + 5); } /* draw select background and highlight */ i = rowp->tree.level * xoff2 + pixWidth + XmLICON_SPACING; rect.x = cellRect->x + i; rect.y = cellRect->y; rect.height = cellRect->height; rect.width = 0; if (t->grid.colCount == 1 && rowp->tree.stringWidthValid) rect.width = rowp->tree.stringWidth + 4; else if ((int)cellRect->width > i) rect.width = cellRect->width - i; i = XmLRectIntersect(&rect, clipRect); if (i != XmLRectOutside && ds->drawSelected) { if (i == XmLRectPartial && !clipSet) { clipSet = 1; XSetClipRectangles(dpy, ds->gc, 0, 0, clipRect, 1, Unsorted); } XSetForeground(dpy, ds->gc, ds->selectBackground); XFillRectangle(dpy, win, ds->gc, rect.x, rect.y, rect.width, rect.height); } if (ds->drawFocusType != XmDRAW_FOCUS_NONE && t->grid.highlightThickness >= 2) { if (i == XmLRectPartial && !clipSet) { clipSet = 1; XSetClipRectangles(dpy, ds->gc, 0, 0, clipRect, 1, Unsorted); } XSetForeground(dpy, ds->gc, t->manager.highlight_color); x1 = rect.x; x2 = rect.x + rect.width - 1; y1 = rect.y; y2 = rect.y + rect.height - 1; XDrawLine(dpy, win, ds->gc, x1, y1, x2, y1); if (ds->drawFocusType == XmDRAW_FOCUS_CELL || ds->drawFocusType == XmDRAW_FOCUS_RIGHT) XDrawLine(dpy, win, ds->gc, x2, y1, x2, y2); XDrawLine(dpy, win, ds->gc, x1, y2, x2, y2); XDrawLine(dpy, win, ds->gc, x1, y1, x1, y2); y1 += 1; y2 -= 1; XDrawLine(dpy, win, ds->gc, x1, y2, x2, y2); XDrawLine(dpy, win, ds->gc, x1, y1, x2, y1); x1 += 1; x2 -= 1; XDrawLine(dpy, win, ds->gc, x1, y1, x1, y2); if (ds->drawFocusType == XmDRAW_FOCUS_CELL || ds->drawFocusType == XmDRAW_FOCUS_RIGHT) XDrawLine(dpy, win, ds->gc, x2, y1, x2, y2); } /* draw string */ if (icon->string) { if (ds->drawSelected == True) XSetForeground(dpy, ds->gc, ds->selectForeground); else XSetForeground(dpy, ds->gc, cellValues->foreground); XmLStringDraw(w, icon->string, ds->stringDirection, cellValues->fontList, XmALIGNMENT_LEFT, ds->gc, &rect, clipRect); } if (clipSet) XSetClipMask(dpy, ds->gc, None); }
static void CreateDefaultPixmaps(XmLTreeWidget t) { Display *dpy; Window win; XWindowAttributes attr; XColor color; Pixmap pixmap; Pixel pixel; XImage *image; int i, x, y; enum { white = 0, black = 1, yellow = 2, gray = 3 }; static unsigned short colors[4][3] = { { 65535, 65535, 65535 }, { 0, 0, 0 }, { 57344, 57344, 0 }, { 32768, 32768, 32768 }, }; static unsigned char fileMask_bits[] = { 0xf8, 0x0f, 0xfc, 0x1f, 0xfc, 0x3f, 0xfc, 0x7f, 0xfc, 0x7f, 0xfc, 0x7f, 0xfc, 0x7f, 0xfc, 0x7f, 0xfc, 0x7f, 0xfc, 0x7f, 0xfc, 0x7f, 0xfc, 0x7f, 0xfc, 0x7f, 0xfc, 0x7f, 0xfc, 0x7f, 0xf8, 0x7f }; static unsigned char folderMask_bits[] = { 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xf0, 0x0f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xf8, 0x7f }; static unsigned char folderOpenMask_bits[] = { 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xf0, 0x0f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xf0, 0x7f }; static char icons[3][16][16] = { { " GGGGGGGGG ", " GWWWWWWWWKK ", " GWWWWWWWWKWK ", " GWWWWWWWWKKKK ", " GWWWWWWWWWWGK ", " GWGGGGGGGWWGK ", " GWWKKKKKKKWGK ", " GWWWWWWWWWWGK ", " GWGGGGGGGWWGK ", " GWWKKKKKKKWGK ", " GWWWWWWWWWWGK ", " GWGGGGGGGWWGK ", " GWWKKKKKKKWGK ", " GWWWWWWWWWWGK ", " GGGGGGGGGGGGK ", " KKKKKKKKKKKK ", }, { " ", " ", " GGGGGG ", " GYYYYYYG ", " GGYYYYYYYYGG ", " GWWWWWWWWWWWYG ", " GWYYYYYYYYYYYGK", " GWYYYYYYYYYYYGK", " GWYYYYYYYYYYYGK", " GWYYYYYYYYYYYGK", " GWYYYYYYYYYYYGK", " GWYYYYYYYYYYYGK", " GWYYYYYYYYYYYGK", " GYYYYYYYYYYYYGK", " GGGGGGGGGGGGKK", " KKKKKKKKKKKK ", }, { " ", " ", " GGGGGG ", " GYYYYYYG ", " GGYYYYYYYYGG ", " GYYYYYYYYYYYYG ", " GYYYYYYYYYYYYGK", "GGGGGGGGGGGYYYGK", "GWWWWWWWWWYKYYGK", "GWYYYYYYYYYKYYGK", " GYYYYYYYYYYKYGK", " GYYYYYYYYYYKYGK", " GYYYYYYYYYYKGK", " GYYYYYYYYYYKGK", " GGGGGGGGGGGKK", " KKKKKKKKKKK ", }, }; dpy = XtDisplay(t); win = XtWindow(t); XGetWindowAttributes(dpy, win, &attr); t->tree.filePixmask = XCreatePixmapFromBitmapData(dpy, win, (char *)fileMask_bits, 16, 16, 1L, 0L, 1); t->tree.folderPixmask = XCreatePixmapFromBitmapData(dpy, win, (char *)folderMask_bits, 16, 16, 1L, 0L, 1); t->tree.folderOpenPixmask = XCreatePixmapFromBitmapData(dpy, win, (char *)folderOpenMask_bits, 16, 16, 1L, 0L, 1); for (i = 0; i < 4; i++) { color.red = colors[i][0]; color.green = colors[i][1]; color.blue = colors[i][2]; color.flags = DoRed | DoGreen | DoBlue; if (XAllocColor(dpy, attr.colormap, &color)) t->tree.pixColors[i] = color.pixel; else { color.flags = 0; XAllocColor(dpy, attr.colormap, &color); t->tree.pixColors[i] = color.pixel; } } image = XCreateImage(dpy, attr.visual, attr.depth, ZPixmap, 0, NULL, 16, 16, XBitmapPad(dpy), 0); if (!image) XmLWarning((Widget)t, "CreateDefaultPixmaps() - can't allocate image"); else image->data = (char *)malloc(image->bytes_per_line * 16); for (i = 0; i < 3; i++) { pixmap = XCreatePixmap(dpy, win, 16, 16, attr.depth); for (x = 0; x < 16; x++) for (y = 0; y < 16; y++) { switch (icons[i][y][x]) { case ' ': pixel = t->core.background_pixel; break; case 'W': pixel = t->tree.pixColors[white]; break; case 'K': pixel = t->tree.pixColors[black]; break; case 'Y': pixel = t->tree.pixColors[yellow]; break; case 'G': pixel = t->tree.pixColors[gray]; break; } XPutPixel(image, x, y, pixel); } if (image) XPutImage(dpy, pixmap, t->grid.gc, image, 0, 0, 0, 0, 16, 16); if (i == 0) t->tree.filePixmap = pixmap; else if (i == 1) t->tree.folderPixmap = pixmap; else t->tree.folderOpenPixmap = pixmap; } if (image) XDestroyImage(image); t->tree.defaultPixmapsCreated = 1; }