📄 tachometer.c
字号:
/* * Tachometer Widget Implementation * * Author: Kazuhiko Shutoh, 1989. * Revised by Shinji Sumimoto, 1989/9 (xtachos) * * Permission to use, copy, modify and distribute without charge this software, * documentation, images, etc. is granted, provided that this comment and the * author's name is retained. The author assumes no responsibility for lost * sleep as a consequence of use of this software. * * Send any comments, bug reports, etc. to shutoh@isl.yamaha.JUNET * * Modifications : ilham@mit.edu (July 10 '90) */#include <X11/IntrinsicP.h>#include <X11/StringDefs.h>#include <TachometerP.h>#include <math.h>/**************************************************************** * * Full class record constant * ****************************************************************/#define PI 3.1415927typedef struct { unsigned char digit[7]; } DigitRec;typedef struct { int nofline; XPoint point_list[5]; } StringRec;/* Number character database - like an "LED" */static DigitRec num_segment[] = { {{1,1,1,1,1,1,0}}, {{0,1,1,0,0,0,0}}, {{1,1,0,1,1,0,1}}, {{1,1,1,1,0,0,1}}, {{0,1,1,0,0,1,1}}, {{1,0,1,1,0,1,1}}, {{1,0,1,1,1,1,1}}, {{1,1,1,0,0,0,0}}, {{1,1,1,1,1,1,1}}, {{1,1,1,1,0,1,1}}};static XSegment offset[] = { {-10,-10, 10,-10}, { 10,-10, 10, 0}, { 10, 0, 10, 10}, { 10, 10,-10, 10}, {-10, 10,-10, 0}, {-10, 0,-10,-10}, {-10, 0, 10, 0}};/* " X 10 %" character database */static StringRec char_data[] = { { 2, /* "X" */ {{-17, -5}, {-7, 5}}}, { 2, {{-7, -5}, {-17, 5}}}, { 2, /* "1" */ {{-2, -5}, {-2, 5}}}, { 5, /* "0" */ {{2, -5}, {12, -5}, {12, 5}, {2, 5}, {2, -5}}}};#if 0{{{{ {2, -5}}}, { 5, /* "%" */ {{17, -5}, {20, -5}, {20, -2}, {17, -2}, {17, -5}}}, { 2, {{27, -5}, {17, 5}}}, {5, {{24, 2}, {27, 2}, {27, 5}, {24, 5}, {24, 2}}}};#endif#define offst(field) XtOffset(TachometerWidget, field)static XtResource resources[] = { {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), offst(tachometer.scale), XtRString, "XtDefaultForeground"}, {XtNtachometerCircleColor, XtCBorderColor, XtRPixel, sizeof(Pixel), offst(tachometer.circle), XtRString, "XtDefaultForeground"}, {XtNtachometerNeedleColor, XtCBorderColor, XtRPixel, sizeof(Pixel), offst(tachometer.needle), XtRString, "XtDefaultForeground"}, {XtNtachometerNeedleSpeed, XtCtachometerNeedleSpeed, XtRInt, sizeof(int), offst(tachometer.speed), XtRImmediate, (caddr_t) 1}, {XtNvalue, XtCValue, XtRInt, sizeof(int), offst(tachometer.value), XtRImmediate, (caddr_t) 0}, {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension), offst(core.height), XtRImmediate, (caddr_t) 100}, {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension), offst(core.width), XtRImmediate, (caddr_t) 100}, {XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension), offst(core.border_width), XtRImmediate, (caddr_t) 0}, {XtNinternalBorderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension), offst(tachometer.internal_border), XtRImmediate, (caddr_t) 0},};static void Initialize(), Realize(), Resize(), Redisplay(), Destroy();static Boolean SetValues();TachometerClassRec tachometerClassRec = { {/* core_class fields */ #define superclass (&simpleClassRec) /* superclass */ (WidgetClass) superclass, /* class_name */ "Tachometer", /* widget_size */ sizeof(TachometerRec), /* class_initialize */ NULL, /* class_part_initialize */ NULL, /* class_inited */ FALSE, /* initialize */ Initialize, /* initialize_hook */ NULL, /* realize */ Realize, /* actions */ NULL, /* num_actions */ 0, /* resources */ resources, /* num_resources */ XtNumber(resources), /* xrm_class */ NULLQUARK, /* compress_motion */ TRUE, /* compress_exposure */ TRUE, /* compress_enterleave */ TRUE, /* visible_interest */ FALSE, /* destroy */ Destroy, /* resize */ Resize, /* expose */ Redisplay, /* set_values */ 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 */ NULL, /* display_accelerator */ XtInheritDisplayAccelerator, /* extension */ NULL },/* Simple class fields initialization */ { /* change_sensitive */ XtInheritChangeSensitive }};WidgetClass tachometerWidgetClass = (WidgetClass)&tachometerClassRec;/**************************************************************** * * Private Procedures * ****************************************************************/static void DrawTachometer(), FastFillCircle(), GetneedleGC();static void GetscaleGC(), GetbackgroundGC(), DrawGauge(), DrawNeedle();static void DrawNumbers(), DrawSingleNumber(), DrawLabelString(), MoveNeedle();static void DrawTachometer(TachometerWidget w){ Cardinal center_x, center_y; Cardinal radius_x, radius_y; center_x = w->core.width / 2; center_y = w->core.height / 2; radius_x = center_x - w->tachometer.internal_border; radius_y = center_y - w->tachometer.internal_border; if ((center_x==0) || (center_y==0) || (radius_x<=0) || (radius_y<=0)) return; /* Can't draw anything -- no room */ /* Draw meter shape */ /* Big circle */ FastFillCircle(XtDisplay(w), XtWindow(w), w->tachometer.circle_GC, center_x, center_y, radius_x, radius_y); /* Inner circle same color as the background */ FastFillCircle(XtDisplay(w), XtWindow(w), w->tachometer.background_GC, center_x, center_y, (Cardinal) (radius_x * 0.95), (Cardinal) (radius_y * 0.95)); /* Small circle */ FastFillCircle(XtDisplay(w), XtWindow(w), w->tachometer.circle_GC, center_x, center_y, (Cardinal) (radius_x * 0.1), (Cardinal) (radius_y * 0.1)); /* Draw the details */ DrawGauge(w); DrawNeedle(w, w->tachometer.value);}static void FastFillCircle( Display *d, Drawable w, GC gc, Cardinal center_x, Cardinal center_y, Cardinal radius_x, Cardinal radius_y){ XPoint points[360]; Cardinal angle; for (angle = 0; angle < 360; angle++) { points[angle].x = (short) (sin((double) angle * PI / 180.0) * (double) radius_x + (double) center_x); points[angle].y = (short) (cos((double) angle * PI / 180.0) * (double) radius_y + (double) center_y); } XFillPolygon(d, w, gc, points, 360, Complex, CoordModeOrigin);}static void DrawGauge(TachometerWidget w){ XPoint points[4]; double step; Cardinal in_gauge_x, in_gauge_y; Cardinal out_gauge_x, out_gauge_y; Cardinal number_x, number_y; Cardinal center_x, center_y; Cardinal radius_x, radius_y; GC gc; double jump = 1.0; center_x = w->core.width / 2; center_y = w->core.height / 2; radius_x = center_x - w->tachometer.internal_border; radius_y = center_y - w->tachometer.internal_border; if ((center_x==0) || (center_y==0) || (radius_x<=0) || (radius_y<=0)) return; /* Can't draw anything */ gc = w->tachometer.scale_GC; for (step = 330.0; step >= 30.0; step -= jump) { if ((Cardinal) (step) % 30 == 0) { points[0].x = sin((step + 1.0) * PI / 180.0) * radius_x * 0.75 + center_x; points[0].y = cos((step + 1.0) * PI / 180.0) * radius_y * 0.75 + center_y; points[1].x = sin((step - 1.0) * PI / 180.0) * radius_x * 0.75 + center_x; points[1].y = cos((step - 1.0) * PI / 180.0) * radius_y * 0.75 + center_y; points[2].x = sin((step - 1.0) * PI / 180.0) * radius_x * 0.85 + center_x; points[2].y = cos((step - 1.0) * PI / 180.0) * radius_y * 0.85 + center_y; points[3].x = sin((step + 1.0) * PI / 180.0) * radius_x * 0.85 + center_x; points[3].y = cos((step + 1.0) * PI / 180.0) * radius_y * 0.85 + center_y; XFillPolygon(XtDisplay(w), XtWindow(w), gc, points, 4, Complex, CoordModeOrigin); number_x = sin((step + 1.0) * PI / 180.0) * radius_x * 0.65 + center_x; number_y = cos((step + 1.0) * PI / 180.0) * radius_y * 0.65 + center_y; if ((int)((330.0 - step) / 30.0) == 1) jump = 3.0; DrawNumbers(w, (unsigned char) ((330.0 - step) / 30.0), number_x, number_y); } else { in_gauge_x = sin(step * PI/180.0) * radius_x * 0.8 + center_x; in_gauge_y = cos(step * PI/180.0) * radius_y * 0.8 + center_y; out_gauge_x = sin(step * PI/180.0) * radius_x * 0.85 + center_x; out_gauge_y = cos(step * PI/180.0) * radius_y * 0.85 + center_y; XDrawLine(XtDisplay(w), XtWindow(w), gc, in_gauge_x, in_gauge_y, out_gauge_x, out_gauge_y); } } DrawLabelString(w);}static void DrawNeedle(TachometerWidget w, int load){ XPoint points[6]; double cur_theta1, cur_theta2, cur_theta3; double cur_theta4, cur_theta5; Cardinal center_x, center_y; Cardinal radius_x, radius_y; GC gc; center_x = w->core.width / 2; center_y = w->core.height / 2; radius_x = center_x - w->tachometer.internal_border;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -