Formula takes an expression and converts it into a formula object. expression may be either a string (e.g., 'self.x + self.y') or a function (e.g., lambda self: self.x + self.y). If a formula wants to reference an instance variable in the object to which it will be attached, it should preface the name of the instance variable with self. (e.g., self.x).
In general, you must use a lambda function whenever you reference a variable or function outside the object to which the formula is attached (i.e., whenever you reference a variable or function that is not prefixed with self). The reason is that such references are considered references to global variables and there must be some way to capture the global dictionary for these variables. A lambda function captures this global dictionary.
print_contents()
print_contents prints the values of the fields in the formula data structure. This function can be useful for debugging a formula.
feedback.width = pam.Formula('self.obj_being_changed.width')
feedback.height = pam.Formula('self.obj_being_changed.height')
To handle cases where the pointer variable should be null, Pam defines a special global constant called FNULL that represents a null object. If a formula tries to make an access through a variable with the FNULL value, the formula will simply return its old value and terminate. For example, when no object is being moved or resized, the obj_being_changed variable could be set to FNULL. When the application accesses the feedback object's width or height variable, it will get the last computed value for these variables.
class RedSquare (pam.Rectangle):
filling_style = pam.Am_Red
length = 10
width = pam.Formula(lambda self: self.length)
height = pam.Formula(lambda self: self.length)
These values will be inherited by any instance objects that are
created, unless they are overridden by a subclass, or are overridden
by the user.
obj.name = pam.Formula(...)
For example, to assign a formula to a.bottom, one can write:
a.bottom = pam.Formula('self.top + self.height')
obj.remove_formula(name)
name should be the name of an instance variable. For example, to remove a formula from rect1.left, one would type:
rect1.remove_formula('left')
name = ClassName(variable1 = value, variable2 = value, ...)
where the variable names should be strings and the values may be either simple values or formulas. For example:
a = pam.Rectangle(left = 30,
right = pam.Formula('self.left + (2 * self.width)'),
value = 20)
print_contents prints all of a FormulaObject's variables and their values. Formula values are printed as Formula(value, valid flag), where value is the value last computed by the formula and the valid flag is t if the value is up-to-date and f if the value is out-of-date. For example, immediately after a is created in the above example, a.print_contents() would produce the output:
am_object ==> 2 fill_style ==> <PredefinedStyle instance at c7b28> height ==> 10 left ==> 30 line_style ==> <PredefinedStyle instance at c7b10> parts ==> [] right ==> Formula(0,'f') top ==> 0 value ==> 20 visible ==> 1 width ==> 10
The slots shown in addition to left, right and value are slots that are inherited from the instance's superclass (pam.Rectangle).
variable default description
name value
left 0 object's left side
top 0 object's top
width 10 object's width
height 10 object's height
visible true whether the object is visible
line_style Am_Black style of object's line segments
fill_style Am_White style of object's interior
as_line false whether the object should be treated as
a line or non-line
as_circle false whether the object should be treated as
a circle or non-circle
The line_style and fill_style attributes may be set
to pre-defined values representing useful attributes (e.g., the color
red), or to custom values created using the Style object. See the
Style Objects section below for details. The
as_line and as_circle attributes control how interactors,
such as the move-grow interactor, interact with the object (e.g., if
an object is treated as a circle, the move-grow interactor will set
the object's diameter slot rather than the object's width
and height slots.
This method destroys the graphical object and removes the object's image from the screen. The destroy command is also called when the object is garbage collected.
point_in_object(x, y, ref_obj)
This method returns true if the point lies within the object and false otherwise. ref_obj defines the coordinate system for the point. Usually the reference object will be a window, but sometimes it could be a group object.
to_top()
This method moves the object to the top of the stacking order in its group (or window if the object's owner is a window)
to_bottom()
This method moves the object to the bottom of the stacking order in its group (or window if the object's owner is a window).
move_object(ref_obj, above = true)
This method moves the object to just above the reference object in the stacking order if above is true, and otherwise to just below the reference object. above is an optional parameter that defaults to true.
my_rect = pam.Rectangle(left = 20, top = 50)
x = left + (fractional_point.x * width)
y = top + (fractional_point.y * height)
The relative attribute of a polygon determines which type of polygon it is. If relative is true, the polygon is a scalable polygon. If relative is false, the polygon is an absolute coordinate polygon. relative is settable only at polygon creation time. Consequently, once a polygon has been created, it cannot be changed to its other form.
The special attributes for a polygon are defined as follows:
variable default description
name value
point_list [(0.5, 0), (1, 1), points of the polygon--must be a list of
(0, 1), (0.5, 0)] tuples. Each tuple must be a pair of fractions
between 0 and 1 if the polygon is
a scalable polygon or a pair of integers if
the polygon is an absolute coordinate polygon.
relative true determines whether the polygon is a scalable
polygon (true) or an absolute coordinate
polygon (false). This attribute is settable
only at polygon-creation time.
_abs_point_list read-only The absolute coordinates of the polygon. This
variable will be the same as the point list
for absolute coordinate polygons. This
variable will contain the computed absolute
coordinates for scalable polygons.
Absolute coordinate polygons.
The specification for an example absolute coordinate polygon might look as follows:
p1 = pam.Polygon(point_list = [(10, 10), (40, 10), (25, 50), (10, 10)], relative = pam.false)
Scalable polygons. A scalable polygon's left, top, width, and height slots are both settable with integer values and constrainable via formulas. The polygon will be appropriately translated and resized in response to changes to any of these variables. The specification for an example scalable polygon might look as follows:
r1 = pam.Rectangle(left = 30, top = 40) p1 = pam.Polygon(point_list = [(0,0), (1, 0), (0.5, 1), (0, 0)], left = pam.Formula(lambda self: r1.left + r1.width + 20) top = pam.Formula(lambda self: r1.top), width = 30, height = 40)
variable default description name value x1 0 horizontal coordinate of first endpoint y1 0 vertical coordinate of first endpoint x2 10 horizontal coordinate of second endpoint y2 10 vertical coordinate of second endpoint as_line true tells Pam to treat the object like a line left read-only the line's left top read-only the line's top width read-only the line's width height read-only the line's heightA line object may be created by instancing Line. The position of a line can be set only via the x1, y1, x2 and y2 slots. For example:
my_line = pam.Line(x1 = 20, y1 = 50, x2 = 80, y2 = 130)is legal, but
my_line = pam.Line(left = 20, top = 50, width = 60, height = 80)is illegal and will cause an exception.
variable default description name value head_width 3 width of arrow head head_length 5 length of each arrow head lineAn arrow-line is a line with an "arrow head" at the (x2,y2) end.
variable default description name value angle1 0 origin, degrees from 3 o'clock angle2 360 terminus, distance from originAn arc object may be created by instancing Arc. For example:
my_arc = pam.Arc(left = 20, top = 50, width = 60, height = 80,
angle1 = 90, angle2 = 100)
The angle1 attribute specifies the origin of the arc, in degrees from
3 o'clock. The angle2 attribute specifies the
terminus (angular distance from origin), in degrees. The default for
angle1 is 0, and the default for angle2 is 360. Consequently,
by leaving out these two attributes, you can create an oval or circle
-- but you can also use Pam's oval and circle objects to do this as
well (see below).
variable default description name value radius read-only radius of circle diameter 10 diameter of circle as_circle true tells Pam to treat the object like a circle width read-only width of circle height read-only height of circleA circle object may be created by instancing Circle. Pam constrains the radius and diameter slots to have the expected relation: radius = 2 * diameter. The width and height attributes are similarly constrained, so that the width and height of the circle are always equal to each other and to the diameter.
The only size slot that can be modified or constrained by the user is the diameter slot. The width, height, and radius slots are all read only.
variable default description name value radius Am_SMALL_RADIUS radius of semicircle in cornerA roundtangle object may be created by instancing Roundtangle. For example:
my_roundtangle = pam.Roundtangle(left = 20, top = 50, width = 60, height = 80,
radius = 10)
The radius attribute specifies the radius of the half-circle
that makes up a corner. You can specify this value using an integer,
or the pre-defined constants Am_SMALL_RADIUS,
Am_MEDIUM_RADIUS, and Am_LARGE_RADIUS, whose values
are determined by the Amulet run-time library (and are therefore
subject to change). The default is Am_SMALL_RADIUS.
my_bitmap = pam.Bitmap(left = 20, top = 50, image = 'mypic.xbm')The image attribute specifies the file from which the image should be read. The width and height attributes of the bitmap default to the width and height of the entire image. These two attributes are read-only.
variable default description name value text '' text string to be displayed font Am_Default_Font font used to display text string width formula width of the displayed text string height formula height of the displayed text string
A text object may be created by instancing Text. For example:
my_text = pam.Text(left = 20, top = 50,
text = 'Not on a plane, not on a train')
This code will display the string 'Not on a plane, not on a train'
with the lower left corner of the 'N' at location (20, 50), using the
default font on your system. If you wish to use a different font, you
could create a Font Object and use it to specify the font
attribute of your Text Object, as in the following example:
my_font = pam.Font(family = pam.Am_FONT_SERIF, size = pam.Am_FONT_LARGE,
bold = pam.true, italic = pam.true)
my_text = pam.Text(left = 20, top = 50,
text = 'Not on a plane, not on a train',
font = my_font)
A font object has the following attributes:
variable default description name value family Am_FONT_FIXED font family size Am_FONT_MEDIUM font size bold false whether to use bold-face italic false whether to use italics underline false whether to use underlineThe family attribute specifies the font family in which to draw the text. The following values are supported :
class arrowline (pam.Group):
components = [ ('line',
lambda: am.Line(x1 = pam.Formula('self.owner.x1'),
y1 = pam.Formula('self.owner.y1'),
x2 = pam.Formula('self.owner.x2'),
y2 = pam.Formula('self.owner.y2'))),
('arrow',
lambda: pam.Polyline(point_list =
pam.Formula(lambda self: compute_pts(self))))
]
When an instance of the group is created, the function for each entry in the components list will be executed, creating a part. A reference to the part is then placed in the variable defined by the name portion of the entry. In the above example, each instance of arrowline would create two parts, and place references to them in the variables line and arrow.
Each part has a reference to its group placed in its owner variable. Hence each line and arrow part would have an owner slot that pointed to the appropriate arrowline object.
Finally, each part also has a name variable that stores the object's name (e.g., 'line' or 'arrow').
add_part dynamically adds parts to a group object after it has been created. The add_part method takes an object and an optional name, which must be a character string, and adds the object as a part of the group. For example:
my_group.add_part(a_rect) my_group.add_part(a_text, 'label')
If a name is passed to the add_part method, then a reference to the part is placed in a variable with that name in the group object. For example, the latter call in the above example stores a reference to a_text in my_group.label. If a name is passed to the add_part method, the name is also stored in the part's name variable.
Regardless of whether or not a name is passed as an argument, the owner variable in the object is set to its new group. Hence, in the above calls, both a_rect.owner and a_text.owner would be set to my_group.
remove_part(object)
An object can be removed from a group by calling remove_part with the object to be removed. For example, a_rect could be removed from my_group via the call:
my_group.remove_part(a_rect)
When an object is removed from a group, its owner variable is set to FNULL and its name variable, if one is defined, is destroyed. If the part was named, than the variable that pointed to this part in the group is set to FNULL. The reason for storing FNULL in the owner variable and in the group's partname variable rather than destroying these slots is to avoid destroying formulas that depend on these variables. These formulas will be temporarily inactivated. If the object is added to a new group, the formulas that depend on its owner slot will be reactivated. Similarly, if a new part with the same name as the old part is added to the group, the formulas in the group and in the group's parts that refer to this partname will be reactivated. Hence parts can be swapped in and out of a group without altering the formulas that depend on these parts.
An object does not have to be removed from a group before it is destroyed. The destroy method automatically removes an object from a group.
destroy()
destroy recursively destroys all of a group object's parts by calling their destroy commands, and then destroys the group object.
point_in_part(x, y, ref_obj)
point_in_part returns the topmost part (least covered) in the group that contains this point.
In order to display a graphical object in a window, it must be attached to the window using the add_part command. For example:
my_win.add_part(my_group)
In turn, a window must be attached to the screen object using the add_part command:
pam.screen.add_part(my_win)
Although there is a Screen class in Pam, Pam currently supports only one Screen object, called screen. Windows should always be added to this object.
When an object or window is destroyed, it is automatically removed from the window or screen of which it is a part. An object may be removed explicitly from a window using the remove_part method:
my_win.remove_part(my_group)
Similarly, a window can be removed from the screen using the remove_part method:
pam.screen.remove_part(my_win)
Am_Red Am_Cyan Am_Motif_Gray Am_Motif_Light_Gray Am_Green Am_Orange Am_Motif_Blue Am_Motif_Light_Blue Am_Blue Am_Black Am_Motif_Green Am_Motif_Light_Green Am_Yellow Am_White Am_Motif_Orange Am_Motif_Light_Orange Am_Purple Am_AMulet_Purple
Am_Thin_Line Am_Line_1 Am_Line_4 Am_Dashed_Line Am_Line_0 Am_Line_2 Am_Line_8 Am_Dotted_Line
Am_Gray_Stipple Am_Opaque_Gray_Stipple Am_Light_Gray_Stipple Am_Diamond_Stipple Am_Dark_Gray_Stipple Am_Opaque_Diamond_Stipple Am_No_Style
myblue = pam.AmBlue myblue.r = 0.5
thickblue_style = pam.Style(r = 0.0, g = 0.0, b = 1.0, thickness = 5)
my_rect = pam.Rectangle(top = 20, left = 20, width = 100, height = 50,
style = thickblue_style)
Unlike graphical objects, whose attributes can be changed after the object
is created, user-defined style objects do not allow their attributes
to be changed after the object is created. For example, the following Pam
code would result in an error:
thickblue_style = pam.Style(r = 0.0, g = 0.0, b = 1.0, thickness = 5)
my_rect = pam.Rectangle(top = 20, left = 20, width = 100, height = 50,
style = thickblue_style)
thickblue_style.r = 0.5
In order for Pam to process events, the programmer must call Pam's event loop:
pam.event_loop()
Pam's event loop continuously reads events, dispatches them to the appropriate interactor objects (discussed in the next section), and then updates the display after each event has been processed.
To get back to the Python interpreter, either:
variable default description
name value
start_when 'LEFT_DOWN' mouse event that initiates interaction
start_where_test Am_Inter_In_ position that cursor must be in to
Object_Or_Part initiate interaction
stop_when 'LEFT_UP' mouse event that terminates interaction
active true whether interactor works or not
start_callback (interactor-specific) routine that gets called when the
interactor starts
running_callback (interactor-specific) routine that gets called continuously
as the interactor runs
callback (interactor-specific) routine that gets called when
the interactor finishes
Further information on the possible
values for all these slots can be found in Section 5.3 of the Amulet
Reference Manual, and common sense also suggests what these values
might be. For example, since the start_when attribute
defaults to 'LEFT_DOWN', it makes sense that other values for
this attribute would be 'LEFT_UP', 'MIDDLE_DOWN',
etc.
The callback functions for each of the interactors have default actions.
If you want to override these default actions, you can write your own
callback functions. The sections that describe the individual interactors
describe which parameters each callback takes.
If you want to extend the default callback functions, rather than
overriding their behavior, you can call the default callback functions
by prefixing them with their superclass name. For example, to call
the default start_callback for a move/grow interactor, one would use
the name pam.Move_Grow_Interactor.start_callback.
There is more information about callbacks in each of the interactor sections.
my_rect = pam.Rectangle(top = 20, left = 20, width = 100, height = 50) my_inter = pam.Move_Grow_Interactor() my_rect.add_part(my_inter) pam.update() pam.event_loop()In this example, we haven't specified values for any of the attribute slots of the interactor, so how do we know what sort of behavior it will support? Fortunately, Pam provides some sensible defaults for the slots: in the example above, the interaction would start when the user clicked the left mouse button inside the rectangle, and would stop when the user released this button. Between those two events, the rectangle would move around its window as the user moved the mouse around. Note the invocation of pam.event_loop(); without this call, no user interaction could take place.
variable default description
name value
growing false if true, mouse movement resizes the
object; otherwise, it moves it
start_object None the object that will be modified
by this interactor
feedback_object None a feedback object that can be used
to show the object's new position or
size. A formula that reads the
object in the start_object slot and
then reads the object's as_line and
as_circle slots can be used to return
the appropriate feedback object (either
a line, circle, or rectangular feedback
object).
By default, a Move_Grow_Interactor behaves as follows. When the interactor starts, the start_callback checks the feedback slot of the interactor. If the feedback slot references a feedback object, then this feedback object is made visible and its position and size are set to the position and size of the object being moved or resized. If the value of the feedback slot is None, the start_callback does nothing.
While the move/grow interactor is running, the default running callback sets the appropriate position and size attributes of either the feedback object, if one exists, or the object being modified, if no feedback object exists.
When the move/grow interactor stops, the default callback function moves or resizes the object being modified.
If you want a different behavior for any of these three actions (start, running, or stop), you will need to write your own set of callback functions. All three callbacks take the same set of parameters:
self : A reference to the interactor
obj_changed : A reference to either the feedback object or to the
object being modified, whichever is appropriate
(if there is a feedback object, then the start and
running callbacks will get references to the feedback
object).
left (x1) : The left, top, width, and height values that the
top (y1) interactor has computed for a non-line object, or
width (x2) x1, y1, x2, y2 if the object is a line. Unlike Amulet,
height (y2) if the object is a line, the value will be for the
x1, y1, x2, y2 slots, no matter whether the object
is being moved or resized (Amulet will return the
line's left, top, width, and height if the line is
being moved).
For example, to turn the changed object red while it is being moved and then change it back to white when the movement is complete, one could write the following two callbacks:
def start_callback(self, obj_changed, left, top, width, height):
pam.Move_Grow_Interactor.start_callback(self, obj_changed, left,
top, width, height)
obj_changed.fill_style = pam.Am_Red
def callback(self, obj_changed, left, top, width, height):
pam.Move_Grow_Interactor.callback(self, obj_changed, left, top,
width, height)
obj_changed.fill_style = pam.Am_White
win = pam.Window(top = 200, left = 200, width = 400, height = 400)
pam.screen.add_part(win)
square = pam.Rectangle(top = 50, left = 50, width = 50, height = 50,
selected = pam.false,
interim_selected = pam.false,
line_style = pam.Formula(lambda self: (self.interim_selected
and pam.Am_Line_8) or pam.Am_Line_0),
fill_style = pam.Formula(lambda self: (self.selected and pam.Am_Red)
or pam.Am_White))
circle = pam.Arc(top = 150, left = 50, width = 50, height = 50,
selected = pam.false,
interim_selected = pam.false,
line_style = pam.Formula(lambda self: (self.interim_selected and
pam.Am_Line_8) or pam.Am_Line_0),
fill_style = pam.Formula(lambda self: (self.selected and pam.Am_Red)
or pam.Am_White))
inter = pam.Choice_Interactor()
win.add_part(square)
win.add_part(circle)
win.add_part(inter)
pam.update()
pam.event_loop()
In this example, we've put up a small square and circle, and allowed
th user to choose between them. The selected item is colored red. As
the choice interactor runs, the item currently under the mouse cursor
has its line style thickened.
Pam's Choice_Interactor supports the following additional slots:
variable default description
name value
how_set Am_CHOICE_TOGGLE whether single or multiple
values will be selected
first_one_only false whether mouse button must be
released to move between items
(i.e,. whether menu- or button-like)
value None object(s) selected. Will be either
None or a single object if
Am_CHOICE_TOGGLE or Am_CHOICE_SET
are used. Will be a list of 0 or more
items if Am_CHOICE_LIST_TOGGLE is used.
Will always be None if Am_CHOICE_CLEAR
is used.
object_modified read-only the object the mouse was over when
the interactor stopped. If how_set
is either Am_CHOICE_LIST_TOGGLE,
Am_CHOICE_CLEAR, or Am_CHOICE_TOGGLE,
this slot can be used to determine
the item that was affected by this
interaction.
By default the choice interactor works as follows. As the interactor runs, it sets the interim_selected slot of the object currently under the mouse to true. The interim_selected slots of all other objects are set to false. When the interactor stops, interim_selected slots of all the objects become false. The selected slots of all the objects in the interactor's value slot are set to true. The selected slots of the remaining objects are set to false. If the Am_CHOICE_CLEAR option is set, then the selected slot of the final object the mouse cursor was over is set to false.
Warning: Pam does not define the interim_selected and selected slots as a part of the base class for graphical objects. Hence, you must explicitly define default values for the interim_selected and selected slots in your graphical objects. If you do not explicitly define these slots and your objects access these slots in order to set their properties, then when the objects initially appear on the screen, they will cause an attribute error when they try to consult the interim_selected and selected slots.
The callbacks for the choice interactor have only one parameter:
self : A reference to the interactorThe value and object_modified slots of the interactor are useful for finding out which objects are currently selected, and which object was affected by this particular interaction.
text = pam.Text(text = 'Hello World', top = 50, left = 50) win.add_part(text) inter = pam.Text_Edit_Interactor() text.add_part(inter) pam.update() pam.event_loop()By placing the cursor over the edit-enabled text, the user can delete or add characters as in any text editor. The Text_Edit_Interactor supports the following additional attribute slots:
variable default description
name value
value "" value of text after edit
old_value "" value of text before edit
stop_when RETURN default stop event
start_where_test Am_inter_in_text_ default start where test
object_or_part
Note that the defaults for the start_where_test and
stop_when slots have different values in the Text_Edit_Interactor
than they do in the general interactor: in the Text_Edit_Interactor,
start_where_test defaults to
Am_inter_in_text_object_or_part, and stop_when defaults
to 'RETURN' (i.e., interaction terminates when the user hits a
carriage-return.)
As the text edit interactor runs, it continuously updates the text string in the object that it is editing. Consequently, when the text edit interactor stops, the object's text slot will contain its final value.
The callbacks for the text edit interactor have three parameters:
self : A reference to the interactor obj_changed : The object whose text string was modified value : The new text string
The New_Points_Interactor provides you with a little more flexibility, however: You can use any graphical object as the "feedback object" for the click-and-drag phase, and you can create any object once you've released the mouse button. So, for example, you can create a group of circles using a rectangle as the feedback object. Of course, this flexibility requires a little extra work on your part: you must first create the feedback object, and write a creation function, before the interactor can work as desired. Here is a simple example:
def create_rect(self, l, t, w, h):
new_rect = pam.Rectangle(left=l, top=t, width=w, height=h)
win.add_part(new_rect)
return new_rect
feedback_rect = pam.Rectangle(visible=pam.false,
line_style = pam.Am_Dashed_Line)
inter = pam.New_Points_Interactor(feedback_object = feedback_rect,
create_new_object_method = create_rect)
win.add_part(feedback_rect)
win.add_part(inter)
pam.update()
pam.event_loop()
There are a few things worth noting about this example:
The New_Points_Interactor supports the following additional slots:
variable default description name value feedback_object None object to show during interaction as_line false should be set to true if feedback object is a line flip_if_change_sides true if true, flip object when cursor moves to top or left of click-down point start_where_test Am_Inter_In position that cursor must be in to initiate interaction create_new_object_method None function that gets final position and dimenions of feedback object and whose return value is put into the value slot of the interactor value None value returned by create_new_object_ function (typically, newly- created object)There are a couple things to note about the Pam new points interactor:
By default, the new points interactor works as follows. When the interactor starts, the start callback makes the feedback object visible, if there is one. As the interactor runs, the running callback continually updates the feedback object's size. When the interactor stops, it calls the create_new_object_method and then the callback function. The create_new_object_method is expected to return a new object, while the callback does any other processing that is required.
The callbacks for the new points interactor have five parameters:
self : A reference to the interactor left (x1) : The left, top, width, and height values that the top (y1) interactor has computed for a non-line object, or width (x2) x1, y1, x2, y2 if the object is a line height (y2)
variable default description
name value
active true whether widget works or not
active_2 true when false, turns off graying-out
of widget when widget is
inactive
fill_style Am_Amulet_Purple color of widget
font Am_Default_Font font to use for item labels
implementation_parent None widget that will also respond
this widget's event -- e.g.,
dialog box could be
implementation parent of its
'Okay' button
max_rank false If max_rank is false, the widget's
items are laid out in a single row
or column. If max_rank is an integer,
that integer denotes the maximum
number of items that can be placed in
a row or column
value None current value of widget
variable default description
name value
final_feedback_wanted false whether to show which item is
selected or not
h_align Am_LEFT_ALIGN in a vertically-arranged
button panel with variable-
width buttons, determines
how buttons should be
arranged in panel (one of
Am_LEFT_ALIGN, Am_CENTER_ALIGN,
or Am_RIGHT_ALIGN)
v_align Am_CENTER_ALIGN works like h_align, but is
used only in horizontally-
arranged button panels with
variable-height buttons. Possible
values are Am_TOP_ALIGN,
Am_CENTER_ALIGN,
and Am_BOTTOM_ALIGN.
width Am_Width_Of_Parts read-only
height Am_Height_Of_Parts read-only
how_set read_only whether single or multiple
buttons can be selected
items None a list of tuples, each of the form
('label', routine), where
label is the button label and
routine the callback to
execute when the button is clicked
item_offset 3 number of pixels between
button label and button edge
layout Am_Vertical_Layout button orientation (either
Am_Vertical_Layout or
Am_Horizontal_Layout)
The following code example illustrates a simple usage of the Panel
Button. Note that:
win = pam.Window(left=300,width = 400, height = 400)
pam.screen.add_part(win)
pam.update()
def do_pooh(self):
print 'Oh bother!'
def do_piglet(self):
print 'I say, wake up, Pooh!'
def do_tigger(self):
print 'Ta-ta for now!'
list = [('Pooh',do_pooh), ('Piglet',do_piglet), ('Tigger',do_tigger)]
panel = pam.Button_Panel(top=20, left=20, items=list)
win.add_part(panel)
pam.update()
pam.event_loop()
variable default description
name value
items None a list of tuples, each of the form
('menu-name',
[('lable1',routine1),
('label2',routine2), ...])
The following code example illustrates a simple usage of the Menu
Bar. Note that callbacks take self as their single argument:
win = pam.Window(left=300,width = 400, height = 400)
pam.screen.add_part(win)
pam.update()
def do_save(self):
print 'save'
def do_open(self):
print 'open'
def do_new(self):
print 'new'
def do_cut(self):
print 'cut'
def do_copy(self):
print 'copy'
def do_paste(self):
print 'paste'
list = [
('File', [('Save',do_save), ('Open',do_open), ('New',do_new)]),
('Edit', [('Cut',do_cut), ('Copy',do_copy), ('Paste',do_paste)])
]
bar = pam.Menu_Bar(top=20, left=20, items=list)
win.add_part(bar)
pam.update()
pam.event_loop()
variable default description
name value
items None a list of labels
how_set read_only whether single or multiple
values will be selected
box_width 15 width of radio button, in pixels
box_height 15 height of radio button, in pixels
box_on_left true button to left of text if true,
to right of text if false
fixed_width false ???
final_feedback_wanted true whether or not to show which item is
selected
callback None function called when the user selects
an option
The following code example illustrates a simple usage of the Radio Button
Panel:
win = pam.Window(left=300,width = 400, height = 400) pam.screen.add_part(win) pam.update() list = ['WIMZ', 'WNCW', 'WUOT' ] panel = pam.Radio_Button_Panel(top=20, left=20, items=list) win.add_part(panel) pam.update() pam.event_loop()After the user selects an item from the panel, the identity of this item can be obtained as panel.value; a string value is returned.
The callback for the radio button panel takes only one parameter:
self : A reference to the radio button panelFor example:
def my_callback(self):
print self.value
panel.callback = my_callback
pam.event_loop()
variable default description
name value
items None a list of labels
how_set Am_CHOICE_LIST_TOGGLE whether single or multiple
values will be selected
box_width 15 width of check-box, in pixels
box_height 15 height of check-box, in pixels
box_on_left true button to left of text if true,
to right of text if false
fixed_width false ???
final_feedback_wanted true whether or not to show
which item is selected
callback None function called when the user
selects an option
After the user selects items from the panel, the identity of these
items can be obtained as panel.value; a list of strings is returned.
The callback for the radio button panel takes only one parameter:
self : A reference to the check box panelFor example:
def my_callback(self):
print self.value
panel.callback = my_callback
pam.event_loop()
Pam supports the following additional slots for the Scrolling_Group widget:
variable default description name value width 150 object's height 150 dimensions x_offset 0 coordinates of visual region, y_offset 0 in relation to origin of inner region inner_fill_style None background fill color: if None, 'fill_style' attribute value is used h_scroll_bar true whether or not to show horizontal scrollbar v_scroll_bar true whether or not to show vertical scrollbar h_scroll_bar_on_top false if true, horizontal scrollbar is put on top; otherwise, it's put on bottom v_scroll_bar_on_left false if true, vertical scrollbar is put on left; otherwise, it's put on right h_small_increment 10 small increments, in pixels, of v_small_increment 10 scrollbars: determine how much scrolling occurs when user clicks on scrollbar arrows h_large_increment None large increments, in pixels, of v_large_increment None scrollbars: determine how much scrolling occurs when user clicks in scroll area next to slider inner_width 400 size of entire group, not just inner_height 400 visible portionThe following code example illustrates a simple usage of the Scrolling_Group widget:
win = pam.Window(left=300,width = 400, height = 400) pam.screen.add_part(win) pam.update() sg = pam.Scrolling_Group(top=20, left=20, width=200, height=200) win.add_part(sg) square = pam.Rectangle(top=50, left=50, width=20, height=20) circle = pam.Circle(top=100, left=250, diameter=30) sg.add_part(square) sg.add_part(circle) pam.update() pam.event_loop()Initially, the circle would be outside the viewing range, but could be moved into view by using the horizontal scrollbar.
variable default description name value value '' text in the widget label '' label to left of text area width 150 width of text area font Am_Default_Font font for editable text label_font Am_Default_Label_Font font for label height (formula) set to maximum of label and value strings' heights callback (see below) function called when the user hits a carriage returnThe default Text_Input callback function sets the widget's value slot to the text entered by the user. If you want a different behavior for this function, you can write your own callback, which should accept two arguments, the first being the widget itself, and the second being the new value. For example:
def beavis_callback(self, value):
print 'Uh... you said ' + value + '... huh huh huh!'
widget = pam.Text_Input(top=100, left=20, callback=beavis_callback)
win.add_part(widget)
The Scroll_Bar widgets provide the following additional slots:
variable default description name value value 50 value set by scroll bar width 20 for Vertical_Scroll_Bar 200 for Horizontal_Scroll_Bar height 200 for Vertical_Scroll_Bar 20 for Horizontal_Scroll_Bar value_1 0 value at top (or left) value_2 100 value at bottom (or right) small_increment 1 change when arrow is clicked large_increment 10 change when scroll bar is clicked between arrow and indicator percent_visible 0.2 size of indicator (range = [0,1]) callback (see below) function called when the user moves the scroll-bar indicatorThe default callback function sets the widget's value slot to the value shown by the indicator, as the user changes the value. If you want a different behavior for this function, you can write your own callback, which should accept two arguments, the first being the widget itself, and the second being the new value, as in the Text_Input example above.
On the other hand, it is probably more useful to leave the callback slot alone and use a formula to display or otherwise access the value as it changes. The following example shows how you might do this, by having a Text object that reports the scroll bar's value as it changes:
scrollbar = pam.Vertical_Scroll_Bar(top=20, left=20) win.add_part(scrollbar) text = pam.Text(top=20, left=40, source=scrollbar, text=pam.Formula(lambda self: str(self.source.value))) win.add_part(text)
Line_Between_Objects defines these additional attributes:
variable default description name value object1 None object that governs (x1,y1) object2 None object that governs (x2,y2)You can use a circle-like object (as_circle slot true) or a rectangle-like object (both the as_circle and as_line slots are false) for either of the objects. Group objects are handled properly as long as the as_circle and as_line slots are set properly:
win = pam.Window(top = 200, left = 200, width = 400, height = 400)
pam.screen.add_part(win)
pam.update()
object1 = pam.Rectangle(top=200, left=200, width=80, height=50)
object2 = pam.Group(top=100, left=100, width=pam.Formula('self.diameter'),
height=pam.Formula('self.diameter'),
diameter = 40, as_circle = pam.true)
circle = pam.Circle(top=0, left=0,
diameter = pam.Formula('self.owner.diameter'))
object2.add_part(circle)
line = pam.Line_Between_Objects(object1=object1, object2=object2)
win.add_part(object1)
win.add_part(object2)
win.add_part(line)
inter = pam.Move_Grow_Interactor() # no fun unless we can move objects!
win.add_part(inter)
pam.event_loop()