#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#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[] =
"<EnterWindow>: SelectIt()\n\
<LeaveWindow>: UnSelectIt()\n\
<Btn1Down>: 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);
}
syntax highlighted by Code2HTML, v. 0.9.1