#ifndef _HPUX_SOURCE #define _HPUX_SOURCE #endif #include #include #include #include "CircPercP.h" #define DEFAULT_LENGTH 75 #define DEFAULT_WIDTH 75 #define offset(field) XtOffsetOf(XfwfCircularPercentageRec, field) static XtResource resources[] = { { XtNborderColor, XtCBorderColor, XtRPixel, sizeof(Pixel), offset(circular_percentage.border_color), XtRString, (XtPointer) "black" }, { XtNinteriorColor, XtCInteriorColor, XtRPixel, sizeof(Pixel), offset(circular_percentage.interior_color), XtRString, (XtPointer) "red" }, { XtNcompletedColor, XtCCompletedColor, XtRPixel, sizeof(Pixel), offset(circular_percentage.completed_color), XtRString, (XtPointer) "yellow" }, { XtNpercentageCompleted, XtCPercentageCompleted, XtRInt, sizeof(int), offset(circular_percentage.iPercentageCompleted), XtRImmediate, (XtPointer) 0 } }; #if NeedFunctionPrototypes > 0 static void Initialize(Widget,Widget,ArgList,Cardinal *); static void Redisplay(Widget,XExposeEvent *); static void Destroy(Widget); static void Resize(Widget); static Boolean SetValues(Widget,Widget,Widget,ArgList,Cardinal *); static XtGeometryResult QueryGeometry(Widget, XtWidgetGeometry *, XtWidgetGeometry *); static void MakeGC(XfwfCircularPercentageWidget); static void RedrawPart(XfwfCircularPercentageWidget, int, int); #else static void Initialize(); static void Redisplay(); static void Destroy(); static void Resize(); static Boolean SetValues(); static XtGeometryResult QueryGeometry(); static void MakeGC(); static void RedrawPart(); #endif XfwfCircularPercentageClassRec xfwfCircularPercentageClassRec = { { /* core_class fields */ /* superclass */ (WidgetClass) &widgetClassRec, /* class_name */ "XfwfCircularPercentage", /* widget_size */ sizeof(XfwfCircularPercentageRec), /* class_initialize */ NULL, /* class_part_initialize */ NULL, /* class_inited */ FALSE, /* initialize */ (XtInitProc) Initialize, /* initialize_hook */ NULL, /* realize */ XtInheritRealize, /* actions */ NULL, /* num_actions */ 0, /* resources */ resources, /* num_resources */ XtNumber(resources), /* xrm_class */ NULLQUARK, /* compress_motion */ TRUE, /* compress_exposure */ XtExposeCompressMultiple, /* compress_enterleave */ TRUE, /* visible_interest */ FALSE, /* destroy */ (XtWidgetProc) Destroy, /* resize */ (XtWidgetProc) Resize, /* expose */ (XtExposeProc) Redisplay, /* set_values */ (XtSetValuesFunc) SetValues, /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, /* accept_focus */ NULL, /* version */ XtVersion, /* callback_private */ NULL, /* tm_table */ NULL, /* query_geometry */ (XtGeometryHandler) QueryGeometry, /* display_accelerator */ XtInheritDisplayAccelerator, /* extension */ NULL }, { /* extension */ 0 } }; WidgetClass xfwfCircularPercentageWidgetClass = (WidgetClass) & xfwfCircularPercentageClassRec; #if NeedFunctionPrototypes > 0 static void Initialize(Widget treq_widget, Widget tnew_widget, ArgList args, Cardinal *num_args) #else static void Initialize(treq_widget,tnew_widget,args,num_args) Widget treq_widget; Widget tnew_widget; ArgList args; Cardinal *num_args; #endif { XfwfCircularPercentageWidget new_widget = (XfwfCircularPercentageWidget) tnew_widget; Dimension dimWidth, dimHeight; dimWidth = DEFAULT_LENGTH; dimHeight = DEFAULT_WIDTH; if (dimWidth > new_widget -> core.width) new_widget -> core.width = dimWidth; if (dimHeight > new_widget -> core.height) new_widget -> core.height = dimHeight; if (new_widget -> circular_percentage.iPercentageCompleted < 0) { XtWarning("XfwfCircularPercentage: percentageCompleted resource should have a value between 0 and 10000,\n (value specified was negative)."); new_widget -> circular_percentage.iPercentageCompleted = 0; } else if (new_widget -> circular_percentage.iPercentageCompleted > 10000) { XtWarning("XfwfCircularPercentage: percentageCompleted resource should have a value between 0 and 10000,\n (value specified was over 10000)."); new_widget -> circular_percentage.iPercentageCompleted = 10000; } new_widget -> circular_percentage.gc = None; } #if NeedFunctionPrototypes > 0 static void CalculateArcs(XfwfCircularPercentageWidget our_widget, XArc *arcs, int iPercentageCompleted) #else static void CalculateArcs(our_widget,arcs,iPercentageCompleted) XfwfCircularPercentageWidget our_widget; XArc *arcs; int iPercentageCompleted; #endif { int iXfwfCircularPercentageArc; iXfwfCircularPercentageArc = (iPercentageCompleted * 360 * 64) / 10000; arcs[0].x = 5 ; arcs[0].y = 5 ; arcs[0].width = our_widget -> core.width - arcs[0].x * 2; arcs[0].height = our_widget -> core.height - arcs[0].x * 2; arcs[0].angle1 = 90 * 64 ; arcs[0].angle2 = - iXfwfCircularPercentageArc ; #ifdef WANT_NOISE fprintf (stderr, "(x,y) : (%d,%d) (width,height) (%d,%d) (angle1,angle2) (%d,%d)\n", (int) arcs[0].x,(int)arcs[0].y, (int)arcs[0].width,(int)arcs[0].height, (int)arcs[0].angle1,(int)arcs[0].angle2); #endif arcs[1].x = 5 ; arcs[1].y = 5 ; arcs[1].width = our_widget -> core.width - arcs[1].x * 2; arcs[1].height = our_widget -> core.height - arcs[1].x * 2; arcs[1].angle1 = (90 * 64 - iXfwfCircularPercentageArc) ; arcs[1].angle2 = - (360 * 64 - iXfwfCircularPercentageArc); #ifdef WANT_NOISE fprintf (stderr, "(x,y) : (%d,%d) (width,height) (%d,%d) (angle1,angle2) (%d,%d)\n", (int) arcs[1].x,(int)arcs[1].y, (int)arcs[1].width,(int)arcs[1].height, (int)arcs[1].angle1,(int)arcs[1].angle2); #endif } #if NeedFunctionPrototypes > 0 static void Redisplay(Widget w, XExposeEvent *event) #else static void Redisplay(w,event) Widget w; XExposeEvent *event; #endif { XfwfCircularPercentageWidget our_widget = (XfwfCircularPercentageWidget) w; Display *pDisplay = XtDisplay(our_widget); Window window = XtWindow(our_widget); XArc arcs[2]; Dimension dimWidth = our_widget -> core.width; Dimension dimHeight = our_widget -> core.height; if (!XtIsRealized(w)) return; if ((our_widget -> core.width < 25) || (our_widget -> core.height < 25)) return; if (our_widget -> circular_percentage.gc == None) MakeGC(our_widget); CalculateArcs(our_widget,arcs,our_widget -> circular_percentage.iPercentageCompleted); if (arcs[0].angle2) { XSetForeground(pDisplay, our_widget -> circular_percentage.gc, our_widget -> circular_percentage.completed_color); XFillArcs(pDisplay, window, our_widget -> circular_percentage.gc, &arcs[0], 1); } if (arcs[1].angle2) { XSetForeground(pDisplay, our_widget -> circular_percentage.gc, our_widget -> circular_percentage.interior_color); XFillArcs(pDisplay, window, our_widget -> circular_percentage.gc, &arcs[1], 1); } XSetForeground(pDisplay, our_widget -> circular_percentage.gc, our_widget -> circular_percentage.border_color); XDrawArc(pDisplay, window, our_widget -> circular_percentage.gc, 5,5, dimWidth - 10, dimHeight - 10, 0, 360*64); XFlush(pDisplay); } #define WidgetValuesDiffer(w1,w2,component) (w1 -> circular_percentage.component != \ w2 -> circular_percentage.component) /* ARGSUSED */ #if NeedFunctionPrototypes > 0 static Boolean SetValues(Widget current, Widget request, Widget new_widget, ArgList args, Cardinal *num_args) #else static Boolean SetValues(current, request, new_widget, args, num_args) Widget current; Widget request; Widget new_widget; ArgList args; Cardinal *num_args; #endif { Boolean bShouldRedraw = False; XfwfCircularPercentageWidget current_widget = (XfwfCircularPercentageWidget) current; XfwfCircularPercentageWidget check_widget = (XfwfCircularPercentageWidget) new_widget; if (WidgetValuesDiffer(current_widget,check_widget, border_color) || WidgetValuesDiffer(current_widget,check_widget, interior_color) || WidgetValuesDiffer(current_widget,check_widget, completed_color)) bShouldRedraw = True; if (WidgetValuesDiffer(current_widget,check_widget, iPercentageCompleted)) { if (check_widget -> circular_percentage.iPercentageCompleted < 0 || check_widget -> circular_percentage.iPercentageCompleted > 10000) { XtWarning("XfwfCircularPercentage: new value for percentage out of range [0,10000])."); check_widget -> circular_percentage.iPercentageCompleted = current_widget -> circular_percentage.iPercentageCompleted; } else bShouldRedraw = True; } if (bShouldRedraw) Redisplay(new_widget,NULL); return False; } #if NeedFunctionPrototypes > 0 static void Destroy(Widget w) #else static void Destroy(w) Widget w; #endif { XfwfCircularPercentageWidget our_widget = (XfwfCircularPercentageWidget) w; if (our_widget -> circular_percentage.gc != None) XFreeGC(XtDisplay(our_widget),our_widget -> circular_percentage.gc); } #if NeedFunctionPrototypes > 0 static void Resize(Widget w) #else static void Resize(w) Widget w; #endif { } #if NeedFunctionPrototypes > 0 static XtGeometryResult QueryGeometry(Widget w, XtWidgetGeometry *proposed, XtWidgetGeometry *answer) #else static XtGeometryResult QueryGeometry(w, proposed, answer) Widget w; XtWidgetGeometry *proposed; XtWidgetGeometry *answer; #endif { XfwfCircularPercentageWidget our_widget = (XfwfCircularPercentageWidget) w; XtGeometryResult xtgrOutcome = XtGeometryYes; #ifdef WANT_NOISE fprintf(stderr, "Proposed:\n\nreq_mode : %d,\n(x,y):(%d,%d)\n(width,height) : (%d,%d)\nbw: %d, sibling : %x, stack_mode : %i\n\n", proposed -> request_mode, proposed -> x, proposed -> y, proposed -> width, proposed -> height, proposed -> border_width, proposed -> sibling, proposed -> stack_mode); #endif answer -> request_mode = CWWidth | CWHeight; answer -> width = DEFAULT_LENGTH; answer -> height = DEFAULT_WIDTH; if (proposed -> request_mode & CWWidth) if (proposed -> width >= answer -> width) answer -> width = proposed -> width; else xtgrOutcome = XtGeometryAlmost; if (proposed -> request_mode & CWHeight) if (proposed -> height >= answer -> height) answer -> height = proposed -> height ; else xtgrOutcome = XtGeometryAlmost; if (answer -> width == our_widget -> core.width && answer -> height == our_widget -> core.height) xtgrOutcome = XtGeometryNo; #ifdef WANT_NOISE fprintf(stderr, "Answer:\n\n(width,height) : (%d,%d)\n", answer -> width, answer -> height); #endif return xtgrOutcome; } #if NeedFunctionPrototypes > 0 static void MakeGC(XfwfCircularPercentageWidget w) #else static void MakeGC(w) XfwfCircularPercentageWidget w; #endif { Display *pDisplay = XtDisplay(w); XGCValues xgcValues; xgcValues.function = GXcopy; xgcValues.line_width = 1; xgcValues.line_style = LineSolid; xgcValues.fill_style = FillSolid; xgcValues.fill_rule = EvenOddRule; xgcValues.cap_style = CapRound; xgcValues.join_style = JoinMiter; xgcValues.arc_mode = ArcPieSlice ; w -> circular_percentage.gc = XCreateGC(pDisplay, XtWindow(w), GCFunction| GCLineWidth| GCLineStyle| GCFillStyle| GCFillRule| GCCapStyle| GCJoinStyle| GCArcMode, &xgcValues); } #if NeedFunctionPrototypes > 0 void XfwfCircularPercentageSetPercentage(Widget w, int iNewXfwfCircularPercentage) #else void XfwfCircularPercentageSetPercentage(w,iNewXfwfCircularPercentage) Widget w; int iNewXfwfCircularPercentage ; #endif { XfwfCircularPercentageWidget our_widget = (XfwfCircularPercentageWidget) w; if (! XtIsSubclass(w,xfwfCircularPercentageWidgetClass)) return; if (iNewXfwfCircularPercentage < 0 || iNewXfwfCircularPercentage > 10000) { XtWarning("XfwfCircularPercentage: new value for percentage out of range [0,10000])."); return; } RedrawPart(our_widget, our_widget -> circular_percentage.iPercentageCompleted, iNewXfwfCircularPercentage); our_widget -> circular_percentage.iPercentageCompleted = iNewXfwfCircularPercentage; } #if NeedFunctionPrototypes > 0 static void RedrawPart(XfwfCircularPercentageWidget our_widget, int iOldXfwfCircularPercentage, int iNewXfwfCircularPercentage) #else static void RedrawPart(our_widget, iOldXfwfCircularPercentage, iNewXfwfCircularPercentage) XfwfCircularPercentageWidget our_widget; int iOldXfwfCircularPercentage; int iNewXfwfCircularPercentage; #endif { Display *pDisplay = XtDisplay(our_widget); Window window = XtWindow(our_widget); XArc old_arc[2] ; XArc new_arc[2] ; short sDifference; Pixel drawing_color; short sAngle; if (! XtIsRealized((Widget) our_widget)) return; if (our_widget -> circular_percentage.gc == None) { Redisplay((Widget)our_widget,NULL); return; } if (iOldXfwfCircularPercentage == iNewXfwfCircularPercentage) return; #ifdef WANT_NOISE fprintf(stderr,"*** Redraw Part (%d,%d)\n",iOldXfwfCircularPercentage,iNewXfwfCircularPercentage); #endif CalculateArcs(our_widget, old_arc, iOldXfwfCircularPercentage); CalculateArcs(our_widget, new_arc, iNewXfwfCircularPercentage); if (iNewXfwfCircularPercentage < iOldXfwfCircularPercentage) { sDifference = (old_arc[1].angle1 - new_arc[1].angle1); drawing_color = our_widget -> circular_percentage.interior_color; sAngle = new_arc[1].angle1; } else { sDifference = (new_arc[1].angle1 - old_arc[1].angle1); drawing_color = our_widget -> circular_percentage.completed_color; sAngle = old_arc[1].angle1; } XSetForeground(pDisplay, our_widget -> circular_percentage.gc, drawing_color); XFillArc(pDisplay, window, our_widget -> circular_percentage.gc, old_arc[1].x, old_arc[1].y, old_arc[1].width, old_arc[1].height, sAngle, sDifference); XSetForeground(pDisplay, our_widget -> circular_percentage.gc, our_widget -> circular_percentage.border_color); XDrawArc(pDisplay, window, our_widget -> circular_percentage.gc, old_arc[1].x, old_arc[1].y, old_arc[1].width, old_arc[1].height, sAngle, sDifference); XFlush(pDisplay); }