Problem with methods

woc8r@maple.cs.virginia.edu
Tue, 18 Jan 94 22:03:14 EST

I was hoping that I could enlist some help here...

I'm trying to add a Python interface to a user interface toolkit
written in C. The problem that I am having is when I specify my own
"widgets" -- elements of the user interface (like buttons or labels).
When these are specified, you have to specify two procedures - one
indicating what to paint on the widget, and the other to specify what
to do when it is "hit". I have implemented Python classes for each
widget (even though the underlying C is not object oriented). The
solution I have works fine when the hit and paint procedures are just
functions. The problem is that when the hit and paint procedures are
methods of a class, they get trampled on.

To be more specific, I declare two objects. One is of class
DraggingWidget (defined by me), and the other is of class TrashCan
(defined by the package). If the hit and paint procedures are not
methods of DraggingWidget, everything works fine. If they are
methods, the call to addDisplayToObject (the code will follow) knows
that hit and paint are methods, but as soon as the hit and paint
procedures are called, it thinks that the hit procedure is the
TrashCan instance and the paint procedure is a null object.

The python code is:
#! /users/woc8r/bin/python

import suit
import GP

class DraggingWidget (suit.Widget):
def __init__ (self, name):
self.object=suit.createObject (self, name, 'my dragging widget')
suit.addDisplayToObject (self.object, 'standard', self.HitDragger, self.PaintDragger)
def PaintDragger (self):
GP.line ((0.0, 0.0), (1.0, 1.0))
def HitDragger (dragger, ev):
myEvent = suit.Event (ev)
if (myEvent.type==suit.MOUSE_DOWN):
oldvp = dragger.getViewport (suit.VIEWPORT)
newvp = suit.moveRectangle (oldvp, myEvent.locator.position, suit.FALSE)
trashvp = trashcan.getViewport (suit.VIEWPORT)
if (suit.viewportsOverlap (newvp, trashvp)):
answer=suit.inform ('I\'ve been dropped over the trash can.')
else:
dragger.setViewport (suit.VIEWPORT, newvp)

suit.init ('dragdrop.py')
draggee = DraggingWidget('waldo')
trashcan = suit.TrashCan ('floyd')
done = suit.DoneButton (None)
suit.beginStandardApplication ()

-----
The c code for addDisplayToObject is:
static object* python_SUIT_addDisplayToObject (object* self, object* args)
{
object* arg_object;
char* arg_displayName;
object* arg_hitProc;
object* arg_paintProc;
SUIT_object c_object;
Pointer hitProc;
Pointer paintProc;

if (!getargs (args, "(OsOO)", &arg_object, &arg_displayName, &arg_hitProc, &arg_paintProc))
return NULL;

if (is_stringobject(arg_object)) {
if ((c_object = SUIT_name(getstringvalue(arg_object))) == NULL) {
char buffer[100];
sprintf (buffer, "SUIT object '%%s' does not exist", getstringvalue(arg_object));
err_setstr (RuntimeError, buffer);
return NULL;
}
}
else if (is_intobject(arg_object)) {
c_object = SUITobjectList[getintvalue(arg_object)].c_object;
}
else {
err_setstr (RuntimeError, "bad SUIT_object parameter");
return NULL;
}

if ((!is_funcobject (arg_hitProc)) && (!is_instancemethodobject (arg_hitProc)) && (arg_hitProc != None))
{
err_setstr (RuntimeError, "hitproc parameter is not function");
return NULL;
}
if (arg_hitProc == None)
hitProc = NULL;
else
hitProc = (Pointer) SharedPythonHit;

if ((!is_funcobject(arg_paintProc)) && (!is_instancemethodobject(arg_paintProc))&& (arg_paintProc != None))
{
err_setstr (RuntimeError, "paintproc parameter is not function");
return NULL;
}
if (arg_paintProc == None)
paintProc = NULL;
else
paintProc = (Pointer) SharedPythonPaint;

if (is_instancemethodobject (arg_paintProc))
printf ("paint is a method\n");

if (is_funcobject (arg_paintProc))
printf ("paint is a function\n");

SUIT_setFunctionPointer (c_object, PYTHON_PAINT, (void*)arg_paintProc);
SUIT_setFunctionPointer (c_object, PYTHON_HIT, (void*)arg_hitProc);
SUIT_addDisplayToObject (c_object, arg_displayName, hitProc, paintProc);

INCREF(None);
return None;
}

----
and the C code for the C paint procedure is:
(this is given to the C package as the paint procedure, where all it
does is call the Python paint procedure)

void SharedPythonPaint (SUIT_object obj)
{
object* pythonPaint;
object* param;

pythonPaint = (object*) SUIT_getFunctionPointer (obj, PYTHON_PAINT);

printf ("paint function is ");
printobject (pythonPaint, stdout, 0);
printobject (SUITobjectList[SUIT_getInteger (obj, WIDGET_NUMBER)].python_object, stdout, 0);
printf ("\n");

if ((!is_funcobject(pythonPaint)) && (!is_instancemethodobject(pythonPaint))) {
printf ("bad paint procedure\n");
return;
}

param = mkvalue ("(O)", SUITobjectList[SUIT_getInteger (obj, WIDGET_NUMBER)].python_object);
call_object (pythonPaint, param);
}

---
Any help I could get would be *greatly* appreciated!

Thanks!!! ___ ___ \ \ / / -=Bill Carlson=- | "I wanna decide who \ \/ / | lives and who dies" \ / INTERNET: woc8r@Virginia.EDU | \__/ BITNET: woc8r@VIRGINIA | -Crow T. Robot