#include #include #include "LabeledPictureP.h" /* Private Data */ #define LPOffset(tag) XtOffset(LabeledPictureWidget, labeled_picture.tag) #define ACCESS_SUPER(w,tag) (XtSuperclass(w)->core_class.tag) #define CALL_SUPER(w,cmd,arg) (*ACCESS_SUPER(w,cmd))arg #define CALL_SELF(w,cmd,arg) (*XtClass(w)->core_class.cmd)arg static int defLabelMargin = 3; static int defSideMargin = 6; static Boolean defTrue = True; static XtResource resources[] = { {AiNlabel, XtCLabel, XtRString, sizeof(String), LPOffset(label), XtRString, NULL}, {AiNpixmap, XtCPixmap, XtRPixmap, sizeof(Pixmap), LPOffset(pixmap), XtRPixmap, NULL}, {AiNforeground, XtCForeground, XtRPixel, sizeof(Pixel), LPOffset(foreground), XtRString, "Black"}, {AiNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct*), LPOffset(font), XtRString, "-adobe-courier-bold-r-normal--12-120-75-75-m-70-iso8859-1"}, {AiNlabelMargin, AiCLabelMargin, XtRInt, sizeof(int), LPOffset(label_margin), XtRInt, (caddr_t)&defLabelMargin}, {AiNsideMargin, AiCSideMargin, XtRInt, sizeof(int), LPOffset(side_margin), XtRInt, (caddr_t)&defSideMargin}, {AiNcallback, XtCCallback, XtRCallback, sizeof(caddr_t), LPOffset(callback), XtRCallback, (caddr_t)NULL}, {AiNsensitive, XtCSensitive, XtRBoolean, sizeof(Boolean), LPOffset(sensitive), XtRBoolean, (caddr_t)&defTrue}, {AiNtextPosition, AiCTextPosition, AiRTextPosition, sizeof(TextPosition), LPOffset(position), XtRString, (caddr_t)"lower"}, }; static void ClassInitialize(); static void Initialize(), Redisplay(), Destroy(); static void SelectIt(), UnSelectIt(), ActivateIt(); /**** Actions ****/ static char defaultActions[] = ": SelectIt()\n\ : UnSelectIt()\n\ : ActivateIt()"; static XtActionsRec actions[] = { {"SelectIt", SelectIt}, {"UnSelectIt", UnSelectIt}, {"ActivateIt", ActivateIt}, }; LabeledPictureClassRec labeledPictureClassRec = { { /* core_class fields */ /* superclass */ (WidgetClass)&widgetClassRec, /* class_name */ "LabeledPicture", /* widget_size */ sizeof(LabeledPictureRec), /* class_initialize */ ClassInitialize, /* class_part_initialize */ NULL, /* class_inited */ FALSE, /* initialize */ Initialize, /* initialize_hook */ NULL, /* realize */ XtInheritRealize, /* actions */ actions, /* num_actions */ XtNumber(actions), /* resources */ resources, /* num_resources */ XtNumber(resources), /* xrm_class */ NULLQUARK, /* compress_motion */ TRUE, /* compress_exposure */ TRUE, /* compress_enterleave */ TRUE, /* visible_interest */ FALSE, /* destroy */ Destroy, /* resize */ XtInheritResize, /* expose */ Redisplay, /* set_values */ NULL, /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, /* accept_focus */ NULL, /* version */ XtVersion, /* callback_private */ NULL, /* tm_table */ defaultActions, /* query_geometry */ NULL, }, }; WidgetClass labeledPictureWidgetClass = (WidgetClass)&labeledPictureClassRec; #define _max_(x,y) ((x)>(y)?(x):(y)) /* * Converter from String to TextPosition */ static void convertStr2TextPosition(args,numargs,from,to) XrmValue *args; Cardinal *numargs; XrmValue *from; XrmValue *to; { TextPosition *pos = (TextPosition*)XtMalloc(sizeof(TextPosition)); switch (*from->addr) { case 'l': case 'L': switch(from->addr[1]) { case 'e': case 'E': *pos = left; break; case 'o': case 'O': *pos = lower; break; default: XtWarning("LabeledPicture: Bad text position string"); *pos = lower; } break; case 'r': case 'R': *pos = right; break; case 'u': case 'U': *pos = upper; break; default: XtWarning("LabeledPicture: Bad text position string"); *pos = lower; } to->size = sizeof(TextPosition); to->addr = (caddr_t)pos; } static void ClassInitialize() { XtAddConverter(XtRString, AiRTextPosition, convertStr2TextPosition, NULL,0); } static void AdjustSize(w,force) LabeledPictureWidget w; Boolean force; { LabeledPicturePart *lp = &w->labeled_picture; int depth; int x,y,bwidth; Window rootwin; lp->label_width = XTextWidth(lp->font,lp->label,strlen(lp->label)); if (lp->pixmap != NULL && lp->pixmap != AiNullPixmap) { XGetGeometry(XtDisplay(w),lp->pixmap, &rootwin, &x, &y, &lp->pixmap_width, &lp->pixmap_height, &bwidth, &depth); if (w->core.width == 0 || (force && !(lp->status & ST_INIT_WIDTH))) { if (lp->position == upper || lp->position == lower) { w->core.width = _max_(lp->pixmap_width, lp->label_width)+ lp->side_margin*2; } else { w->core.width = lp->pixmap_width+ lp->label_width+ lp->side_margin*3; } } if (w->core.height == 0 || (force && !(lp->status & ST_INIT_HEIGHT))) { if (lp->position == upper || lp->position == lower) { w->core.height = lp->pixmap_height+ lp->font->max_bounds.descent+ lp->font->max_bounds.ascent+ lp->label_margin; } else { w->core.height = _max_(lp->pixmap_height, lp->font->max_bounds.descent+ lp->font->max_bounds.ascent)+ lp->label_margin; } } if (depth == 1) { /* bitmap */ w->labeled_picture.pixmap_is_bitmap = True; } else if (depth != XtScreen(w)->root_depth) { XtError("LabeledPicture: pixmap has different depth from the screen"); } else w->labeled_picture.pixmap_is_bitmap = False; } else { lp->pixmap_width = lp->pixmap_height = 0; if (w->core.width == 0 || (force && !(lp->status & ST_INIT_WIDTH))) w->core.width = lp->label_width+lp->side_margin; if (w->core.height == 0 || (force && !(lp->status & ST_INIT_HEIGHT))) w->core.height = lp->font->max_bounds.descent+ lp->font->max_bounds.ascent+ lp->label_margin; } } static void Initialize(request, new) Widget request, new; { XGCValues gv; LabeledPictureWidget w = (LabeledPictureWidget) new; LabeledPicturePart *lp = &w->labeled_picture; gv.font = lp->font->fid; gv.foreground = lp->foreground; gv.background = w->core.background_pixel; lp->label_GC = XtGetGC((Widget)w, GCFont | GCForeground | GCBackground, &gv); lp->picture_GC = XtGetGC((Widget)w, GCForeground | GCBackground, &gv); if (lp->label == NULL) lp->label = w->core.name; lp->status = 0; if (w->core.width) lp->status |= ST_INIT_WIDTH; if (w->core.height) lp->status |= ST_INIT_HEIGHT; AdjustSize(w,False); } static void Redisplay(new) Widget new; { LabeledPictureWidget w = (LabeledPictureWidget)new; LabeledPicturePart *lp = &(w->labeled_picture); int len = strlen(w->labeled_picture.label); int picX,picY,lblX,lblY; if (lp->position == left) { picX = lp->label_width+lp->side_margin; picY = 0; lblX = 0; lblY = w->core.height/2; } else if (lp->position == right) { picX = 0; picY = 0; lblX = lp->pixmap_width+lp->side_margin; lblY = w->core.height/2; } else if (lp->position == upper) { picX = (w->core.width-lp->pixmap_width)/2; picY = lp->font->max_bounds.ascent+ lp->font->max_bounds.descent+ lp->label_margin; lblX = (w->core.width-lp->label_width)/2; lblY = lp->font->max_bounds.ascent; } else { /* lower */ picX = (w->core.width-lp->pixmap_width)/2; picY = 0; lblX = (w->core.width-lp->label_width)/2; lblY = lp->pixmap_height+lp->label_margin+ lp->font->max_bounds.ascent; } XClearWindow(XtDisplay(w),XtWindow(w)); if (lp->pixmap_is_bitmap) { if (lp->pixmap != AiNullPixmap) { XCopyPlane(XtDisplay(w), lp->pixmap, XtWindow(w), lp->picture_GC, 0,0, lp->pixmap_width,lp->pixmap_height, picX,picY, 1); } } else { if (lp->pixmap != AiNullPixmap) { XCopyArea(XtDisplay(w), lp->pixmap, XtWindow(w), lp->picture_GC, 0,0, lp->pixmap_width,lp->pixmap_height, picX,picY); } } XDrawString(XtDisplay(w),XtWindow(w), lp->label_GC, lblX,lblY, lp->label,len); if (lp->status & ST_SELECT) XDrawRectangle(XtDisplay(w),XtWindow(w),lp->picture_GC, 0,0,w->core.width-1, w->core.height-1); } static void Destroy(new) Widget new; { LabeledPictureWidget lw = (LabeledPictureWidget)new; LabeledPicturePart *w = &(lw->labeled_picture); if (w->pixmap != AiNullPixmap) XFreePixmap(XtDisplay(new),w->pixmap); XtReleaseGC(new,w->label_GC); XtReleaseGC(new,w->picture_GC); } /* * Actions */ static void SelectIt(w) LabeledPictureWidget w; { if (w->labeled_picture.sensitive) { w->labeled_picture.status |= ST_SELECT; Redisplay(w); } } static void UnSelectIt(w) LabeledPictureWidget w; { if (w->labeled_picture.sensitive) { w->labeled_picture.status &= ~ST_SELECT; Redisplay(w); } } static void ActivateIt(w,event,params,nparams) LabeledPictureWidget w; XEvent *event; String *params; Cardinal *nparams; { UnSelectIt(w); if (w->labeled_picture.sensitive) { XtCallCallbacks(w, AiNcallback, (caddr_t)event); } } /*********** Functions **********/ /* Get label value */ char * AiGetLabel(w) LabeledPictureWidget w; { return w->labeled_picture.label; } void AiChangeLabel(w,label) LabeledPictureWidget w; String label; { w->labeled_picture.label = label; } Pixmap AiChangePixmap(w,p,resizeWidth,resizeHeight) LabeledPictureWidget w; Pixmap p; Boolean resizeWidth,resizeHeight; { LabeledPicturePart *lp = &(w->labeled_picture); Pixmap old = lp->pixmap; int width = w->core.width, height = w->core.height; lp->pixmap = p; AdjustSize(w,True); if (width != w->core.width || height != w->core.height) { XtResizeWidget(w, w->core.width, w->core.height, w->core.border_width); } return old; } Pixmap AiChangeBitmapData(wig,bit,width,height,resizeWidth,resizeHeight) Widget wig; char *bit; int width,height; Boolean resizeWidth,resizeHeight; { Pixmap p; LabeledPictureWidget w = (LabeledPictureWidget)wig; p = XCreatePixmapFromBitmapData( XtDisplay(wig), XtWindow(wig), bit, width, height, w->labeled_picture.foreground, w->core.background_pixel, XtScreen(w)->root_depth); if (p == 0) return 0; return AiChangePixmap(wig,p,resizeWidth,resizeHeight); }