gdWithinViewportP
(view dx dy
Return t
if the pixel (in coordinates of view) is
inside the viewport of view, otherwise nil
. -->
In many applications, viewports can be changed interactively by users, e.g., when they resize or move a window using the mouse. When this is done, user code may need to be run to adjust coordinate systems or to redraw objects. To assist with this sort of programming, G provides hooks into the viewport setting system. The following routines are called whenever the viewport is changed, either interactively by mousing or by user code.
gAcceptNewViewportSize
(view) gSetCSscale
. For
example, the effect just described can be accomplished as follows:
class FixedScaleWindow (Gwindow):
def gAcceptNewViewportSize(self):
gSetCSscale(window,0,0,'inches,'inches,'upperLeft)
Gwindow.gAcceptNewViewportSize(self)
Now window classes with FixedScaleWindow
mixed in
will behave as desired.
Consider another example of the use of
gAcceptNewViewportSize
. Suppose you want the sizes and
positions of child views within a window to be relative to the viewport
of
the window. The natural way to do this is to set up a normalized
coordinate
system for the window and place the child views within the window using
that coordinate system. However, ordinarily all this would get messed
up
if the window's viewport were changed, because the viewports of the
child
views would not be readjusted The following code defines a mixin that
causes the child views to all be automatically changed as well:
class maintaingViewportsOfChildren (Gview):
def gAcceptNewViewportSize(self):
children = gGetChildren(view)
gViewports = []
for child in children:
gViewports.append(gGetViewport(child))
Gview.gAcceptNewViewportSize(self)
for child, gViewport in zip(children, gViewports):
x1, y1, x2, y2 = gViewport
gSetViewport(child, x1, y1, x2, y2)
Views of this class, or with this class mixed in, will, whenever their viewports are changed, automatically change the viewports of their child views to maintain their positions and sizes in the normalized coordinates of this view. Thus, whenever a view is changed in size, all the child views will be changed proportionately.
gAcceptNewViewportPosition
(view)
G provides several routines for specifying colors, all
beginning with "gColor
". Each returns a
colorCode to be used in drawing routines. ColorCodes(as set by gColorPen)
may be specific to the window, and thus a view must be
specified whenever constructing a colorCode. Normally,
colorCodes are constructed infrequently and then used over
and over, but it is also possible to construct a new
colorCode each time anything is drawn.
If the device does not support the requested color -- for example, if you ask for a blue color when using a grayscale screen -- then you will get some approximation to the requested color.
In G, one can also set the characteristics of the "pen" as part of the colorCode. The pen specifies various characteristics of tk drawing, which underlies G. These characteristics can be set by the G routine gColorPen, but these effects are entirely device specific.
ColorCodes should not be altered by the user in anyway. The implementation may rely on this.
gColorBlack
(view)gColorWhite
(view)gColorPink
view)gColorRed
(view)gColorOrange
(view)gColorYellow
(view)gColorGreen
(view)gColorDarkGreen
(view)gColorLightBlue
(view)gColorBlue
(view)gColorPurple
(view)gColorBrown
(view)gColorTan
(view)gColorLightGray
(view)gColorGray
(view)gColorDarkGray
(view)gColorMagenta
(view)gColorCyan
(view)gColorFlip
(view)gColorInvisible
(view)gColorOn
(view)gColorOff
(view)gColorPen
.)
The
names off
and on
have special meaning in conjunction with the gClear
drawing command. gClear
sets the entire display to the off
color, which may be
different for different
devices. In general, on
is the normal drawing
color for a device, and off
is its opposite, or
erasing color.
Currently on
is the same as 'black
and off
is the same as 'white
.
For quick and dirty color use, we also provide the following symbols, internal to the G package:
gBlack
gWhite
gPink
gRed
gOrange
gYellow
gGreen
gDarkGreen
gLightBlue
gBlue
gPurple
gBrown
gTan
gLightGray
gGray
gDarkGray
gMagenta
gCyan
gFlip
gInvisible
gOn
gOff
gColorUserPick
(view[, *args])
gColorRGB
(view, red, green, blue) gColorRGB255
(view, red, green, blue) gColorBW
(view, intensity) off
color
at intensity=0 to the on
color at intensity=1.0.
See above for definitions of on
and off
colors. gColorPen
(view, colorCode, pattern, mode,
xSize[, ySize]) gColorUserPick, gColorRGB, gColorRGB255
,
or it may be a
colorCode object returned by gColorPen
.
The pattern is an 8 by 8 bit pattern that acts like the ink of the pen. Currently G is not using the pattern, so all items are drawn as "solid" objects, and there are no dithering effects.
The mode determines the interaction between the pixels being drawn (from pattern) and the pixels already on the display. For example, the drawn pixels could replace them, OR with them, XOR with them, etc. Currently the mode is not being used either, so all pixels replace, or paint over the existing ones.
The last two arguments to gColorPen
make the
pen xSize pixels wide and ySize pixels
tall. This causes lines and other graphical objects drawn with
the new color to appear with the new thickness. When the pen
size is greater than one, the extra pixels are drawn below and
to the right of the usual pixels. Only the xSize is being
used.
gSetColor
(view, colorcode) gFont
(view, fontname, fontsize, fontface)
"Geneva"
), fontsize
should be an integer size (e.g. 11
), and fontface
should be a string describing the face desired (e.g. "normal",
"bold", "italic", "bold italic"
).
The drawing routines are those G routines that perform a display (or output-buffering) function.
Most drawing routines come in two forms, one prefaced by
"g
", and the other by "gd
". These two forms
differ only in the method used to specify spatial coordinates on the
display surface. The g
routines use normalized
realValued coordinates. Many users will probably use exclusively
g
routines, but for those who wish to have greater
control at the pixel level, the gd
routines operate in
device-dependent integer coordinates corresponding to pixels of the
display. Most calls to g
routines get quickly
translated into calls to gd
routines within G. The use
of these two kinds of routines can be freely intermixed.
A suffix convention is used for routines that specify two endpoints,
such as
gDrawLine
. One version of the routine specifies both
endpoints
in absolute coordinates, while another specifies the second endpoint
relatively, by an offset from the first. The relative version of the
routine has
a suffix of "R
". For example, the version of
gDrawLine
that specifies the second endpoint relative to
the
first is named "gDrawLineR
".
Here are some examples of drawing in device coordinates:
The arguments of all the drawing routines are patterned as follows.
The first argument is the view within which drawing takes place. The
following arguments typically specify the x and
y coordinates of the drawing operation. For g
routines these are in normalized coordinates. For gd
routines, these are in pixel coordinates, and in tk they must be
integers. The final argument is an optional colorCode. (Color codes
are constructed by the color
specification routines.) If a color is not provided (or nil), then
the color used is the same as the last color used with the window
associated with the view. To establish a current color for drawing
without calling an actual drawing routine, use gSetColor
.
Not all of tk's abilities are currently available via G routines. Additional routines should be added, patterned after these, as the need for their additional abilities arise.
gClear
(view[, color])
off
color if color is not provided. Under normal
circumstances, a
display is initialized to the off
color, but G itself
performs no initialization of display. gDelete
(view, object) gMakeVisible
(view) gDrawPoint
(view, x, y[, color])
gDrawLine
(view, x1, y1, x2, y2[,
color])gdDrawLine
(view, x1, y1, x2, y2[,
color]) gDrawLineR
(view, x, y, deltax, deltay[,
color])gdDrawLineR
(view, x, y, deltax, deltay[,
color]) gOutlineRect
(view, x1, y1, x2, y2[,
color])gdOutlineRect
(view, x1, y1, x2, y2[,
color])
gOutlineRectR
(view, x, y, deltax, deltay[,
color])gdOutlineRectR
(view, x, y, deltax, deltay[,
color]) Only vertically or horizontally oriented rectangles can be drawn -- arbitrary angles are not possible. A box of dimension zero appears as a single pixel.
gFillRect
(view, x1, y1, x2, y2[,
color])gdFillRect
(view, x1, y1, x2, y2[,
color]) gFillRectR
(view, x, y, deltax, deltay[,
color])gdFillRectR
(view, x, y, deltax, deltay[,
color]) Only vertically or horizontally oriented rectangles can be drawn -- arbitrary angles are not possible. A rectangle of dimension zero appears as a single pixel.
gFillPolygon
(view, color, x1, y1, x2, y2,
x3, y3, ...gdFillPolygon
(view, color, x1, y1, x2, y2,
x3, y3, ... gDrawCircle
(view, x, y, radius[,
color])gdDrawCircle
(view, x, y, radius[,
color]) gDrawCircle
is interpretted as a
distance along the
"y" or vertical dimension and the circle size is scaled accordingly.
Returns a pointer to the circle.
As currently implemented, this routine will draw circles that
are
as wide as they are tall as measured in numbers of pixels.
Thus, if the aspect ratio of the display is not 1:1, circles will
come out as elipses. The shape of the circle is never affected by the
coordinate systems associated with view. Note that this
can cause different parts of a display to change their positions
relative to each other (when using g
routines) as a
view is mapped to different viewports.
gDrawDisk
(view, x, y, radius[,
color])gdDrawDisk
(view, x, y, radius[,
color]) gDrawArc
(view, x, y, radius, startAngle,
angle[, color])gdDrawArc
(view, x, y, radius, startAngle,
angle[, color]) gDrawArc(view,x,y,radius,180,90,color)
draws the outline of a quarter circle in the lower left quadrant.
Otherwise, these routines behave similarly to the circleDrawing
routines
described above. They also return a pointer to the new object.gDrawWedge
(view, x, y, radius, startAngle,
angle[, color])gdDrawWedge
(view, x, y, radius, startAngle,
angle[, color]) gDrawWedge(view,x,y,radius,180,90,color)
draws a filled in quarter circle in the lower left quadrant.
Otherwise, these routines behave similarly to the circleDrawing
routines
described above. They also return a pointer to the new object. gDrawText
(view, string, font, x, y[,
color])gdDrawText
(view, string, font, x, y[,
color]) ("Monaco",12,'italic')
in tk. You can use gFont
to build this object.
In tk, permitted font names
include all the fonts installed in your system. The font size is in
points
from 1 to 127. The font styles should be one or more of the following: 'normal',
'italic', 'bold'
. If several of these are
provided, they must be in one string (e.g. 'bold italic'
).
A 'normal'
font style implies the absence of other font
styles.
gDrawTextCentered
(view, string, font, x, y[,
color])gdDrawTextCentered
(view, string, font, x, y[,
color]) gTextHeight
(view, string, font)gdTextHeight
(view, string, font) gTextWidth
(view, string, font)gdTextWidth
(view, string, font)
These are routines for responding to events.
gGetCursorPosition
(view)gdGetCursorPosition
(view) gClickEventHandler
(view, x, y)gdClickEventHandler
(view dx dy) gClickEventHandler
or gdClickEventHandler
specialized for the new class.
That method will
be called with the coordinates of the mouse click whenever there is a
mouse click within the viewport of a view of that new class. For
example, here is how to cause the current mouse coordinates to be
printed
to the shell window each time the mouse button is clicked within the
view:
class myView (Gview):
def gClickEventHandler (self, x, y):
print x, y
gMouseUpEventHandler
(view, x, y)gdMouseUpEventHandler
(view dx dy) gMouseUpEventHandler
or gdMouseUpEventHandler
specialized for the new class.
That method will
be called with the coordinates where the mouse was released whenever
the mouse button is released in the viewport of a view of that new
class. Use this in conjunction with the click event handlers to allow
the user to drag objects in the view. For example, here is how to cause
an object to be dragged within the view:
class myView (Gview):
def gClickEventHandler (self, x, y):
self.lastx, self.lasty = x, y
# find object specified at x, y
...
self.curEvent = 'move'
def gMouseUpEventHandler (self, x, y):
if self.curEvent == 'move':
if x != selflastx or y != lasty:
# move object from lastx, lasty to x, y
...
self.curEvent = None
gMotionEventHandler
(view, x, y)gdMotionEventHandler
(view dx dy) gMotionEventHandler
or gdMotionEventHandler
.
That method will
be called with the coordinates along the path of the mouse dragging.
Use this in conjunction with the click and mouse up event handlers to
allow
the user to visibly drag objects in the view. For example:
class myView (Gview):
def gClickEventHandler (self, x, y):
self.lastx, self.lasty = x, y
# find object specified at x, y
...
self.curEvent = 'move'
def gMouseUpEventHandler (self, x, y):
if self.curEvent == 'move':
if x != selflastx or y != lasty:
# move object from lastx, lasty to x, y
...
self.curEvent = None
def gMotionEventHandler (self, x, y):
if self.curEvent == 'move':
if x != selflastx or y != lasty:
# move object from lastx, lasty to x, y
...
gKeyEventHandler
(view, key)gKeyEventHandler
.
That method will
be called with the key name when a key is pressed while that view is
active.
Key names are: "Left", "Right", "Up", "Down", "Space",
"BackSpace", "Delete", "Escape", "Tab", "Shift_L", "Shift_R",
"Control_L", "Control_R", "Alt_L", Alt_R", "Return", "A", "a", "1"
,
"F2"
, etc. For more details, check the tkinter manual,
or just make your event handler print the key it got and press keys to
see their names. For example, here is how to respond to a space key
pressed while in the
view:class myView (Gview):
def gKeyEventHandler (self, key):
if key == "Space":
...
gDrawView
(view) off
color. For
example, suppose you want a black circle on a white background to
always appear in your view. This is what you should do:
class myView (Gview):
def gDrawView(self):
gDrawCircle(self,.5,.5,.2,gColorBlack(view))
def gAcceptNewViewportSize(self):
Gview.gAcceptNewViewportSize(self)
gClear(view)
self.gDrawView() ; complete redrawing on vp changes
The following routines follow the argument conventions established for G, and are designed to extend and be compatible with the other G routines. Since they are written "on top of" G, i.e., since they simply call G routines, they are not considered elementary G routines. (Obviously, this division is a bit arbitrary.)
gDrawArrow
(view, x1, y1, x2, y2[,
color])gdDrawArrow
(view, x1, y1, x2, y2[,
color]) gDrawArrowR
(view, x, y, deltax, deltay[,
color])gdDrawArrowR
(view, x, y, deltax, deltay[,
color]) gDrawArrowhead
(view, x1, y1, x2, y2 bodySize
headSize[, color])gdDrawArrowhead
(view, x1, y1, x2, y2
bodySize headSize[, color]) gDrawArrow
is
implemented as
def gDrawArrow(view,x1,y1,x2,y2,color=None)
gDrawArrowhead(view,x1,y1,x2,y2,1,.25,color))
gDrawArrowheadR
(view, x, y, deltax, deltay
bodySize headSize[, color])gdDrawArrowheadR
(view, x, y, deltax, deltay
bodySize headSize[, color])
These routines add buttons and menus and invoke the event processing.
gMainloop
()gMakeVisible
(view)gMainloop.
Your window will not be
interactive if you do not start gMainloop, though. You will not be able
to close, resize or move the window. On the mac, the spinning color
disc will be the cursor you see when you move into the window.gQuit
()gAddButton
(view, text, command, x, y[,
background])gdAddButton
(view, text, command, x, y[,
background]) gEnableButton
(button)gDisableButton
(button)gSetTitle
(vieworbutton, newtitle)gSetCursor
(view, cursorname)'crosshair', 'cross'
(crosshair cursor), 'sizing'
(resize handles), 'arrow',
'sb_down_arrow', 'sb_up_arrow', 'sb_left_arrow', 'sb_right_arrow'
(various arrows), 'watch', 'plus', 'pencil', 'hand1', 'hand2',
'xterm'
.
For example, to make the cross-hairs cursor appear whenever the
cursor goes over your
view, you would do the following: gSetCursor(myview, 'crosshair')
gAddMenu
(parent, menulabel[,
menuitems])The format of the menu items is as follows:
For example:
gAddMenu(window, "FA Demo", \
[["Init", initDemo], \
['button', "Show Old Line", showoldlines, 1, 0, None], \
["Resolution Higher", setResolutionHigher], \
["Resolution Lower", setResolutionLower], \
'---', \
["Alpha = 1.0", lambda: setAlpha(1.0)]])
If you wish to have the same menu for any window in your
application, you can add to the menu associated with GDEVICE. It is
called GMENU. For example,
global GMENU
gAddMenu(GMENU, "File", [["Open", openfile], ["Quit", gQuit]])
will make a small File menu that is inherited by any window you make.
G as described herein can be obtained by following instructions here. Move to the directory where you put g, and start Python. Then import G
from g import *
from quickgraph.g import *
If you have downloaded the RL Toolkit package and installed it as a python module, you can run Python from anywhere and import g with
from RLtoolkit.g import *
gMainloop
(or use gMakeVisible)
or your windows won't display or
be interactive.G is based on the python package Tkinter. As all of our development has been on a Macintosh, and not all of tk is available through Tkinter, and even less on the mac, some things have not been included so far (patterns, modes, button colors, etc). G is still under development and some undesired things may happen. Please let us know if they do.
Here is a small example:
# eg with gDrawView - try resizing the window!!
from g import *
class MyWindow(Gwindow):
def __init__(self):
Gwindow.__init__(self)
gdSetViewport(self, 10, 30, 300, 500)
def gDrawView(self):
gClear(self, 'blue')
drawThing(self, 'red')
def drawThing(win, color):
gdFillRect(win, 10, 20, 100, 200, color)
w = MyWindow()
gMainloop()
Here is a very small sample program with a button.
from g import *
def drawThing():
global w
gdFillRect(, 10, 20, 100, 200, 'red')
w = Gwindow()
gdSetViewport(w, 10, 30, 300, 500)
gClear(w, 'blue')
gdAddButton(w, "draw", drawThing, 20, 400, 'blue')
gMainloop()
Here is a very small sample program using gMakeVisible instead of
gMainloop.
from g import *
w = Gwindow()
gdSetViewport(w, 10, 30, 300, 500)
gClear(w, 'blue')
gdDrawCircle(w, 100, 100, 50, 'red')
gMakeVisible(w)