/* * File: gobjects.h * ---------------- * This interface exports a hierarchy of graphical shapes based on the * model developed for the ACM Java Graphics. */ #ifndef _gobjects_h #define _gobjects_h #include "cslib.h" #include "generic.h" #include "gtypes.h" #include "vector.h" #ifndef _gwindow_h typedef struct GWindowCDT *GWindow;/* * Type: GObject * ------------- * This type represents an abstract type that unifies the set of all * graphics objects. As with an abstract class in an object-oriented * language, it is not legal to create a GObject directly. Graphical * objects are created instead by calling the constructor for one of the * concrete subclasses, as follows: * * * * >newGRect(x, y, width, height) * * >newG3DRect(x, y, width, height, raised) * * >newGRoundRect(x, y, width, height, corner) * * >newGOval(x, y, width, height) * * >newGLine(x0, y0, x1, y1) * * >newGArc(x, y, width, height, start, sweep) * * >newGImage(filename, x, y) * * >newGLabel(str, x, y) * * >newGPolygon * * >newCompound * * * Even though C has no object-oriented hierarchies, this interface defines * the types GArc, GCompound, GImage, GLabel, GLine, GOval, GPolygon, * GRect, GRoundRect, and G3DRect as synonyms for GObject. Doing so helps * to clarify what types are expected by each function and simplifies the * process of converting code from languages that implement full * hierarchies. */ typedef struct GObjectCDT *GObject; #endif/* * Function: freeGObject * Usage: freeGObject(gobj); * ------------------------- * Frees the memory associated with the object. This operation is not * necessary for objects that have been installed in a window. Adding a * GObject to a GWindow or a GCompound transfers ownership to the * container, which assumes responsibility for freeing the object. */ void freeGObject(GObject gobj);/* * Function: getX * Usage: x = getX(gobj); * ---------------------- * Returns the x-coordinate of the object. */ double getXGObject(GObject gobj);/* * Function: getY * Usage: y = getY(gobj); * ---------------------- * Returns the y-coordinate of the object. */ double getYGObject(GObject gobj);/* * Function: getLocation * Usage: pt = getLocation(gobj); * ------------------------------ * Returns the location of this object as a GPoint. */ GPoint getLocation(GObject gobj);/* * Function: setLocation * Usage: setLocation(gobj, x, y); * ------------------------------- * Sets the location of this object to the specified coordinates. */ void setLocation(GObject gobj, double x, double y);/* * Function: move * Usage: move(gobj, dx, dy); * -------------------------- * Moves the object on the screen using the displacements dx and dy. */ void move(GObject gobj, double dx, double dy);/* * Function: getWidth * Usage: width = getWidth(gobj); * ------------------------------ * Returns the width of this object, which is defined to be the width of * the bounding box. */ double getWidthGObject(GObject gobj);/* * Function: getHeight * Usage: height = getHeight(gobj); * -------------------------------- * Returns the height of this object, which is defined to be the height of * the bounding box. */ double getHeightGObject(GObject gobj);/* * Function: getSize * Usage: size = getSize(gobj); * ---------------------------- * Returns the size of the object as a GDimension. */ GDimension getSize(GObject gobj);/* * Function: getBounds * Usage: rect = getBounds(gobj); * ------------------------------ * Returns the bounding box of this object, which is defined to be the * smallest rectangle that covers everything drawn by the figure. The * coordinates of this rectangle do not necessarily match the location * returned by getLocation. Given a GLabel object, for example, * getLocation returns the coordinates of the point on the baseline at * which the string begins; the getBounds method, by contrast, returns a * rectangle that covers the entire window area occupied by the string. */ GRectangle getBounds(GObject gobj);/* * Function: setColor * Usage: setColor(gobj, color); * ----------------------------- * Sets the color used to display this object. The color string is usually * one of the predefined color names: * * BLACK * BLUE * CYAN * DARK_GRAY * GRAY * GREEN * LIGHT_GRAY * MAGENTA * ORANGE * PINK * RED * WHITE * YELLOW * * The case of the individual letters in the color name is ignored, as are * spaces and underscores, so that the color DARK_GRAY can be written as * "Dark Gray". */ void setColorGObject(GObject gobj, string color);/* * Function: getColorGObject * Usage: color = getColorGObject(gobj); * ------------------------------ * Returns the color used to display this object. This color is always * returned as a string in the form "#rrggbb", where rr, gg, and bb are the * red, green, and blue components of the color, expressed as two-digit * hexadecimal values. */ string getColorGObject(GObject gobj);/* * Function: setVisible * Usage: setVisible(gobj, flag); * ------------------------------ * Sets whether this object is visible. */ void setVisibleGObject(GObject gobj, bool flag);/* * Function: isVisible * Usage: if (isVisible(gobj)) . . . * --------------------------------- * Returns true if this object is visible. */ bool isVisibleGObject(GObject gobj);/* * Function: sendForward * Usage: sendForward(gobj); * ------------------------- * Moves this object one step toward the front in the z dimension. If it * was already at the front of the stack, nothing happens. */ void sendForward(GObject gobj);/* * Function: sendToFront * Usage: sendToFront(gobj); * ------------------------- * Moves this object to the front of the display in the z dimension. By * moving it to the front, this object will appear to be on top of the * other graphical objects on the display and may hide any objects that are * further back. */ void sendToFront(GObject gobj);/* * Function: sendBackward * Usage: sendBackward(gobj); * -------------------------- * Moves this object one step toward the back in the z dimension. If it * was already at the back of the stack, nothing happens. */ void sendBackward(GObject gobj);/* * Function: sendToBack * Usage: sendToBack(gobj); * ------------------------ * Moves this object to the back of the display in the z dimension. By * moving it to the back, this object will appear to be behind the other * graphical objects on the display and may be obscured by other objects in * front. */ void sendToBack(GObject gobj);/* * Function: contains * Usage: if (contains(gobj, x, y)) . . . * -------------------------------------- * Returns true if the specified point is inside the object. */ bool containsGObject(GObject gobj, double x, double y);/* * Function: getType * Usage: type = getType(gobj); * ---------------------------- * Returns the subtype of the object as a string, as in "GOval" or "GRect". */ string getType(GObject gobj);/* * Function: getParent * Usage: parent = getParent(gobj); * -------------------------------- * Returns a pointer to the GCompound that contains this object. Every * GWindow is initialized to contain a single GCompound that is aligned * with the window. Adding objects to the window adds them to that * GCompound, which means that every object you add to the window has a * parent. Calling getParent on the top-level GCompound returns NULL. */ GObject getParent(GObject gobj);/* Functions that apply to several types */ /* * Function: setSize * Usage: setSize(gobj, width, height); * ------------------------------------ * Changes the size of this object to the specified width and height. This * method applies to the types GOval, GImage, and GRect (and its * subclasses). */ void setSize(GObject gobj, double width, double height);/* * Function: setBounds * Usage: setBounds(gobj, x, y, width, height); * -------------------------------------------- * Changes the bounds of this object to the specified values. This method * applies to the types GOval, GImage, and GRect (and its subclasses). */ void setBounds(GObject gobj, double x, double y, double width, double height);/* * Function: setFilled * Usage: setFilled(gobj, flag); * ----------------------------- * Sets the fill status for gobj, where false is outlined and true is * filled. */ void setFilled(GObject gobj, bool flag);/* * Function: isFilled * Usage: if (isFilled(gobj)) . . . * -------------------------------- * Returns true if gobj is filled. */ bool isFilled(GObject gobj);/* * Function: setFillColor * Usage: setFillColor(gobj, color); * --------------------------------- * Sets the color used to display the filled region of this rectangle. */ void setFillColor(GObject gobj, string color);/* * Function: getFillColor * Usage: color = getFillColor(gobj); * ---------------------------------- * Returns the color used to display the filled region of gobj. rectangle. * If none has been set, getFillColor returns the empty string. */ string getFillColor(GObject gobj);/* * Type: GRect * ----------- * This type represents a graphical object whose appearance consists of a * rectangular box. For example, the following code adds a filled, red, * 200x100 rectangle at the upper left corner of the graphics window: * * main() { * GWindow gw = newGWindow(500, 300); * printf("This program draws a red rectangle at (0, 0).\n") * GRect rect = newGRect(0, 0, 200, 100); * setFilled(rect, true); * setColor(rect, "RED"); * add(gw, rect); * } */ typedef GObject GRect;/* * Function: newGRect * Usage: rect = newGRect(x, y, width, height); * -------------------------------------------- * Creates a new GRect with the specified bounds. By default, the * rectangle is unfilled. */ GRect newGRect(double x, double y, double width, double height);/* * Type: GRoundRect * ---------------- * This type represents a rectangular box with rounded corners. */ typedef GRect GRoundRect;/* * Function: newGRoundRect * Usage: GRoundRect rect = newGRoundRect(x, y, width, height, corner); * -------------------------------------------------------------------- * Creates a new GRoundRect with the specified dimensions. The corner * parameter specifies the diameter of the arc forming the corner. */ GRoundRect newGRoundRect(double x, double y, double width, double height, double corner);/* * Type: G3DRect * ------------- * This type represents a rectangular box that can appear raised or * lowered. */ typedef GRect G3DRect;/* * Function: newG3DRect * Usage: G3DRect rect = newG3DRect(x, y, width, height, raised); * -------------------------------------------------------------- * Creates a new G3DRect with the specified dimensions. The corner * parameter specifies whether this rectangle should appear raised. */ G3DRect newG3DRect(double x, double y, double width, double height, bool raised);/* * Function: setRaised * Usage: setRaised(rect, raised); * ------------------------------- * Indicates whether this object appears raised. */ void setRaised(G3DRect rect, bool raised);/* * Function: isRaised * Usage: if (isRaised(rect)) ... * ------------------------------ * Returns true if this object appears raised. */ bool isRaised(G3DRect rect);/* * Type: GOval * ----------- * This type represents an oval inscribed in a rectangular box. For * example, the following code displays a filled green oval inscribed in * the graphics window: * * main() { * GWindow gw = newGWindow(500, 300); * printf("This program draws a green oval filling the window.\n"); * GOval oval = newGOval(getWidth(gw), getHeight(gw)); * setFilled(oval, true); * setColor(oval, "GREEN"); * add(gw, oval); * } */ typedef GObject GOval;/* * Function: newGOval * Usage: oval = newGOval(x, y, width, height); * -------------------------------------------- * Creates a new GOval with the specified bounds. By default, the oval is * unfilled. */ GObject newGOval(double x, double y, double width, double height);/* * Type: GLine * ----------- * This type represents a line segment. For example, the following code * adds lines that mark the diagonals of the graphics window: * * main() { * GWindow gw = newGWindow(500, 300); * printf("This program draws the diagonals on the window.\n"); * add(gw, newGLine(0, 0, getWidth(gw), getHeight(gw))); * add(gw, newGLine(0, getHeight(gw), getWidth(gw), 0)); * } */ typedef GObject GLine;/* * Function: newGLine * Usage: line = newGLine(x0, y0, x1, y1); * --------------------------------------- * Creates a new graphical line connecting the points (x0, y0) and * (x1, y1). */ GObject newGLine(double x0, double y0, double x1, double y1);/* * Function: setStartPoint * Usage: setStartPoint(gline, x, y); * ---------------------------------- * Sets the start point for the line to (x, y), leaving the end point * unchanged. This method is therefore different from setLocation, which * moves both components of the line segment. */ void setStartPoint(GLine line, double x, double y);/* * Function: setEndPoint * Usage: setEndPoint(line, x, y); * ------------------------------- * Sets the end point for the line to (x, y), leaving the start point * unchanged. */ void setEndPoint(GLine line, double x, double y);/* * Function: getStartPoint * Usage: pt = getStartPoint(gobj); * -------------------------------- * Returns the point at which a GLine or GArc starts. */ GPoint getStartPoint(GObject gobj);/* * Function: getEndPoint * Usage: pt = getEndPoint(gobj); * ------------------------------ * Returns the point at which a GLine or GArc ends. */ GPoint getEndPoint(GObject gobj);/* * Type: GArc * ---------- * This type represents an elliptical arc. The arc is specified by the * following parameters: * * * The coordinates of the bounding rectangle (x, * y, width, height) * The angle at which the arc starts (start) * The number of degrees that the arc covers (sweep) * * All angles in a GArc description are measured in degrees moving * counterclockwise from the +x axis. Negative values for either start or * sweep indicate motion in a clockwise direction. */ typedef GObject GArc;/* * Function: newGArc * Usage: arc = newGArc(x, y, width, height, start, sweep); * -------------------------------------------------------- * Creates a new GArc consisting of an elliptical arc. */ GArc newGArc(double x, double y, double width, double height, double start, double sweep);/* * Function: setStartAngle * Usage: setStartAngle(arc, start); * --------------------------------- * Sets the starting angle for this GArc object. */ void setStartAngle(GArc arc, double start);/* * Function: getStartAngle * Usage: angle = getStartAngle(arc); * ---------------------------------- * Returns the starting angle for this GArc object. */ double getStartAngle(GArc arc);/* * Function: setSweepAngle * Usage: setSweepAngle(arc, start); * --------------------------------- * Sets the sweep angle for this GArc object. */ void setSweepAngle(GArc arc, double start);/* * Function: getSweepAngle * Usage: angle = getSweepAngle(arc); * ---------------------------------- * Returns the sweep angle for this GArc object. */ double getSweepAngle(GArc arc);/* * Function: setFrameRectangle * Usage: setFrameRectangle(arc, x, y, width, height); * --------------------------------------------------- * Changes the boundaries of the rectangle used to frame the arc. */ void setFrameRectangle(GArc garc, double x, double y, double width, double height);/* * Function: getFrameRectangle * Usage: rect = getFrameRectangle(arc); * ------------------------------------- * Returns the boundaries of the rectangle used to frame the arc. */ GRectangle getFrameRectangle(GArc arc);/* * Type: GLabel * ------------ * This subtype represents a text string. For example, the following code * adds a GLabel containing "hello, world" to the center of the window: * * main() { * GWindow gw; * GLabel label; * double x, y; * * printf("This program draws the 'hello, world' message.\n"); * gw = newGWindow(600, 400); * label = newGLabel("hello, world"); * setFont(label, "SansSerif-18"); * x = (getWidth(gw) - getWidth(label)) / 2; * y = (getHeight(gw) + getFontAscent(label)) / 2; * setLocation(label, x, y); * add(gw, label); * } * * Controlling the appearance and positioning of a GLabel depends on * understanding the following terms: * * * The baseline is the horizontal line on which the * characters rest. * The origin is the point on the baseline at which * the label begins. * The height is the distance that separate two * successive lines. * The ascent is the maximum distance a character * in this font extends above the baseline. * The descent is the maximum distance a character * in this font extends below the baseline. */ typedef GObject GLabel;/* * Function: newGLabel * Usage: label = newGLabel(str); * ------------------------------ * Creates a GLabel object containing the specified string, positioned with * an origin of (0, 0). */ GLabel newGLabel(string str);/* * Function: setFont * Usage: setFont(label, font); * ---------------------------- * Changes the font used to display the GLabel as specified by the string * font, which has the following format: * * family-style-size * * where both style and size are optional. If any of these elements are * missing or specified as an asterisk, the existing value is retained. */ void setFont(GLabel label, string font);/* * Function: getFont * Usage: font = getFont(label); * ----------------------------- * Returns the current font for the GLabel. */ string getFont(GLabel label);/* * Function: setLabel * Usage: setLabel(label, str); * ---------------------------- * Changes the string stored within the GLabel object, so that a new text * string appears on the display. */ void setLabel(GLabel label, string str);/* * Function: getLabel * Usage: str = getLabel(label); * ----------------------------- * Returns the string displayed by this object. */ string getLabel(GLabel label);/* * Function: getFontAscent * Usage: ascent = getFontAscent(label); * ------------------------------------- * Returns the maximum distance strings in this font extend above the * baseline. */ double getFontAscent(GLabel label);/* * Function: getFontDescent * Usage: descent = getFontDescent(label); * --------------------------------------- * Returns the maximum distance strings in this font descend below the * baseline. */ double getFontDescent(GLabel label);/* * Type: GImage * ------------ * This subtype represents an image from a file. For example, the * following code adds a GImage containing the Stanford tree at the center * of the window, assuming that the image file StanfordTree.png exists, * either in the current directory or an images subdirectory: * * main() { * printf("This program draws the Stanford tree.\n"); * GWindow gw = newGWindow(600, 400); * GImage tree = newGImage("StanfordTree.png"); * double x = (getWidth(gw) - getWidth(tree)) / 2; * double y = (getHeight(gw) - getHeight(tree)) / 2; * add(gw, tree, x, y); * } */ typedef GObject GImage;/* * Function: newGImage * Usage: GImage image = newGImage(filename); * ------------------------------------------ * Constructs a new image by loading the image from the specified file, * which is either in the current directory or a subdirectory named images. * The upper left corner of the image is positioned at the origin. */ GImage newGImage(string filename);/* * Type: GPolygon * -------------- * This subtype represents a polygon bounded by line segments. The * newGPolygon function creates an empty polygon. To complete the figure, * you need to add vertices to the polygon using the functions addVertex, * addEdge, and addPolarEdge. As an example, the following code adds a * filled red octagon to the center of the window: * * main() { * GWindow gw; * GPolygon stopSign; * double edge; * int i; * * printf("This program draws a red octagon.\n"); * gw = newGWindow(600, 400); * edge = 75; * stopSign = newGPolygon(); * addVertex(stopSign, -edge / 2, edge / 2 + edge / sqrt(2.0)); * for (i = 0; i < 8; i++) { * addPolarEdge(stopSign, edge, 45 * i); * } * setFilled(stopSign, true); * setColor(stopSign, "RED"); * add(gw, stopSign, getWidth(gw) / 2, getHeight(gw) / 2); * } */ typedef GObject GPolygon;/* * Function: newGPolygon * Usage: poly = newGPolygon(); * ---------------------------- * Constructs a new empty polygon. */ GPolygon newGPolygon(void);/* * Function: addVertex * Usage: addVertex(poly, x, y); * ----------------------------- * Adds a vertex at (x, y) relative to the polygon origin. */ void addVertex(GPolygon poly, double x, double y);/* * Function: addEdge * Usage: addEdge(poly, dx, dy); * ----------------------------- * Adds an edge to the polygon whose components are given by the * displacements dx and dy from the last vertex. */ void addEdge(GPolygon poly, double dx, double dy);/* * Function: addPolarEdge * Usage: addPolarEdge(poly, r, theta); * ------------------------------------ * Adds an edge to the polygon specified in polar coordinates. The length * of the edge is given by r, and the edge extends in direction theta, * measured in degrees counterclockwise from the +x axis. */ void addPolarEdge(GPolygon poly, double r, double theta);/* * Function: getVertices * Usage: vec = getVertices(poly); * ------------------------------- * Returns a vector whose elements are pointers to the GPoint values that * represent the vertices. This vector is shared with the internal data * structure of the GPolygon and must not be freed by the client. */ Vector getVertices(GPolygon poly);/* * Type: GCompound * --------------- * This subtype consists of a collection of other graphical objects. Once * assembled, the internal objects can be manipulated as a unit. The * GCompound keeps track of its own position, and all items within it are * drawn relative to that location. */ typedef GObject GCompound;/* * Function: newGCompound * Usage: comp = newGCompound(); * ----------------------------- * Creates a new graphical compound with no internal components. */ GObject newGCompound(void);/* * Function: add * Usage: add(compound, gobj); * --------------------------- * Adds the object to the compound. */ void addGCompound(GCompound compound, GObject gobj);/* * Function: add * Usage: add(compound, gobj); * --------------------------- * Removes the object from the compound. */ void removeGCompound(GCompound compound, GObject gobj);/* * Friend function: getGObjectCompound * Usage: gobj = getGObjectCompound(GCompound compound, double x, double y); * ------------------------------------------------------------------------- * Returns the topmost object covering x and y, or NULL if no such object * exists. */ GObject getGObjectCompound(GCompound compound, double x, double y);/* * Friend type: ObjectTypeBits * --------------------------- * This enumeration identifies a GObject type in a way that simplifies * checking whether a particular function is legal on that object. */ typedef enum { GARC = 1<<0, GCOMPOUND = 1<<1, GIMAGE = 1<<2, GLABEL = 1<<3, GLINE = 1<<4, GOVAL = 1<<5, GPOLYGON = 1<<6, GRECT = 1<<7, G3DRECT = 1<<8, GROUNDRECT = 1<<9, GINTERACTOR = 0x1F<<10, GBUTTON = 1<<10, GCHECKBOX = 1<<11, GCHOOSER = 1<<12, GSLIDER = 1<<13, GTEXTFIELD = 1<<14 } GObjectTypeBits; #endif