]> granicus.if.org Git - python/commitdiff
Started on support for callbacks for UserPane controls. Unfinished and untested.
authorJack Jansen <jack.jansen@cwi.nl>
Mon, 20 Mar 2000 16:09:09 +0000 (16:09 +0000)
committerJack Jansen <jack.jansen@cwi.nl>
Mon, 20 Mar 2000 16:09:09 +0000 (16:09 +0000)
Mac/Modules/ctl/Ctlmodule.c
Mac/Modules/ctl/ctlsupport.py

index 9b39f1a1efffd6b440deba7bdb0a4c620cbb2c35..530904c92510a248ab7f6fada39e6622c190057c 100644 (file)
@@ -84,6 +84,8 @@ ControlFontStyle_Convert(v, itself)
 /* TrackControl and HandleControlClick callback support */
 static PyObject *tracker;
 static ControlActionUPP mytracker_upp;
+static ControlUserPaneDrawUPP mydrawproc_upp;
+static ControlUserPaneIdleUPP myidleproc_upp;
 
 extern int settrackfunc(PyObject *);   /* forward */
 extern void clrtrackfunc(void);        /* forward */
@@ -99,6 +101,7 @@ PyTypeObject Control_Type;
 typedef struct ControlObject {
        PyObject_HEAD
        ControlHandle ob_itself;
+       PyObject *ob_callbackdict;
 } ControlObject;
 
 PyObject *CtlObj_New(itself)
@@ -110,6 +113,7 @@ PyObject *CtlObj_New(itself)
        if (it == NULL) return NULL;
        it->ob_itself = itself;
        SetControlReference(itself, (long)it);
+       it->ob_callbackdict = NULL;
        return (PyObject *)it;
 }
 CtlObj_Convert(v, p_itself)
@@ -128,6 +132,7 @@ CtlObj_Convert(v, p_itself)
 static void CtlObj_dealloc(self)
        ControlObject *self;
 {
+       Py_XDECREF(self->ob_callbackdict);
        if (self->ob_itself)SetControlReference(self->ob_itself, (long)0); /* Make it forget about us */
        PyMem_DEL(self);
 }
@@ -722,19 +727,18 @@ static PyObject *CtlObj_RemoveControlProperty(_self, _args)
        PyObject *_args;
 {
        PyObject *_res = NULL;
-       OSStatus _err;
+       OSStatus _rv;
        OSType propertyCreator;
        OSType propertyTag;
        if (!PyArg_ParseTuple(_args, "O&O&",
                              PyMac_GetOSType, &propertyCreator,
                              PyMac_GetOSType, &propertyTag))
                return NULL;
-       _err = RemoveControlProperty(_self->ob_itself,
-                                    propertyCreator,
-                                    propertyTag);
-       if (_err != noErr) return PyMac_Error(_err);
-       Py_INCREF(Py_None);
-       _res = Py_None;
+       _rv = RemoveControlProperty(_self->ob_itself,
+                                   propertyCreator,
+                                   propertyTag);
+       _res = Py_BuildValue("l",
+                            _rv);
        return _res;
 }
 
@@ -743,19 +747,18 @@ static PyObject *CtlObj_GetControlRegion(_self, _args)
        PyObject *_args;
 {
        PyObject *_res = NULL;
-       OSStatus _err;
+       OSStatus _rv;
        ControlPartCode inPart;
        RgnHandle outRegion;
        if (!PyArg_ParseTuple(_args, "hO&",
                              &inPart,
                              ResObj_Convert, &outRegion))
                return NULL;
-       _err = GetControlRegion(_self->ob_itself,
-                               inPart,
-                               outRegion);
-       if (_err != noErr) return PyMac_Error(_err);
-       Py_INCREF(Py_None);
-       _res = Py_None;
+       _rv = GetControlRegion(_self->ob_itself,
+                              inPart,
+                              outRegion);
+       _res = Py_BuildValue("l",
+                            _rv);
        return _res;
 }
 
@@ -1255,6 +1258,39 @@ static PyObject *CtlObj_GetControlDataHandle(_self, _args)
 
 }
 
+static PyObject *CtlObj_SetControlDataCallback(_self, _args)
+       ControlObject *_self;
+       PyObject *_args;
+{
+       PyObject *_res = NULL;
+
+       OSErr _err;
+       ControlPartCode inPart;
+       ResType inTagName;
+       PyObject *callback;
+       UniversalProcPtr *c_callback;
+
+       if (!PyArg_ParseTuple(_args, "hO&O",
+                             &inPart,
+                             PyMac_GetOSType, &inTagName,
+                             &callback))
+               return NULL;
+
+       if ( setcallback(_self, inTagName, callback, &c_callback) < 0 )
+               return NULL;
+       _err = SetControlData(_self->ob_itself,
+                             inPart,
+                             inTagName,
+                             sizeof(c_callback),
+                             (Ptr)&c_callback);
+
+       if (_err != noErr)
+               return PyMac_Error(_err);
+       _res = Py_None;
+       return _res;
+
+}
+
 static PyObject *CtlObj_GetPopupData(_self, _args)
        ControlObject *_self;
        PyObject *_args;
@@ -1373,9 +1409,9 @@ static PyMethodDef CtlObj_methods[] = {
        {"IsValidControlHandle", (PyCFunction)CtlObj_IsValidControlHandle, 1,
         "() -> (Boolean _rv)"},
        {"RemoveControlProperty", (PyCFunction)CtlObj_RemoveControlProperty, 1,
-        "(OSType propertyCreator, OSType propertyTag) -> None"},
+        "(OSType propertyCreator, OSType propertyTag) -> (OSStatus _rv)"},
        {"GetControlRegion", (PyCFunction)CtlObj_GetControlRegion, 1,
-        "(ControlPartCode inPart, RgnHandle outRegion) -> None"},
+        "(ControlPartCode inPart, RgnHandle outRegion) -> (OSStatus _rv)"},
        {"GetControlVariant", (PyCFunction)CtlObj_GetControlVariant, 1,
         "() -> (ControlVariant _rv)"},
        {"SetControlReference", (PyCFunction)CtlObj_SetControlReference, 1,
@@ -1420,6 +1456,8 @@ static PyMethodDef CtlObj_methods[] = {
         "(ResObj) -> None"},
        {"GetControlDataHandle", (PyCFunction)CtlObj_GetControlDataHandle, 1,
         "(part, type) -> ResObj"},
+       {"SetControlDataCallback", (PyCFunction)CtlObj_SetControlDataCallback, 1,
+        "(callbackfunc) -> None"},
        {"GetPopupData", (PyCFunction)CtlObj_GetPopupData, 1,
         NULL},
        {"SetPopupData", (PyCFunction)CtlObj_SetPopupData, 1,
@@ -1912,6 +1950,83 @@ mytracker(ctl, part)
                PySys_WriteStderr("TrackControl or HandleControlClick: exception in tracker function\n");
 }
 
+static int
+setcallback(self, which, callback, uppp)
+       ControlObject *self;
+       OSType which;
+       PyObject *callback;
+       UniversalProcPtr *uppp;
+{
+       char keybuf[9];
+       
+       if ( which == kControlUserPaneDrawProcTag )
+               *uppp = mydrawproc_upp;
+       else if ( which == kControlUserPaneIdleProcTag )
+               *uppp = myidleproc_upp;
+       else
+               return -1;
+       /* Only now do we test for clearing of the callback: */
+       if ( callback == Py_None )
+               *uppp = NULL;
+       /* Create the dict if it doesn't exist yet (so we don't get such a dict for every control) */
+       if ( self->ob_callbackdict == NULL )
+               if ( (self->ob_callbackdict = PyDict_New()) == NULL )
+                       return -1;
+       /* And store the Python callback */
+       sprintf(keybuf, "%x", which);
+       if (PyDict_SetItemString(self->ob_callbackdict, keybuf, callback) < 0)
+               return -1;
+       return 0;
+}
+
+static PyObject *
+callcallback(self, which, arglist)
+       ControlObject *self;
+       OSType which;
+       PyObject *arglist;
+{
+       char keybuf[9];
+       PyObject *func, *rv;
+       
+       sprintf(keybuf, "%x", which);
+       if ( self->ob_callbackdict == NULL ||
+                       (func = PyDict_GetItemString(self->ob_callbackdict, keybuf)) == NULL ) {
+               PySys_WriteStderr("Control callback without callback object\n");
+               return NULL;
+       }
+       rv = PyEval_CallObject(func, arglist);
+       if ( rv == NULL )
+               PySys_WriteStderr("Exception in control callback handler\n");
+       return rv;
+}
+
+static pascal void
+mydrawproc(ControlHandle control, SInt16 part)
+{
+       ControlObject *ctl_obj;
+       PyObject *arglist, *rv;
+       
+       ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
+       arglist = Py_BuildValue("Oh", ctl_obj, part);
+       rv = callcallback(ctl_obj, kControlUserPaneDrawProcTag, arglist);
+       Py_XDECREF(arglist);
+       Py_XDECREF(rv);
+}
+
+static pascal void
+myidleproc(ControlHandle control)
+{
+       ControlObject *ctl_obj;
+       PyObject *arglist, *rv;
+       
+       ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
+       arglist = Py_BuildValue("O", ctl_obj);
+       rv = callcallback(ctl_obj, kControlUserPaneIdleProcTag, arglist);
+       Py_XDECREF(arglist);
+       Py_XDECREF(rv);
+}
+
+
 
 void initCtl()
 {
@@ -1921,6 +2036,8 @@ void initCtl()
 
 
        mytracker_upp = NewControlActionProc(mytracker);
+       mydrawproc_upp = NewControlUserPaneDrawProc(mydrawproc);
+       myidleproc_upp = NewControlUserPaneDrawProc(myidleproc);
 
 
        m = Py_InitModule("Ctl", Ctl_methods);
index 5104d058ef2b02453fece75c29f5328a923459b2..ea9dcef20bf67b114e97dfa32a986ac4e9569abd 100644 (file)
@@ -84,6 +84,8 @@ ControlFontStyle_Convert(v, itself)
 /* TrackControl and HandleControlClick callback support */
 static PyObject *tracker;
 static ControlActionUPP mytracker_upp;
+static ControlUserPaneDrawUPP mydrawproc_upp;
+static ControlUserPaneIdleUPP myidleproc_upp;
 
 extern int settrackfunc(PyObject *);   /* forward */
 extern void clrtrackfunc(void);        /* forward */
@@ -157,19 +159,103 @@ mytracker(ctl, part)
        else
                PySys_WriteStderr("TrackControl or HandleControlClick: exception in tracker function\\n");
 }
+
+static int
+setcallback(self, which, callback, uppp)
+       ControlObject *self;
+       OSType which;
+       PyObject *callback;
+       UniversalProcPtr *uppp;
+{
+       char keybuf[9];
+       
+       if ( which == kControlUserPaneDrawProcTag )
+               *uppp = mydrawproc_upp;
+       else if ( which == kControlUserPaneIdleProcTag )
+               *uppp = myidleproc_upp;
+       else
+               return -1;
+       /* Only now do we test for clearing of the callback: */
+       if ( callback == Py_None )
+               *uppp = NULL;
+       /* Create the dict if it doesn't exist yet (so we don't get such a dict for every control) */
+       if ( self->ob_callbackdict == NULL )
+               if ( (self->ob_callbackdict = PyDict_New()) == NULL )
+                       return -1;
+       /* And store the Python callback */
+       sprintf(keybuf, "%x", which);
+       if (PyDict_SetItemString(self->ob_callbackdict, keybuf, callback) < 0)
+               return -1;
+       return 0;
+}
+
+static PyObject *
+callcallback(self, which, arglist)
+       ControlObject *self;
+       OSType which;
+       PyObject *arglist;
+{
+       char keybuf[9];
+       PyObject *func, *rv;
+       
+       sprintf(keybuf, "%x", which);
+       if ( self->ob_callbackdict == NULL ||
+                       (func = PyDict_GetItemString(self->ob_callbackdict, keybuf)) == NULL ) {
+               PySys_WriteStderr("Control callback without callback object\\n");
+               return NULL;
+       }
+       rv = PyEval_CallObject(func, arglist);
+       if ( rv == NULL )
+               PySys_WriteStderr("Exception in control callback handler\\n");
+       return rv;
+}
+
+static pascal void
+mydrawproc(ControlHandle control, SInt16 part)
+{
+       ControlObject *ctl_obj;
+       PyObject *arglist, *rv;
+       
+       ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
+       arglist = Py_BuildValue("Oh", ctl_obj, part);
+       rv = callcallback(ctl_obj, kControlUserPaneDrawProcTag, arglist);
+       Py_XDECREF(arglist);
+       Py_XDECREF(rv);
+}
+
+static pascal void
+myidleproc(ControlHandle control)
+{
+       ControlObject *ctl_obj;
+       PyObject *arglist, *rv;
+       
+       ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
+       arglist = Py_BuildValue("O", ctl_obj);
+       rv = callcallback(ctl_obj, kControlUserPaneIdleProcTag, arglist);
+       Py_XDECREF(arglist);
+       Py_XDECREF(rv);
+}
+
 """
 
 initstuff = initstuff + """
 mytracker_upp = NewControlActionProc(mytracker);
+mydrawproc_upp = NewControlUserPaneDrawProc(mydrawproc);
+myidleproc_upp = NewControlUserPaneDrawProc(myidleproc);
 """
 
 class MyObjectDefinition(ObjectIdentityMixin, GlobalObjectDefinition):
+       def outputStructMembers(self):
+               GlobalObjectDefinition.outputStructMembers(self)
+               Output("PyObject *ob_callbackdict;")
        def outputCheckNewArg(self):
                Output("if (itself == NULL) return PyMac_Error(resNotFound);")
        def outputInitStructMembers(self):
                GlobalObjectDefinition.outputInitStructMembers(self)
                Output("SetControlReference(itself, (long)it);")
+               Output("it->ob_callbackdict = NULL;")
        def outputCleanupStructMembers(self):
+               Output("Py_XDECREF(self->ob_callbackdict);")
                Output("if (self->ob_itself)SetControlReference(self->ob_itself, (long)0); /* Make it forget about us */")
 
 # Create the generator groups and link them
@@ -404,6 +490,38 @@ f = ManualGenerator("GetControlDataHandle", getcontroldatahandle_body);
 f.docstring = lambda: "(part, type) -> ResObj"
 object.add(f)
 
+# Manual Generator for SetControlDataCallback
+setcontroldatacallback_body = """
+OSErr _err;
+ControlPartCode inPart;
+ResType inTagName;
+PyObject *callback;
+UniversalProcPtr *c_callback;
+
+if (!PyArg_ParseTuple(_args, "hO&O",
+                      &inPart,
+                      PyMac_GetOSType, &inTagName,
+                      &callback))
+       return NULL;
+
+if ( setcallback(_self, inTagName, callback, &c_callback) < 0 )
+       return NULL;
+_err = SetControlData(_self->ob_itself,
+                     inPart,
+                     inTagName,
+                     sizeof(c_callback),
+                      (Ptr)&c_callback);
+
+if (_err != noErr)
+       return PyMac_Error(_err);
+_res = Py_None;
+return _res;
+"""
+
+f = ManualGenerator("SetControlDataCallback", setcontroldatacallback_body);
+f.docstring = lambda: "(callbackfunc) -> None"
+object.add(f)
+
 # And manual generators to get/set popup menu information
 getpopupdata_body = """
 PopupPrivateDataHandle hdl;