/---------------------\
| Notes for lecture08 |
| 26 October 1999     |
| CS 125-609          |
| Michael Goldwasser  |
\---------------------/

=========================================================================
  GRAPHICS (Chapter 5.1 + additional notes thanks to online help)
=========================================================================

Preface:   As usual, much of this material is covered in the text book
chapter, however some of it is not.  A lot of this information is also
available in the online help pages.

Think of this document as my own mix between the two - sort of an
annotated help page on the commands


=========================================================================

GRAPHICS AT DESIGN TIME

If you ever want some basic graphics to spice up your form, you will
notice that the toolbox contains a control called a "Shape" and
another control called a "Line".  These can be used for putting a bit
more graphics into the layout of your form.

Their use is pretty self explanatory as these controls do not have any
events associated with them.  Their properties can be used to define
the size, shape, placement and other attributes.   A shape control can
be used to represent a rectangle, square, rounded rectangle, rounded
square, circle or oval.

=========================================================================

GRAPHICS IN PICTURE BOXES

Much more interesting is the fact that we can use picture boxes at run
time for displaying graphics which we create (as opposed to loading a
pre-designed picture).

Actually, all of the rest of this material can equally be used to draw
in picture boxes,  to draw on the form itself, or to draw directly to
the printer.

=========================================================================

COORDINATE SYSTEM

  "How is an (x,y) value treated on the screen?"

  The first interesting issue is the coordinate system for using
  graphics. We have already seen a bit of this as controls are placed
  on a Form by setting their Left, Top, Width, Height properties.  All
  of these properties are referencing an underlying coordinate system
  for the Form.  In a similar spirit, a picture box has its own
  internal coordinate system which is separate from the Form's
  coordinates. 

  This coordinate system is setup by default, however we are free to
  change it at any time to better meet our graphical needs.

  DEFAULT --  the default coordinate system is set up so that the
  X-axis goes to the right as numbers increase, and so that the Y-axis
  goes down as numbers increase.   That is, the top-left corner can be
  thought of as an origin, with coordinates increasing from there.
  Note that using the top-left as an origin is quite common with
  computers.


  At the same time, you may want to change this default.  For example,
  mathematicians treat the X-axis as going to the right, but the
  Y-axis as going UPWARDS as coordinates increase.  (that is, the
  bottom-left corner is often the origin).

  Visual Basic lets you choose exactly how you want to treat the axes
  in the coordinate system (we will see how this is done in a moment).
 
-------------------------------------------------------------------------

  "What are the units?"

  If we draw a circle with radius "50" what does the 50 mean?  Again,
  there are defaults ("twips") for how the units are set up by Visual
  Basic, but we can change the scale of the coordinate system to be
  based on inches, millimeters, pixels or many other values (see
  ScaleMode property).   In fact, we can even define the X-units and
  Y-units to be whatever we want (and they can even be different from
  each other). 

-------------------------------------------------------------------------
  
   object.Scale (x1,y1)-(x2,y2)


   Resets the coordinate system so that the top-left corner of the
   picture box is considered to have coordinates (x1,y1) and so that
   the bottom-right corner has coordinates (x2,y2).

   This command does not actually change the corners of the picture
   box, rather it changes the coordinate system to line up the axes
   and their units to match our desired system.

   Example:
       object.Scale (0,0)-(100,100)        '<--- programmers view?

       object.Scale (-50,-50)-(50,50)      '<--- moving the origin

       object.Scale (0,-100)-(100,0)       '<--- mathematicians view?


=========================================================================

DEFAULT PEN LOCATION

  Question:  when I say to draw something, where does it get drawn?

  Answer:  There are really two answers.   Many of the commands we see
  will have a way to explicitly define where something gets drawn
  (based on the coordinate system).   But if you don't specify the
  coordinates, it will use a default pen location which is based 
  partly on the location of the most recent graphic which was drawn.

  For example, when using "Print" to display text in a picture box,
  we have already seen the difference between placing a line break
  and not.   This really is effecting where the default pen location
  is left after outputting the text.

  In a similar manner, if you draw a line, the default gets left at
  the endpoint of the line.  If you draw a circle, it gets left at the
  center of the circle, and so on.


   The way this is done is based on the following two properties:

   object.CurrentX
   object.CurrentY

   You may read and even modify these values at any time.

=========================================================================

DRAWING A POINT

  To draw a point, you minimally need to specify the location of the
  point. Optional is to give a color choice.


  Syntax:
   object.PSet [Step] (x,y), [color]


   Part        description
   ----        -----------
   Step        Optional. Keyword specifying that the starting point
               coordinates are relative to the current graphics
               position given by the CurrentX and CurrentY properties. 

  (x, y)       Required. Single values indicating the coordinates of
               the point being drawn. 

  color        Optional. Indicates color used to draw the line. If
               omitted, the ForeColor property setting is used.


  Note: When PSet executes, the CurrentX and CurrentY properties are
  set to the point specified by the arguments.

  The "width" of the point is determined by the DrawWidth parameter


  Examples:
    ' to draw a point at (5,5)
    object.Pset (5,5)

    ' to draw a point at (CurrentX + 5, CurrentY + 5)
    object.Pset Step(5,5)

    ' to draw a red point at (5,5)
    object.Pset (5,5), vbRed

=========================================================================

DRAWING A LINE OR RECTANGLE

  To draw a line, you minimally need to specify a starting and ending
  point.  Giving a color choice is optional.

  To draw a rectangle, you minimally need to specify two opposite
  corners. Giving a color choice for the boundary is optional.  The
  interior of the rectangle will be filled in based on the FillStyle
  and FillColor properties of the picture box (invisible by default).
  You can override this by changing the FillColor and FillStyle
  properties, or by telling it that you want it filled solid using the
  same color as the boundary.



  Syntax:
   object.Line [Step] (x1, y1) - [Step] (x2, y2), [color], [B][F]


   Part        description
   ----        -----------
   Step        Optional. Keyword specifying that the starting point
               coordinates are relative to the current graphics
               position given by the CurrentX and CurrentY properties. 

 (x1, y1)      Optional. Single values indicating the coordinates of the
               starting point for the line or rectangle. If omitted,
               the line begins at the position indicated by CurrentX
               and CurrentY.   

   Step        Optional. Keyword specifying that the end point
               coordinates are relative to the line starting point. 

 (x2, y2)      Required. Single values indicating the coordinates of
               the end point for the line being drawn. 

  color        Optional. Indicates color used to draw the line. If
               omitted, the ForeColor property setting is used.

    B          Optional. If included, causes a box to be drawn using the
               coordinates to specify opposite corners of the box. 

    F          Optional. If the B option is used, the F option
               specifies that the box is filled with the same color
               used to draw the box. You cannot use F without B. If B
               is used without F, the box is filled with the current
               FillColor and FillStyle. The default value for
               FillStyle is transparent.  


  Note: When Line executes, the CurrentX and CurrentY properties are
  set to the end point specified by the arguments.

  Examples:
   ' to draw a line from (0,5) to (5,5)
   object.Line (0,5)-(5,5)

   ' to draw a line from current location to the location (5,5)
   object.Line -(5,5)


   ' to draw a line from current location to the location (currentX+5,currentY+5)
   object.Line -Step(5,5)


   ' to draw a rectangle with opposite corners at (3,5) and (4,6)
   ' with boundary drawn in blue, and with the interior drawn
   ' according to the FillColor and FillStyle properties
   object.Line (3,5)-(4,6), vbBlue, B


   ' to draw a rectangle with opposite corners at (3,5) and (4,6)
   ' with boundary drawn in red, and with interior filled in solid
   ' red.
   object.Line (3,5)-(4,6), vbRed, BF


=========================================================================

DRAWING A CIRCLE, ELLIPSE, OR ARC

  Syntax:
   object.Circle [Step] (x, y), radius, [color, start, end, aspect]


   Part        description
   ----        -----------
   Step        Optional.Keyword specifying that the center of the
               circle, ellipse, or arc is relative to the current
               coordinates given by the CurrentX and CurrentY
               properties of object.  

  (x, y)       Required. Single values indicating the coordinates for
               the center point of the circle, ellipse, or arc.
 
  radius       Required. Single value indicating the radius of the
               circle, ellipse, or arc.

  color        Optional. Indicating the color of the circle's
               outline. If omitted, the value of the ForeColor
               property is used.

start, end     Optional. Single-precision values. When an arc or a
               partial circle or ellipse is drawn, start and end
               specify (in radians) the beginning and end positions of
               the arc. The range for both is - 2pi radians to 2pi
               radians. The default value for start is 0 radians; the 
               default for end is 2 * pi radians. 

  aspect       Optional. Single-precision value indicating the aspect
               ratio of the circle. The default value is 1.0, which
               yields a perfect circle on any screen. 


  Note: When Circle executes, the CurrentX and CurrentY properties are
  set to the center of the circle.

  In the case that the scale has been changed such that the x-units
  and y-units are not equal, the circle radius is based on x-units.

  To fill a circle, set the FillColor and FillStyle properties of the
  object on which the circle or ellipse is drawn. Only a closed figure
  can be filled. Closed figures include circles, ellipses, or pie
  slices (arcs with radius lines drawn at both ends).

  When drawing a partial circle or ellipse, if start is negative,
  Circle draws a radius to start, and treats the angle as positive; if
  end is negative, Circle draws a radius to end and treats the angle
  as positive. The Circle method always draws in a counter-clockwise
  (positive) direction.

  When drawing pie slices, to draw a radius to angle 0 (giving a
  horizontal line segment to the right), specify a very small negative
  value for start, rather than zero.


  Examples:

  ' draws a circle of radius 5 around the current pen location
  object.Circle Step(0,0), 5

  ' draws a red circle of radius 10 around the point (50,50)
  object.Circle (50,50), 10, vbRed

  ' draws a flat, wide ellipse around the point (50,50)
  object.Circle (50,50), 40, , , , 0.2

  ' draws a quarter of a circle "pie-slice"
  twopi = 8*atn(1)
  object.FillColor = vbBlue
  object.Circle (50,50), 20, , -twopi*3/8, -twopi*5/8


  ' draws three quarters of a circle (e.g. PacMan)
  twopi = 8*atn(1)
  object.FillColor = vbYellow
  object.FillStyle = 0
  object.Circle (50,50), 20, , -twopi*5/8, -twopi*3/8


=========================================================================
COLORS

  There are three ways to describe a color for the above graphic
  methods.

  - Use predefined colors as in the textbook:
     vbBlack, vbRed, vbGreen, vbYellow, vbBlue, vbMagenta, vbCyan, vbWhite

  - QBColor(x)
    where x is in the range 0-15 inclusive.  These are a set of 16
    predefined colors based on earlier versions of the Basic language
    (see help page to get list of the colors)

  - RGB(r,g,b)
    where each of 'r', 'g', and 'b' are integers in the range 0-255,
    with 0 being the lack of the color, and 255 being the most.  (for
    example, RGB(100,0,100) is a dark magenta)

=========================================================================

WORKING WITH TEXT

  We have already seen the use of text in picture boxes (see lecture04).
  But when combining text with graphics, it is important to be able to
  tell the relative size of a piece of text in the coordinate system,
  taking into account the font size and style being used.

    object.TextHeight(string)

  returns the height which would be used if the string were printed
  with the Print method based on the current font settings. If the
  string contains embedded carriage-return characters, then the text
  height takes this into account. 

  Similarly, the method

    object.TextWidth(string)

  returns the width which will be used if the string is printed with
  the Print method based on the current font settings.

=========================================================================

Other issues:

  Although we will not officially cover these properties, you may want to
  be aware of them for your own knowledge, as they are relevant to the
  appearance of graphics which you draw.

  AutoRedraw   <-- best to set this to True when dealing with graphics!
  BorderStyle
  DrawMode
  DrawStyle
  DrawWidth
  FillColor
  FillStyle

=========================================================================