Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cae6da6

Browse files
committed
- added support for ControlActionProcs, exposing the following calls:
- ctl.SetControlAction() - CreateScrollBarControl() - CreateSliderControl() - print traceback when callbacks fail
1 parent 85f9814 commit cae6da6

3 files changed

Lines changed: 187 additions & 7 deletions

File tree

Mac/Modules/ctl/_Ctlmodule.c

Lines changed: 139 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,10 @@ DataBrowserListViewColumnDesc_Convert(PyObject *v, DataBrowserListViewColumnDesc
128128
}
129129

130130
/* TrackControl and HandleControlClick callback support */
131+
#define kMyControlActionProcTag 'ACTN' /* not an official tag, only for internal use */
131132
static PyObject *tracker;
132133
static ControlActionUPP mytracker_upp;
134+
static ControlActionUPP myactionproc_upp;
133135
static ControlUserPaneDrawUPP mydrawproc_upp;
134136
static ControlUserPaneIdleUPP myidleproc_upp;
135137
static ControlUserPaneHitTestUPP myhittestproc_upp;
@@ -1183,6 +1185,25 @@ static PyObject *CtlObj_GetControlVariant(ControlObject *_self, PyObject *_args)
11831185
return _res;
11841186
}
11851187

1188+
static PyObject *CtlObj_SetControlAction(ControlObject *_self, PyObject *_args)
1189+
{
1190+
PyObject *_res = NULL;
1191+
PyObject* actionProc;
1192+
UniversalProcPtr c_callback;
1193+
#ifndef SetControlAction
1194+
PyMac_PRECHECK(SetControlAction);
1195+
#endif
1196+
if (!PyArg_ParseTuple(_args, "O",
1197+
&actionProc))
1198+
return NULL;
1199+
SetControlAction(_self->ob_itself,
1200+
myactionproc_upp);
1201+
Py_INCREF(Py_None);
1202+
_res = Py_None;
1203+
setcallback((PyObject*)_self, kMyControlActionProcTag, actionProc, &c_callback);
1204+
return _res;
1205+
}
1206+
11861207
static PyObject *CtlObj_SetControlReference(ControlObject *_self, PyObject *_args)
11871208
{
11881209
PyObject *_res = NULL;
@@ -4004,6 +4025,8 @@ static PyMethodDef CtlObj_methods[] = {
40044025
"(ControlPartCode inPart, RgnHandle outRegion) -> None"},
40054026
{"GetControlVariant", (PyCFunction)CtlObj_GetControlVariant, 1,
40064027
"() -> (ControlVariant _rv)"},
4028+
{"SetControlAction", (PyCFunction)CtlObj_SetControlAction, 1,
4029+
"(PyObject* actionProc) -> None"},
40074030
{"SetControlReference", (PyCFunction)CtlObj_SetControlReference, 1,
40084031
"(SInt32 data) -> None"},
40094032
{"GetControlReference", (PyCFunction)CtlObj_GetControlReference, 1,
@@ -4989,6 +5012,52 @@ static PyObject *Ctl_CreateBevelButtonControl(PyObject *_self, PyObject *_args)
49895012
}
49905013
#endif
49915014

5015+
static PyObject *Ctl_CreateSliderControl(PyObject *_self, PyObject *_args)
5016+
{
5017+
PyObject *_res = NULL;
5018+
OSStatus _err;
5019+
WindowPtr window;
5020+
Rect boundsRect;
5021+
SInt32 value;
5022+
SInt32 minimum;
5023+
SInt32 maximum;
5024+
UInt16 orientation;
5025+
UInt16 numTickMarks;
5026+
Boolean liveTracking;
5027+
PyObject* liveTrackingProc;
5028+
UniversalProcPtr c_callback;
5029+
ControlHandle outControl;
5030+
#ifndef CreateSliderControl
5031+
PyMac_PRECHECK(CreateSliderControl);
5032+
#endif
5033+
if (!PyArg_ParseTuple(_args, "O&O&lllHHbO",
5034+
WinObj_Convert, &window,
5035+
PyMac_GetRect, &boundsRect,
5036+
&value,
5037+
&minimum,
5038+
&maximum,
5039+
&orientation,
5040+
&numTickMarks,
5041+
&liveTracking,
5042+
&liveTrackingProc))
5043+
return NULL;
5044+
_err = CreateSliderControl(window,
5045+
&boundsRect,
5046+
value,
5047+
minimum,
5048+
maximum,
5049+
orientation,
5050+
numTickMarks,
5051+
liveTracking,
5052+
myactionproc_upp,
5053+
&outControl);
5054+
if (_err != noErr) return PyMac_Error(_err);
5055+
_res = Py_BuildValue("O&",
5056+
CtlObj_New, outControl);
5057+
setcallback(_res, kMyControlActionProcTag, liveTrackingProc, &c_callback);
5058+
return _res;
5059+
}
5060+
49925061
#if TARGET_API_MAC_CARBON
49935062

49945063
static PyObject *Ctl_CreateDisclosureTriangleControl(PyObject *_self, PyObject *_args)
@@ -5755,6 +5824,49 @@ static PyObject *Ctl_CreateCheckBoxControl(PyObject *_self, PyObject *_args)
57555824
}
57565825
#endif
57575826

5827+
static PyObject *Ctl_CreateScrollBarControl(PyObject *_self, PyObject *_args)
5828+
{
5829+
PyObject *_res = NULL;
5830+
OSStatus _err;
5831+
WindowPtr window;
5832+
Rect boundsRect;
5833+
SInt32 value;
5834+
SInt32 minimum;
5835+
SInt32 maximum;
5836+
SInt32 viewSize;
5837+
Boolean liveTracking;
5838+
PyObject* liveTrackingProc;
5839+
UniversalProcPtr c_callback;
5840+
ControlHandle outControl;
5841+
#ifndef CreateScrollBarControl
5842+
PyMac_PRECHECK(CreateScrollBarControl);
5843+
#endif
5844+
if (!PyArg_ParseTuple(_args, "O&O&llllbO",
5845+
WinObj_Convert, &window,
5846+
PyMac_GetRect, &boundsRect,
5847+
&value,
5848+
&minimum,
5849+
&maximum,
5850+
&viewSize,
5851+
&liveTracking,
5852+
&liveTrackingProc))
5853+
return NULL;
5854+
_err = CreateScrollBarControl(window,
5855+
&boundsRect,
5856+
value,
5857+
minimum,
5858+
maximum,
5859+
viewSize,
5860+
liveTracking,
5861+
myactionproc_upp,
5862+
&outControl);
5863+
if (_err != noErr) return PyMac_Error(_err);
5864+
_res = Py_BuildValue("O&",
5865+
CtlObj_New, outControl);
5866+
setcallback(_res, kMyControlActionProcTag, liveTrackingProc, &c_callback);
5867+
return _res;
5868+
}
5869+
57585870
#if TARGET_API_MAC_CARBON
57595871

57605872
static PyObject *Ctl_CreatePopupButtonControl(PyObject *_self, PyObject *_args)
@@ -6144,6 +6256,8 @@ static PyMethodDef Ctl_methods[] = {
61446256
{"CreateBevelButtonControl", (PyCFunction)Ctl_CreateBevelButtonControl, 1,
61456257
"(WindowPtr window, Rect boundsRect, CFStringRef title, UInt16 thickness, UInt16 behavior, ControlButtonContentInfo info, SInt16 menuID, UInt16 menuBehavior, UInt16 menuPlacement) -> (ControlHandle outControl)"},
61466258
#endif
6259+
{"CreateSliderControl", (PyCFunction)Ctl_CreateSliderControl, 1,
6260+
"(WindowPtr window, Rect boundsRect, SInt32 value, SInt32 minimum, SInt32 maximum, UInt16 orientation, UInt16 numTickMarks, Boolean liveTracking, PyObject* liveTrackingProc) -> (ControlHandle outControl)"},
61476261

61486262
#if TARGET_API_MAC_CARBON
61496263
{"CreateDisclosureTriangleControl", (PyCFunction)Ctl_CreateDisclosureTriangleControl, 1,
@@ -6259,6 +6373,8 @@ static PyMethodDef Ctl_methods[] = {
62596373
{"CreateCheckBoxControl", (PyCFunction)Ctl_CreateCheckBoxControl, 1,
62606374
"(WindowPtr window, Rect boundsRect, CFStringRef title, SInt32 initialValue, Boolean autoToggle) -> (ControlHandle outControl)"},
62616375
#endif
6376+
{"CreateScrollBarControl", (PyCFunction)Ctl_CreateScrollBarControl, 1,
6377+
"(WindowPtr window, Rect boundsRect, SInt32 value, SInt32 minimum, SInt32 maximum, SInt32 viewSize, Boolean liveTracking, PyObject* liveTrackingProc) -> (ControlHandle outControl)"},
62626378

62636379
#if TARGET_API_MAC_CARBON
62646380
{"CreatePopupButtonControl", (PyCFunction)Ctl_CreatePopupButtonControl, 1,
@@ -6371,8 +6487,10 @@ mytracker(ControlHandle ctl, short part)
63716487
}
63726488
if (rv)
63736489
Py_DECREF(rv);
6374-
else
6490+
else {
63756491
PySys_WriteStderr("TrackControl or HandleControlClick: exception in tracker function\n");
6492+
PyErr_Print();
6493+
}
63766494
}
63776495

63786496
static int
@@ -6381,7 +6499,9 @@ setcallback(PyObject *myself, OSType which, PyObject *callback, UniversalProcPtr
63816499
ControlObject *self = (ControlObject *)myself;
63826500
char keybuf[9];
63836501

6384-
if ( which == kControlUserPaneDrawProcTag )
6502+
if ( which == kMyControlActionProcTag )
6503+
*uppp = (UniversalProcPtr)myactionproc_upp;
6504+
else if ( which == kControlUserPaneDrawProcTag )
63856505
*uppp = (UniversalProcPtr)mydrawproc_upp;
63866506
else if ( which == kControlUserPaneIdleProcTag )
63876507
*uppp = (UniversalProcPtr)myidleproc_upp;
@@ -6418,11 +6538,26 @@ callcallback(ControlObject *self, OSType which, PyObject *arglist)
64186538
return NULL;
64196539
}
64206540
rv = PyEval_CallObject(func, arglist);
6421-
if ( rv == NULL )
6541+
if ( rv == NULL ) {
64226542
PySys_WriteStderr("Exception in control callback %x handler\n", (unsigned)which);
6543+
PyErr_Print();
6544+
}
64236545
return rv;
64246546
}
64256547

6548+
static pascal void
6549+
myactionproc(ControlHandle control, SInt16 part)
6550+
{
6551+
ControlObject *ctl_obj;
6552+
PyObject *arglist, *rv;
6553+
6554+
ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
6555+
arglist = Py_BuildValue("Oh", ctl_obj, part);
6556+
rv = callcallback(ctl_obj, kMyControlActionProcTag, arglist);
6557+
Py_XDECREF(arglist);
6558+
Py_XDECREF(rv);
6559+
}
6560+
64266561
static pascal void
64276562
mydrawproc(ControlHandle control, SInt16 part)
64286563
{
@@ -6494,6 +6629,7 @@ void init_Ctl(void)
64946629

64956630

64966631
mytracker_upp = NewControlActionUPP(mytracker);
6632+
myactionproc_upp = NewControlActionUPP(myactionproc);
64976633
mydrawproc_upp = NewControlUserPaneDrawUPP(mydrawproc);
64986634
myidleproc_upp = NewControlUserPaneIdleUPP(myidleproc);
64996635
myhittestproc_upp = NewControlUserPaneHitTestUPP(myhittestproc);

Mac/Modules/ctl/ctlscan.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ def makeblacklistnames(self):
8888
'GetControlPropertySize',
8989
'SendControlMessage', # Parameter changed from long to void* from UH3.3 to UH3.4
9090
'CreateTabsControl', # wrote manually
91+
'GetControlAction', # too much effort for too little usefulness
9192

9293
# too lazy for now
9394
'GetImageWellContentInfo',
@@ -259,7 +260,7 @@ def makegreylist(self):
259260
def makeblacklisttypes(self):
260261
return [
261262
'ProcPtr',
262-
'ControlActionUPP',
263+
# 'ControlActionUPP',
263264
'Ptr',
264265
'ControlDefSpec', # Don't know how to do this yet
265266
'ControlDefSpec_ptr', # ditto
@@ -319,6 +320,9 @@ def makerepairinstructions(self):
319320

320321
([("ControlButtonContentInfo", '*', "OutMode")],
321322
[("ControlButtonContentInfo", '*', "InMode")]),
323+
324+
([("ControlActionUPP", 'liveTrackingProc', "InMode")],
325+
[("ControlActionUPPNewControl", 'liveTrackingProc', "InMode")]),
322326
]
323327

324328
if __name__ == "__main__":

Mac/Modules/ctl/ctlsupport.py

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,24 @@
9494
ControlBevelButtonMenuPlacement = UInt16
9595
ControlPushButtonIconAlignment = UInt16
9696

97+
class ControlActionDefinition(Type):
98+
def declare(self, name):
99+
Output("%s %s;", self.typeName, name)
100+
Output("UniversalProcPtr c_callback;")
101+
def passInput(self, name):
102+
return "myactionproc_upp"
103+
def cleanup(self, name):
104+
Output("setcallback((PyObject*)_self, kMyControlActionProcTag, actionProc, &c_callback);")
105+
106+
class ControlActionDefinitionNewControl(ControlActionDefinition):
107+
def cleanup(self, name):
108+
Output("setcallback(_res, kMyControlActionProcTag, liveTrackingProc, &c_callback);")
109+
110+
ControlActionUPP = ControlActionDefinition("PyObject*", "O")
111+
ControlActionUPPNewControl = ControlActionDefinitionNewControl("PyObject*", "O")
112+
ControlSliderOrientation = UInt16
113+
114+
97115
includestuff = includestuff + """
98116
#ifdef WITHOUT_FRAMEWORKS
99117
#include <Controls.h>
@@ -203,8 +221,10 @@
203221
}
204222
205223
/* TrackControl and HandleControlClick callback support */
224+
#define kMyControlActionProcTag 'ACTN' /* not an official tag, only for internal use */
206225
static PyObject *tracker;
207226
static ControlActionUPP mytracker_upp;
227+
static ControlActionUPP myactionproc_upp;
208228
static ControlUserPaneDrawUPP mydrawproc_upp;
209229
static ControlUserPaneIdleUPP myidleproc_upp;
210230
static ControlUserPaneHitTestUPP myhittestproc_upp;
@@ -279,8 +299,10 @@
279299
}
280300
if (rv)
281301
Py_DECREF(rv);
282-
else
302+
else {
283303
PySys_WriteStderr("TrackControl or HandleControlClick: exception in tracker function\\n");
304+
PyErr_Print();
305+
}
284306
}
285307
286308
static int
@@ -289,7 +311,9 @@
289311
ControlObject *self = (ControlObject *)myself;
290312
char keybuf[9];
291313
292-
if ( which == kControlUserPaneDrawProcTag )
314+
if ( which == kMyControlActionProcTag )
315+
*uppp = (UniversalProcPtr)myactionproc_upp;
316+
else if ( which == kControlUserPaneDrawProcTag )
293317
*uppp = (UniversalProcPtr)mydrawproc_upp;
294318
else if ( which == kControlUserPaneIdleProcTag )
295319
*uppp = (UniversalProcPtr)myidleproc_upp;
@@ -326,11 +350,26 @@
326350
return NULL;
327351
}
328352
rv = PyEval_CallObject(func, arglist);
329-
if ( rv == NULL )
353+
if ( rv == NULL ) {
330354
PySys_WriteStderr("Exception in control callback %x handler\\n", (unsigned)which);
355+
PyErr_Print();
356+
}
331357
return rv;
332358
}
333359
360+
static pascal void
361+
myactionproc(ControlHandle control, SInt16 part)
362+
{
363+
ControlObject *ctl_obj;
364+
PyObject *arglist, *rv;
365+
366+
ctl_obj = (ControlObject *)CtlObj_WhichControl(control);
367+
arglist = Py_BuildValue("Oh", ctl_obj, part);
368+
rv = callcallback(ctl_obj, kMyControlActionProcTag, arglist);
369+
Py_XDECREF(arglist);
370+
Py_XDECREF(rv);
371+
}
372+
334373
static pascal void
335374
mydrawproc(ControlHandle control, SInt16 part)
336375
{
@@ -396,6 +435,7 @@
396435

397436
initstuff = initstuff + """
398437
mytracker_upp = NewControlActionUPP(mytracker);
438+
myactionproc_upp = NewControlActionUPP(myactionproc);
399439
mydrawproc_upp = NewControlUserPaneDrawUPP(mydrawproc);
400440
myidleproc_upp = NewControlUserPaneIdleUPP(myidleproc);
401441
myhittestproc_upp = NewControlUserPaneHitTestUPP(myhittestproc);

0 commit comments

Comments
 (0)