A meter
For more information, see the diagram of the widget hierarchy.
<photon/PtMeter.h>
The PtMeter widget is drawn as a half circle with divisional ticks at 1/4, 1/2, and 3/4 of the arc.
You can move the needle in several ways:
Your meter can include up to 3 severity arcs, drawn in colors to indicate different levels of the meter:
The widget bases its size on the text size and the specified dimensions. If the given dimensions are too small, it sizes itself appropriately based on the resize policy. The height of the widget depends on the radius of the meter, which in turn depends on the X dimension and text sizes.
To create a 3-arc meter with the default arc colors and positions (as shown above):
... PhArea_t area = { { 10, 10 }, { 200, 200 } }; ... PtSetArg(&args[0], Pt_ARG_AREA, &area, 0); PtCreateWidget(PtMeter, parent, 1, args) ...
This example creates a 1-arc meter that has a minimum value of 0, and a maximum of 1000. You can move its needle by clicking the mouse buttons; a callback notifies your application when you move the needle:
... PhArea_t area = { { 10, 10 }, { 200, 200 } }; PtCallback_t cb[1] = { {moved_cb, NULL} }; PtSetArg(&args[0], Pt_ARG_AREA, &area, 0); PtSetArg(&args[1], Pt_ARG_METER_MAX_NEEDLE_POSITION, 1000, 0); PtSetArg(&args[2], Pt_CB_METER_MOVED, &cb[0], 0); PtCreateWidget(PtMeter, parent, 3, args) ... int moved_cb(PtWidget_t *widget, void *data, PtCallbackInfo_t *info) { PtMeterCallback_t *mydata; mydata = info->cbdata; printf("Got the callback. Position was: %d severity: %d\n ", mydata->position, mydata->severity); } ...
This example creates a 3-arc meter whose needle can be moved:
with an increment of 10 for each keystroke (for example, the meter moves 0, 10, 20, ... when you press the up-arrow key).
... PhArea_t area = { { 10, 10 }, { 200, 200 } }; PtCallback_t cb[1] = { {moved_cb, NULL} }; PtSetArg(&args[0], Pt_ARG_AREA, &area, 0); PtSetArg(&args[1], Pt_ARG_METER_KEY_LEFT, Pk_Down, 0); PtSetArg(&args[2], Pt_ARG_METER_KEY_RIGHT, Pk_Up, 0); PtSetArg(&args[3], Pt_ARG_METER_INCREMENT, 10, 0); PtSetArg(&args[4], Pt_CB_METER_MOVED, &cb[0], 0); PtCreateWidget( PtMeter, parent, 5, args ); ... int moved_cb( PtWidget_t *widget, void *data, PtCallbackInfo_t *info) { PtMeterCallback_t *mydata; mydata = info->cbdata; printf("Got the callback. Position was: %d severity: %d\n", mydata->position, mydata->severity); }
You'll notice that as you move the needle on the widget, there's very little flickering. This is because when the needle moves it's merely erased and then drawn at the new position. However, if you create a meter with Pg_TRANSPARENT as a fill color, you'll notice more flickering because the needle can't merely be erased — the background must be drawn as well. In this case, flickering is reduced by calculating a bounding rectangle for the needle and redrawing only that rectangle. The most flickering (redraw) occurs when the needle is at 45° or 135°.
For flicker-free performance when using Pg_TRANSPARENT as a fill color, put the PtMeter inside a PtOSContainer widget. |
#include <stdio.h> #include <Pt.h> #include <photon/PtMeter.h> PtWidget_t *window, *meter, *quit, *sev_lbl, *pos_lbl; /* Callback for when the meter moves */ int meter_cb( PtWidget_t *widget, void *data, PtCallbackInfo_t *info) { PtMeterCallback_t *mydata; char pos[10], sev[5]; PtArg_t args[2]; mydata = info->cbdata; itoa(mydata->position, pos, 10); itoa(mydata->severity, sev, 10); /* Set the position label to the current position. */ PtSetArg(&args[0], Pt_ARG_TEXT_STRING, pos, 0); PtSetResources(pos_lbl, 1, args); /* Set the severity label to the current severity. */ PtSetArg(&args[0], Pt_ARG_TEXT_STRING, sev, 0); PtSetResources(sev_lbl, 1, args); return (Pt_CONTINUE); } /* Callback for the quit button */ int quit_cb( PtWidget_t *widget, void *data, PtCallbackInfo_t *info) { PtExit (EXIT_SUCCESS); return (Pt_CONTINUE); } int main(int argc, char *argv[]) { PtArg_t args[10]; PhDim_t win_dim = { 300, 300 }; PhArea_t meter_area = { { 10, 20 }, { 280, 280 } }; PhArea_t sev_area = { { 125, 200 }, { 50, 20 } }; PhArea_t pos_area = { { 125, 230 }, { 50, 20} }; PhArea_t quit_area = { { 230, 270 }, { 60, 20 } }; PtCallback_t callbacks[2] = { {meter_cb, NULL}, {quit_cb, NULL} }; int n = 0; char Helvetica_12[MAX_FONT_TAG]; if (PtInit(NULL) == -1) PtExit(EXIT_FAILURE); PtSetArg( &args[n++], Pt_ARG_WINDOW_TITLE, "PtMeter Demo", 0 ); PtSetArg( &args[n++], Pt_ARG_DIM, &win_dim, 0 ); if ((window = PtCreateWidget(PtWindow, Pt_NO_PARENT, n, args)) == NULL) PtExit(EXIT_FAILURE); /* Draw the meter with 3 arcs and a callback for when the meter is moved. */ n = 0; PtSetArg( &args[n++], Pt_ARG_AREA, &meter_area, 0 ); PtSetArg( &args[n++], Pt_ARG_METER_MAX_NEEDLE_POSITION, 1000, 0 ); /* Generate the name of the font to use for the meter. */ if(PfGenerateFontName("Helvetica", 0, 12, Helvetica_12) == NULL) { perror("Unable to generate font name"); } else { PtSetArg( &args[n++], Pt_ARG_METER_TEXT_FONT, Helvetica_12, 0 ); } PtSetArg( &args[n++], Pt_CB_METER_MOVED, &callbacks[0], 0 ); /* If you don't want your meter to be selectable, add * the following: * * PtSetArg( &args[n++], Pt_ARG_METER_FLAGS, * PtM_NON_SELECTABLE, PtM_NON_SELECTABLE ); */ meter = PtCreateWidget( PtMeter, window, n, args ); /* Draw a label to show the severity changes. The first label is the label to be changed, and the second is the name of the parameter. */ n = 0; PtSetArg( &args[n++], Pt_ARG_AREA, &sev_area, 0 ); PtSetArg( &args[n++], Pt_ARG_FLAGS, Pt_HIGHLIGHTED | Pt_ETCH_HIGHLIGHT, \ Pt_HIGHLIGHTED | Pt_ETCH_HIGHLIGHT); PtSetArg( &args[n++], Pt_ARG_BEVEL_WIDTH, 1, 0); PtSetArg( &args[n++], Pt_ARG_TEXT_STRING, "1", 0); sev_lbl = PtCreateWidget( PtLabel, window, n, args ); n = 0; sev_area.pos.x -= 60; PtSetArg( &args[n++], Pt_ARG_AREA, &sev_area, 0 ); PtSetArg( &args[n++], Pt_ARG_TEXT_STRING, "Severity:", 0); PtCreateWidget( PtLabel, window, n, args ); /* Draw a label to show the position changes. The first label is the label to be changed, and the second is the name of the parameter. */ n = 0; PtSetArg( &args[n++], Pt_ARG_AREA, &pos_area, 0 ); PtSetArg( &args[n++], Pt_ARG_FLAGS, Pt_HIGHLIGHTED | Pt_ETCH_HIGHLIGHT, \ Pt_HIGHLIGHTED | Pt_ETCH_HIGHLIGHT); PtSetArg( &args[n++], Pt_ARG_BEVEL_WIDTH, 1, 0); PtSetArg( &args[n++], Pt_ARG_TEXT_STRING, "0", 0); pos_lbl = PtCreateWidget( PtLabel, window, n, args ); n = 0; pos_area.pos.x -= 60; PtSetArg( &args[n++], Pt_ARG_AREA, &pos_area, 0 ); PtSetArg( &args[n++], Pt_ARG_TEXT_STRING, "Position:", 0); PtCreateWidget( PtLabel, window, n, args ); /* Draw a quit button. */ n = 0; PtSetArg( &args[n++], Pt_ARG_AREA, &quit_area, 0 ); PtSetArg( &args[n++], Pt_ARG_TEXT_STRING, "Quit", 0); PtSetArg( &args[n++], Pt_CB_ACTIVATE, &callbacks[1], 0); quit = PtCreateWidget( PtButton, window, n, args ); PtRealizeWidget( window ); PtMainLoop(); return (EXIT_SUCCESS); }
Resource | C type | Pt type | Default |
---|---|---|---|
Pt_ARG_METER_COLOR | PgColor_t | Scalar | Pg_BLACK |
Pt_ARG_METER_FLAGS | signed long | Flag | PtM_SELECTABLE |
Pt_ARG_METER_FONT_COLOR | PgColor_t | Scalar | Pg_BLACK |
Pt_ARG_METER_INCREMENT | signed short | Scalar | 5 |
Pt_ARG_METER_KEY_LEFT | int | Scalar | Pk_Left |
Pt_ARG_METER_KEY_RIGHT | int | Scalar | Pk_Right |
Pt_ARG_METER_LEVEL1_COLOR | PgColor_t | Scalar | Pg_GREEN |
Pt_ARG_METER_LEVEL1_POS | short | Scalar | 50 |
Pt_ARG_METER_LEVEL2_COLOR | PgColor_t | Scalar | Pg_YELLOW |
Pt_ARG_METER_LEVEL2_POS | short | Scalar | 75 |
Pt_ARG_METER_LEVEL3_COLOR | PgColor_t | Scalar | Pg_RED |
Pt_ARG_METER_MAX_NEEDLE_POSITION | short | Scalar | 100 |
Pt_ARG_METER_MIN_NEEDLE_POSITION | short | Scalar | 0 |
Pt_ARG_METER_NEEDLE_COLOR | PgColor_t | Scalar | Pg_WHITE |
Pt_ARG_METER_NEEDLE_POSITION | short | Scalar | 0 |
Pt_ARG_METER_NUM_SEVERITY_LEVELS | short | Scalar | 3 |
Pt_ARG_METER_TEXT_FONT | char * | String | "TextFont09" |
Pt_CB_METER_MOVED | PtCallback_t * | Link | NULL |
C type | Pt type | Default |
---|---|---|
PgColor_t | Scalar | Pg_BLACK |
The color for the center circle, outline of the meter, and divisional ticks. See PgColor_t in the Photon Library Reference.
C type | Pt type | Default |
---|---|---|
signed long | Flag | PtM_SELECTABLE |
The valid bits are:
C type | Pt type | Default |
---|---|---|
PgColor_t | Scalar | Pg_BLACK |
The font color for the minimum and maximum strings. See PgColor_t in the Photon Library Reference.
C type | Pt type | Default |
---|---|---|
signed short | Scalar | 5 |
The increment used when the keyboard is used to move the meter's needle. Every press of the assigned keys moves the meter this distance.
C type | Pt type | Default |
---|---|---|
int | Scalar | Pk_Left |
The key, as defined in <photon/PkKeyDef.h>, that you can use to move the meter's needle to the left. The default value is the left arrow, Pk_Left.
C type | Pt type | Default |
---|---|---|
int | Scalar | Pk_Right |
The key, as defined in <photon/PkKeyDef.h>, that you can use to move the meter's needle to the right. The default value is the right arrow, Pk_Right.
C type | Pt type | Default |
---|---|---|
PgColor_t | Scalar | Pg_GREEN |
The color of the first severity arc. See PgColor_t in the Photon Library Reference.
C type | Pt type | Default |
---|---|---|
short | Scalar | 50 |
The position of the end of the first severity arc, expressed as a percentage of the whole. If the minimum and/or maximum value(s) change, the location of the arc is updated to remain at this percentage.
C type | Pt type | Default |
---|---|---|
PgColor_t | Scalar | Pg_YELLOW |
The color of the second severity arc. See PgColor_t in the Photon Library Reference.
C type | Pt type | Default |
---|---|---|
short | Scalar | 75 |
The position of the end of the second severity arc, expressed as a percentage of the whole. If the minimum and/or maximum value(s) change, the location of the arc is updated to remain at this percentage.
C type | Pt type | Default |
---|---|---|
PgColor_t | Scalar | Pg_RED |
The color of the third severity arc. See PgColor_t in the Photon Library Reference.
C type | Pt type | Default |
---|---|---|
short | Scalar | 100 |
The maximum needle position; also the value drawn as the maximum.
C type | Pt type | Default |
---|---|---|
short | Scalar | 0 |
The minimum needle position; also the value drawn as the minimum.
C type | Pt type | Default |
---|---|---|
PgColor_t | Scalar | Pg_WHITE |
The color of the meter's needle. See PgColor_t in the Photon Library Reference.
C type | Pt type | Default |
---|---|---|
short | Scalar | 0 |
The current needle position, somewhere between the minimum and maximum needle position. If the position is above the maximum, the maximum is used; if the position is below the minimum, the minimum is used.
C type | Pt type | Default |
---|---|---|
short | Scalar | 3 |
The number of severity arcs (levels) that the meter displays. This must be 1, 2, or 3. If this resource is set higher than 3, only 3 arcs are displayed.
C type | Pt type | Default |
---|---|---|
char * | String | "TextFont09" |
The font for the minimum and maximum strings.
C type | Pt type | Default |
---|---|---|
PtCallback_t * | Link | NULL |
A list of PtCallback_t structures that define the callbacks invoked when the needle is moved. Each callback is passed a PtCallbackInfo_t structure that contains at least the following members:
For more information, see PhEvent_t in the Photon Library Reference.
These callbacks should return Pt_CONTINUE.
If the widget modifies an inherited resource, the “Default override” column indicates the new value. This modification affects any subclasses of the widget.