Easy Drawing Widget
EzDraw

Classname: XwEzDrawWidgetClass
 
 

Header files: WEzdraw.h public header

WEzdrawP.h private header

Description:

The EzDrawWidget is defined to give a conveniant tool for easy drawing of 2D diagrams to a programmer. It may draw one ore more curves onto the screen plotting scaling and grid internally. Exposes and handled automatically. The curves may have different co lours. They are plotted normally as solid lines, but the points may be marked with 33 different 6x6 symbols. As the real drawing is done to a pixmap, several useful features are added. If the pixmap is bigger than the visible portion of screen, the middle button of mouse may be used to drag the visible part around the pixmap. Some possible automatic functions are integrated, so »automove«, which moves the visible part in a way, that the actual plotted point will always be visible; or »autoscale«, which chan ges the scale, if a point will be plotted outside pixmap. Some other features return the scaled value of cursor, or enable a »history« which can be used for hardcopy. Most controls can be done via standard resources, some more specific need the public func tions.

Example of a standard drawing:

Graphic1

Resources:

The widget includes the »core« and the »primitive« class with all resources. To describe it's special features, it has several resources for it's own. The following table contains the resource-name, the resource-class and the access-type. Defining the reso urce in a general resourcefile like .Xdefaults, means, leave out the prefix XwN or XwC. The access type defines if the resource may be set at creation »C«, using XtSetValues »S«, only at creation using XtSetArg »CS« and being read using XtGetValues »G«.

Name  Class  Type  Default  Access 
XmNdestroyCallback  XtCallbackList  NULL  S C 
XmNinputCallback  XtCallbackList  NULL  S C 
XmNexposeCallback  XmCExposeCallback  XtCallbackList  NULL  S C 
XmNresizeCallback  XmCResizeCallback  XtCallbackList  NULL  S C 
XwNezdrawBorder  XwCEzdrawBorder  bool  FALSE  C S G 
XwNezdrawGridScale  XwCEzdrawGridScale  Float[4]  NULL  CS S G 
XwNezdrawScale  XwCEzdrawScale  Float[4]  NULL  CS S G 
XwNezdrawAnnotColor  XwCEzdrawAnnotColor  Pixel  inherit  C S G 
XwNezdrawGridColor  XwCEzdrawGridColor  Pixel  inherit  C S G 
XwNezdrawCUcolor  XwCEzdrawCUcolor  Pixel  inherit  C S G 
XwNezdrawAnnotXNdec  XwCEzdrawAnnotXNdec  Int  C S G 
XwNezdrawAnnotYNdec  XwCEzdrawAnnotYNdec  Int  C S G 
XwNezdrawAnnotXNgrid  XwCEzdrawAnnotXNgrid  Int  C S G 
XwNezdrawAnnotYNgrid  XwCEzdrawAnnotYNgrid  Int  C S G 
XwNezdrawNcurves  XwCEzdrawNcurves  Int  DefaultNcurves(10)  C S G 
XwNezdrawAnnotation  XwCEzdrawAnnotation  Int  left+down  C S G 
XwNezdrawAddvalue  XwCEdrawAddvalue  Bool  FALSE  C S G 
XwNezdrawAddtext  XwCEzdrawAddtext  String  NULL  C S G 
XmNfontList  XmCFontList  XmFontList  inherit  C S G 
XwNezdrawHistory  XwCEzdrawHistory  Bool  TRUE  C S G 
XwNezdrawHistorysize  XwCEzdrawHistorysize  Int  heigt*width/20  C S G 
XwNezdrawPixFactor  XwCEzdrawPixFactor  Int  C S G 
XwNezdrawAutoscroll  XwCEzdrawAutoscroll  Int  C S G 

Detailed Description of special Resources:

Callbacks:
Possible Callbacks are:

XwNdestroyCallback, XmNexposeCallback, XmresizeCallback, XmNinputCallback. Depending on type of callback, the items within the callbackstructure will have slightly different meaning. The most important callback, I think, will be the Input-Callback, as it returns the scaled position of the cursor.

Callback Structure:

typedef struct {
int reason;
XEvent *event; int fd;
float x_value;
float y_value;
float x_max;
float y_max;

}XwEzdrawCallbackStruct;

Expose: x_value/x_max abscissa minimum/maximum scaled

y_value/y_max ordinate minimum/maximum..scaled

Resize: x_value/x_max abscissa minimum/maximum scaled

y_value/y_max ordinate minimum/maximum..scaled

Destroy: No meaning

Input: Only valid for button 1 (left mouse) down)
x_value abscissa value of cursor position
y_value ordinate value of cursor position.

Normally there is no need to handle expose or resize, as the widget does all necessay things itself, but sometimes, it might be useful to react on resize, p.e. rescaling the plot.
 
 

Resources, that must be set:
XwNezdrawScale XwNezdrawGridScale

There is no possibility to create a plot without having any scale, so these resources must be set at creation, they might be changed during lifetime.The only method to set them is using SetValue, as they need an array of four float values. The first pair d efines the abscissa, the second the ordinate. XwNezdrawScale uses the first value as the minimum value of the visible area and the second as the size(width/height) of visible area. Internally it scales the total pixmap according to these values. XwNezdrawG ridScale uses the first value as the minimum (first) grid value and the second as distance to next gridline. Again, not only the visible, but the total pixmap will be gridded.

Resources, that should be set:
XwNezdrawAnnotation

This resources defines the position of annotation, the default is set to the standard, i.e. left and down. The value is a sum of definitions for horizontal and vertical. Changing the resource at run-time will change the display immediately.

Possible values:
XwEzdrawLeAnno 2 /* annotation left */
XwEzdrawRiAnno 4 /* annotation right */
XwEzdrawUpAnno 8 /* annotation above plot */
XwEzdrawDoAnno 16 /* annotation below plot */
XwEzdrawNoAnno 0 /* No annotation */

XwNezdrawAnnotXNdec XwNezdrawAnnotYNdec

These two control the number of decimals for annotation. Be careful and reduce them to a minimum, as there is no protection against overwriting of numbers. Together with the GridScale it might happen, that the annotation distance is to small for big number s, therefor the next two resources allow to skip some gridlines without drawing annotation.

XwNezdrawAnnotXNgrid XwNezdrawAnnotYNgrid

As the default of 1 shows, they define, how often annotation should be plotted to gridlines. So a value of 2 will say, that every other gridline gets annotation.

Additional controlling Resources:
Colours:

The colour of the curve itself must be set via a public function, as each curve may have a different colour. But all other colours, background, grid, annotation and annotation background may be set as resource.

Resource  Function  default  Remark 
XwNezdrawCUcolor  Background colour of the plotting area  Inherited from background  No immediate change 
XwNezdrawAnnotColor  Colour for Annotation text  Inherited from foreground  No immediate change 
XwNezdrawGridColor  Colour for the gridlines  Inherited from foreground  No immediate change 
background  Background colour  No immediate change 
 

As the above colours won't change immediately whe you change the resource, but will be effective only when a total redraw is enforced, the colour of the curve can be changed via a public function, the colourchange will affect the new plotted points only, a s long as no enforced redraw will happen.

XwNezdrawAddvalue XwNezdrawAddtext

XwNezdrawAddvalue is a switch, if it is set to true, the actual plotted point will be displayed with ist numeric values as a pair of ordinate/abscissa values, using the font and colour of annotation.

XwNezdrawAddtext is a string that will be displayed in the upper left corner of the plotting area. In addition to this text, a curve specific text (using the colour of specified curve) can be added using a public function.

HISTORY and PIXMAP-size:
An important set of resources controls the size of the used pixmap, allowing to drag the visible area around a virtual area.A second set controls the option history storing all given points of curve together with the drawing flag in a ring-buffer.

XwNezdrawPixFactor

The default is set to 1, So the internal pixmap is as big as the visible area. Of course dragging doen't make any sense, resizing requires a replotting (if history enabled) or looses information. This resource is defined as a factor, saying the pixmap is X wNezdrawPixFactor times bigger than the visible area.. The visible area will be initiated in the middle of the pixmap. A dynamic change at run time will enforce a recreate and replot from history.

XwNezdrawHistory XwNezdrawHistorysize

The first is just a switch, enabling the ring-buffer. Ist default size is calculated from feight times width divided by 20. So normally this size is big enough to hold a lot of points.Using XwNezdrawHistorysize gives a lot more control over the number of p oints, that can be stored.
 
 

XwNezdrawAutoscroll

Together with a pixmap bigger than the visible area it is possible to enforce the visible area to show the last plotted point. If the resource is set to XwEzdrawAutoMove (2), plotting a point outside the visible area will immediately move the area to show the point. Another automatic option is XwCEzdrawAutoScal (1), this option will change the scaling by 1.25, rescale and redraw all. These two option may be combined by adding.

XwNezdrawBorder

draws a border in foreground colour around the plotting area.
 
 

Public Functions

XwEzdrawAddcurve
long int XwEzdrawAddcurve (Widget w , unsigned long unt Colour);
 
 

To use the plotting feature this function must be called first of all after creating the widget. It defines the colour of the requested curve and allocates memory for it. The return value should be used as curve ID for further access of this particular cur ve. It will be automatically created and counts from zero, so the first ID is 0.
 
 

XwEzdrawcurve
void XwEzdrawcurve (Widget w , long int ID , float xy[2] . int flag , char symbol);

The basic function for plotting. It adds a point to the curve given by it's ID and plots it depending on flag. The parameter symbol is used, if symbol mode is requested. It defines the symbol out of 32 possible symbols. As it might be, that a hardcopy is n eeded, the symboldefinition is synchronized with the definitions of PS-plot system.

flag: basically, an odd value forces immediate display on screen.

XwEzdrawLinePlot (2) connects the actual point to previous with solid line

XwEzdrawSymbPlot (4) plots the point using the given symbol

XwEzdrawCharPlot(8) plots the point using the given character (character is centered), not plotting the corresponding symbol

XwEzdrawMovePlot(16)  moves to the actual point without any connection to previous

both values may be added, giving a combination, adding a 1 will immediately force display, but without this forcing, no display will appear at all until a force is given.

The array xy[2] must contain the coordinate values x and y for plotting.

Symbol definitions: (plotted in a 6x6 pixel matrix)

Value  Letter alias  description 
rectangle 
Filled rectangle 
circle 
Filled circle 
Triangle pointing up 
Filled triangle pointing up 
Triangle pointing down 
Filled triangle pointing down 
Triangle pointing left 
10  Filled triangle pointing left 
11  Triangle pointing right 
12  Filled triangle pointing right 
13  Diamond 
14  Filled diamond 
15  Double triangle vertical 
16  Filled double triangle vertical 
17  Double triangle horizontal 
18  Filled double triangle horizontal 
19  Diagonal cross (X) 
20 
21  Vertical cross (+) 
22 
23  Star (diagonal and vertical cross) 
24 
25  Rectangle with diagonal cross 
26 
27  Rectangle with vertical cross 
28 
29  Circle with diagonal cross 
30 
31  Circle with vertical cross 
32 
33  Diamond with vertical cross 
If any options of XwNezdrawAutoscroll are enabled, these will be checked and executed, so moving the visible area or rescaling.

XwCreateEzdraw
Widget XwCreateEzdraw (Widget parent , char *name , ArgList arglist , Cardinal argcount);

Just a conveniance function for creating a Ezdraw Widget.

XwEzdrawClear
void XwEzdrawClear (Widget w , int flag);

Sometimes there is a need to wipe out all previous drawing. This functions clears all plotted curves, resets the history and redisplays the cleared area.
If flag is zero, the cleared area is redisplayed, else only the internal pixmap is cleared and redisplay is done with the next plotting.
 

XwEzdrawSettext
void XwEzdrawSettext (Widget w , int ID , char *text);

The given text will be displayed in the upper left corner of the visible area, using the curve's colout. If there are more annotions to this edge, they are lined up. An empty text (or a NULL pointer) will delete the curve's text display. There is a small p roblem together with this text. If the update rate of display is high, the displayed text will flicker.

XwEzdrawchangecolor
void XwEzdrawchangecolor ( Widget w , int ID , Pixeö color);

Thie function changes the colour for the particular curve. So from now, all points plotted appear in new colour, all elder points will still have the old colour until a history redraw is done. Text and marker values will change colour immediately.

XwEzdrawhistory
void XwEzdrawhistory (Widget w , long int ID , float **x , float **y , short int ** flag , int *size);

Sometimes there is a need to get all plotted information back to memory. For example to do a hardcopy. If the history option (XwNezdrawHistory) is enabled, this function will allocate (malloc) three array, copy the internal history into them and return the addresses together with the number of items. The user is responsible to free the memory after usage.
 
 

Examples:

A short code-fragment shows the usage of Ezdraw:
 
 

float scal[4] = {-15.0,30.0,-15.0,30.0};

float grid[4] = {-15.0,3.0,-15.0,3.0};
 
 
 
 

n = 0;

XtSetArg(args[n], XmNx, 486); n++;

XtSetArg(args[n], XmNy, 40); n++;

XtSetArg(args[n], XmNwidth, 252); n++;

XtSetArg(args[n], XmNheight, 352); n++;

EZ_userWidget10 = XtCreateWidget("userWidget10", XwEzdrawWidgetClass, EZ, args, n);

XtManageChild(EZ_userWidget10);

/* the following setting of scale and grid could be better done at creation, so move the XtSetArg prior to XtCreateWidget */

n = 0;

XtSetArg(args[n],XwNezdrawScale, scal); n++;

XtSetArg(args[n],XwNezdrawGridScale, grid); n++;

XtSetValues(EZ_userWidget10,args,n);
 
 

/* now add two curves The returned ID is know as 0 and 1, so no need to store */

XwEzdrawAddcurve(EZ_userWidget10, MGetPixel("red",EZ_userWidget10 ));
 
 

XwEzdrawAddcurve(EZ_userWidget10, MGetPixel("blue",EZ_userWidget10 ));
 
 

/* adding callbacks */

XtAddCallback(EZ_userWidget10, XmNresizeCallback, (XtCallbackProc) ezres_cb, (XtPointer)NULL);

XtAddCallback(EZ_userWidget10, XmNinputCallback, (XtCallbackProc) input_cb, (XtPointer)NULL);

XtAddCallback(EZ_userWidget10, XmNexposeCallback, (XtCallbackProc) ezexp_cb, (XtPointer)NULL);
 
 

}
 
 

{

float xy[2] ,xy1[2];

float radius = 10.0 , base = 0.0;

xy1[0] =radius * cos( base);

xy[0] = (radius+0.001) * sin(base);

xy[1] = (radius+0.001) * cos(base);

xy1[1] = radius*sin(base);
 
 

/* two curve points plotted, the first including a symbol, the second curve with display enforcing */

XwEzdrawcurve (EZ_userWidget10 , 0 , xy1 , 2 + XwEzdrawSymbPlot , 2);

XwEzdrawcurve (EZ_userWidget10 , 1 , xy , 1 , 0);
 
 

}

Table of contents

Description: 1

Example of a standard drawing: 1

Resources: 1

Detailed Description of special Resources: 2

Callbacks: 2

Resources, that must be set: 3

Resources, that should be set: 3

Additional controlling Resources: 3

HISTORY and PIXMAP-size: 4

Public Functions 4

XwEzdrawAddcurve 4

XwEzdrawcurve 5

XwCreateEzdraw 6

XwEzdrawClear 6

XwEzdrawSettext 6

XwEzdrawchangecolor 6

XwEzdrawhistory 6

Examples: 6