libcm is a C development framework with an emphasis on audio signal processing applications.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cmGrPlot.c 32KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234
  1. #include "cmGlobal.h"
  2. #include "cmFloatTypes.h"
  3. #include "cmRpt.h"
  4. #include "cmErr.h"
  5. #include "cmCtx.h"
  6. #include "cmMem.h"
  7. #include "cmMallocDebug.h"
  8. #include "cmGr.h"
  9. #include "cmGrDevCtx.h"
  10. #include "cmGrPlot.h"
  11. #include "cmVectOpsTemplateMain.h"
  12. //------------------------------------------------------------------------------------------------------------------
  13. //------------------------------------------------------------------------------------------------------------------
  14. //------------------------------------------------------------------------------------------------------------------
  15. //------------------------------------------------------------------------------------------------------------------
  16. struct cmGrPl_str;
  17. typedef struct cmGrPlotObj_str
  18. {
  19. cmGrH_t grH; // the canvas this object is drawn on
  20. cmGrObjH_t grObjH; // the grObj this object is based on
  21. cmGrPlObjTypeId_t typeId;
  22. unsigned cfgFlags;
  23. unsigned stateFlags;
  24. cmGrVExt_t vext;
  25. cmChar_t* label;
  26. unsigned labelFlags;
  27. int labelAngle;
  28. cmGrColor_t labelColor;
  29. int loffs;
  30. int toffs;
  31. int roffs;
  32. int boffs;
  33. cmGrColor_t drawColors[ kMaxPlGrId ];
  34. cmGrColor_t fillColors[ kMaxPlGrId ];
  35. unsigned fontId;
  36. unsigned fontSize;
  37. unsigned fontStyle;
  38. void* userPtr;
  39. cmGrPlotCbFunc_t cbFunc;
  40. void* cbArg;
  41. struct cmGrPl_str* p; // owning plot object manager
  42. struct cmGrPlotObj_str* parent; // containing object
  43. struct cmGrPlotObj_str* xAnchor; // x-location reference object
  44. struct cmGrPlotObj_str* yAnchor; // y-location reference object
  45. struct cmGrPlotObj_str* next;
  46. struct cmGrPlotObj_str* prev;
  47. } cmGrPlotObj_t;
  48. typedef struct cmGrPl_str
  49. {
  50. cmCtx_t* ctx; //
  51. cmErr_t err; //
  52. cmGrPlotObj_t* list; // plot object linked list
  53. cmGrPlotObj_t* fop; // focused object ptr
  54. } cmGrPl_t;
  55. cmGrPlH_t cmGrPlNullHandle = cmSTATIC_NULL_HANDLE;
  56. cmGrPlObjH_t cmGrPlObjNullHandle = cmSTATIC_NULL_HANDLE;
  57. //------------------------------------------------------------------------------------------------------------------
  58. // Plot Private Functions
  59. //------------------------------------------------------------------------------------------------------------------
  60. cmGrPl_t* _cmGrPlHandleToPtr( cmGrPlH_t h )
  61. {
  62. cmGrPl_t* p = (cmGrPl_t*)h.h;
  63. assert(p!=NULL);
  64. return p;
  65. }
  66. cmGrPlotObj_t* _cmGrPlObjHandleToPtr( cmGrPlObjH_t oh )
  67. {
  68. cmGrPlotObj_t* op = (cmGrPlotObj_t*)oh.h;
  69. assert( op!=NULL);
  70. return op;
  71. }
  72. cmGrPlRC_t _cmGrPlotObjDelete( cmGrPlotObj_t* op )
  73. {
  74. if( op==NULL || cmGrObjIsValid( op->grH, op->grObjH)==false )
  75. return kOkGrPlRC;
  76. cmGrPl_t* p = op->p;
  77. // destroy the cmGrObj - which will call _cmGrPlotObjDestroy()
  78. if( cmGrObjDestroy( op->grH, &op->grObjH ) != kOkGrRC )
  79. return cmErrMsg( &p->err, kGrFailGrPlRC, "Delete failed on the object label='%s' id=%i\n",cmStringNullGuard( op->label ), cmGrObjId(op->grObjH) );
  80. return kOkGrPlRC;
  81. }
  82. void _cmGrPlotObjUnlink( cmGrPlotObj_t* op )
  83. {
  84. cmGrPl_t* p = op->p;
  85. if( op->next != NULL )
  86. op->next->prev = op->prev;
  87. if( op->prev != NULL )
  88. op->prev->next = op->next;
  89. if( p->list == op )
  90. p->list = op->next;
  91. }
  92. void _cmGrPlotObjLink( cmGrPl_t* p, cmGrPlotObj_t* op )
  93. {
  94. if( p->list != NULL )
  95. p->list->prev = op;
  96. op->next = p->list;
  97. op->prev = NULL;
  98. p->list = op;
  99. }
  100. // Destroy all objects
  101. cmGrPlRC_t _cmGrPlotClear( cmGrPl_t* p )
  102. {
  103. cmGrPlRC_t rc = kOkGrPlRC;
  104. cmGrPlotObj_t* op = p->list;
  105. while( op!=NULL )
  106. {
  107. cmGrPlotObj_t* t = op->next;
  108. if((rc = _cmGrPlotObjDelete(op)) != kOkGrPlRC )
  109. break;
  110. op = t;
  111. }
  112. return rc;
  113. }
  114. // Destroy the plot mgr
  115. cmGrPlRC_t _cmGrPlotDestroy( cmGrPl_t* p )
  116. {
  117. cmGrPlRC_t rc;
  118. if((rc = _cmGrPlotClear(p)) != kOkGrPlRC )
  119. return rc;
  120. cmMemFree(p);
  121. return kOkGrPlRC;
  122. }
  123. bool _cmGrPlotObjIsVisible( cmGrPlotObj_t* op )
  124. { return cmIsNotFlag(op->cfgFlags,kNoDrawGrPlFl); }
  125. bool _cmGrPlotObjIsEnabled( cmGrPlotObj_t* op )
  126. {
  127. // invisible objects are never enabled
  128. if( _cmGrPlotObjIsVisible(op) == false )
  129. return false;
  130. return cmIsFlag(op->stateFlags,kEnabledGrPlFl);
  131. }
  132. bool _cmGrPlotObjIsFocused(cmGrPlotObj_t* op)
  133. { return _cmGrPlotObjIsEnabled(op) && op->p->fop==op; }
  134. bool _cmGrPlotObjIsSelected(cmGrPlotObj_t* op)
  135. { return _cmGrPlotObjIsFocused(op) || cmIsFlag(op->stateFlags,kSelectGrPlFl); }
  136. void _cmGrPlotObjSetupCbArg( cmGrPlotCbArg_t* a, cmGrPlotObj_t* op, cmGrPlCbSelId_t selId )
  137. {
  138. cmGrPlObjH_t oH;
  139. oH.h = op;
  140. memset(a,0,sizeof(a));
  141. a->ctx = op->p->ctx;
  142. a->cbArg = op->cbArg;
  143. a->selId = selId;
  144. a->objH = oH;
  145. }
  146. bool _cmGrPlotObjCb( cmGrPlotObj_t* op, cmGrPlCbSelId_t selId, unsigned deltaFlags )
  147. {
  148. if( op->cbFunc != NULL )
  149. {
  150. cmGrPlotCbArg_t a;
  151. _cmGrPlotObjSetupCbArg(&a,op,kPreEventCbSelGrPlId);
  152. a.deltaFlags = deltaFlags;
  153. return op->cbFunc(&a);
  154. }
  155. return true;
  156. }
  157. void _cmGrPlotObjSetFocus( cmGrPlotObj_t* op )
  158. {
  159. // if 'op' is not enabled then it cannot receive the focus
  160. if( _cmGrPlotObjIsEnabled(op) == false )
  161. return;
  162. // if the focus cannot be set on 'op' - then try op->parent
  163. for(; op!=NULL; op=op->parent)
  164. if( cmIsNotFlag(op->cfgFlags,kNoFocusGrPlFl) && cmIsNotFlag(op->cfgFlags,kNoDrawGrPlFl) )
  165. break;
  166. if( op != NULL )
  167. {
  168. if( op->p->fop != NULL )
  169. {
  170. // if the application callback returns false then do no release focus from the current object
  171. if(_cmGrPlotObjCb(op->p->fop, kStateChangeGrPlId, kFocusGrPlFl ) == false )
  172. return;
  173. op->p->fop = NULL;
  174. }
  175. // if the application callback returns false then do not give focus to the selected object
  176. if(_cmGrPlotObjCb(op, kStateChangeGrPlId, kFocusGrPlFl ) == false )
  177. return;
  178. op->p->fop = op;
  179. }
  180. }
  181. void _cmGrPlotObjSetSelect( cmGrPlotObj_t* op, bool clearFl )
  182. {
  183. // if the object is disabled or no selectable
  184. if( _cmGrPlotObjIsEnabled(op)==false || cmIsFlag(op->cfgFlags,kNoSelectGrPlFl | kNoDrawGrPlFl) )
  185. return;
  186. unsigned stateFlags = op->stateFlags;
  187. // if the application callback returns false then do change the select state of the object
  188. if(_cmGrPlotObjCb(op, kStateChangeGrPlId, kSelectGrPlFl ) == false )
  189. return;
  190. if( clearFl )
  191. {
  192. cmGrObjH_t parentObjH = cmGrObjParent(op->grObjH);
  193. cmGrPlotObj_t* cop = op->p->list;
  194. // clear the select flag on all objects that share op->parent
  195. for(; cop!=NULL; cop=cop->next)
  196. if( cmHandlesAreEqual(cmGrObjParent(cop->grObjH),parentObjH) )
  197. cop->stateFlags = cmClrFlag(cop->stateFlags,kSelectGrPlFl);
  198. }
  199. op->stateFlags = cmTogFlag(stateFlags,kSelectGrPlFl);
  200. }
  201. const cmGrColor_t _cmGrPlotColor( cmGrPlotObj_t* op, cmGrColor_t* array )
  202. {
  203. if( _cmGrPlotObjIsFocused(op) )
  204. return array[kFocusPlGrId];
  205. if( _cmGrPlotObjIsSelected(op) )
  206. return array[kSelectPlGrId];
  207. if( _cmGrPlotObjIsEnabled(op) )
  208. return array[kEnablePlGrId];
  209. return array[kDisablePlGrId];
  210. }
  211. unsigned _cmGrPlotObjTriShapeToFlags( unsigned typeId)
  212. {
  213. switch(typeId)
  214. {
  215. case kUTriGrPlId: return kTopGrFl;
  216. case kDTriGrPlId: return kBottomGrFl;
  217. case kLTriGrPlId: return kLeftGrFl;
  218. case kRTriGrPlId: return kRightGrFl;
  219. default:
  220. { assert(0); }
  221. }
  222. return 0;
  223. }
  224. //------------------------------------------------------------------------------------------------------------------
  225. // Plot Object Callback Functions
  226. //------------------------------------------------------------------------------------------------------------------
  227. cmGrRC_t _cmGrPlotObjCreate( cmGrObjFuncArgs_t* args )
  228. {
  229. cmGrPlotObj_t* op = args->cbArg;
  230. _cmGrPlotObjCb(op,kCreatedCbSelGrPlId,0);
  231. // return kOkGrRC to indicate that the create was successful
  232. return kOkGrRC;
  233. }
  234. void _cmGrPlotObjDestroy( cmGrObjFuncArgs_t* args )
  235. {
  236. cmGrPlotObj_t* op = args->cbArg;
  237. // TODO: is it possible to prevent destruction by returning
  238. // 'false' from the used defined callback. This feature is
  239. // slightly complicated by the fact
  240. // that in some circumstances the destroy request is not
  241. // optional - for example when the program is closing.
  242. _cmGrPlotObjCb(op,kDestroyedCbSelGrPlId,0);
  243. _cmGrPlotObjUnlink( op );
  244. cmMemFree(op->label);
  245. cmMemFree(op);
  246. }
  247. void _cmGrPlotObjGetVExt( cmGrPlotObj_t* op, cmGrVExt_t* vext )
  248. {
  249. switch( op->typeId )
  250. {
  251. case kStarGrPlId:
  252. case kCrossGrPlId:
  253. case kPlusGrPlId:
  254. case kDiamondGrPlId:
  255. case kUTriGrPlId:
  256. case kDTriGrPlId:
  257. case kLTriGrPlId:
  258. case kRTriGrPlId:
  259. case kRectGrPlId:
  260. case kLineGrPlId:
  261. case kEllipseGrPlId:
  262. {
  263. *vext = op->vext;
  264. }
  265. break;
  266. case kHLineGrPlId:
  267. case kVLineGrPlId:
  268. {
  269. cmGrVExt_t wext;
  270. cmGrObjH_t oh = cmGrObjParent(op->grObjH);
  271. cmGrObjWorldExt(oh,&wext);
  272. // TODO: Put a check somewhere which can report an error
  273. // message when the parents world extent is not yet set.
  274. // Horz and Vert lines depend on the their parent's
  275. // world extents being set first. There is no automatic
  276. // way to set the parent world extents because we don't
  277. // know the range of values which the data set will cover.
  278. // Any number picked could result in a range much to large
  279. // thereby leaving the data invisible. It therefore must
  280. // be up to the application to set a good range.
  281. assert( cmGrVExtIsNotNullOrEmpty(&wext) );
  282. vext->loc.x = op->typeId==kHLineGrPlId ? wext.loc.x : op->vext.loc.x;
  283. vext->loc.y = op->typeId==kVLineGrPlId ? wext.loc.y : op->vext.loc.y;
  284. vext->sz.w = op->typeId==kHLineGrPlId ? wext.sz.w : op->vext.sz.w;
  285. vext->sz.h = op->typeId==kVLineGrPlId ? wext.sz.h : op->vext.sz.h;
  286. }
  287. break;
  288. default:
  289. { assert(0); }
  290. }
  291. // add up the anchor offsets until the first object in the container
  292. cmGrPlotObj_t* ap = op->xAnchor;
  293. for(; ap!=NULL; ap=ap->xAnchor)
  294. {
  295. vext->loc.x += ap->vext.loc.x;
  296. if( ap->xAnchor==ap->parent)
  297. break;
  298. }
  299. ap = op->yAnchor;
  300. for(; ap!=NULL; ap=ap->yAnchor)
  301. {
  302. vext->loc.y += ap->vext.loc.y;
  303. if( ap->yAnchor==ap->parent)
  304. break;
  305. }
  306. }
  307. void _cmGrPlotObjVExt( cmGrObjFuncArgs_t* args, cmGrVExt_t* vext )
  308. {
  309. cmGrPlotObj_t* op = args->cbArg;
  310. _cmGrPlotObjGetVExt(op, vext);
  311. }
  312. bool _cmGrPlotObjRender( cmGrObjFuncArgs_t* args, cmGrDcH_t dcH )
  313. {
  314. cmGrPlotObj_t* op = args->cbArg;
  315. cmGrPExt_t pext;
  316. cmGrVExt_t vext;
  317. if( !_cmGrPlotObjIsVisible(op) )
  318. return false;
  319. // get the virtual extents of this object
  320. _cmGrPlotObjVExt( args, &vext );
  321. // convert the virtual ext's to phys ext's
  322. cmGrVExt_VtoP( op->grH, op->grObjH, &vext, &pext);
  323. // expand the ext's according to the physical offsets
  324. cmGrPExtExpand(&pext,op->loffs,op->toffs,op->roffs,op->boffs);
  325. switch( op->typeId )
  326. {
  327. case kLineGrPlId:
  328. cmGrDcSetColor( dcH, _cmGrPlotColor(op,op->drawColors) );
  329. cmGrDcDrawLine( dcH, cmGrPExtL(&pext), cmGrPExtT(&pext), cmGrPExtR(&pext), cmGrPExtB(&pext) );
  330. break;
  331. case kStarGrPlId:
  332. case kCrossGrPlId:
  333. case kPlusGrPlId:
  334. case kEllipseGrPlId:
  335. case kDiamondGrPlId:
  336. case kUTriGrPlId:
  337. case kDTriGrPlId:
  338. case kLTriGrPlId:
  339. case kRTriGrPlId:
  340. case kRectGrPlId:
  341. case kHLineGrPlId:
  342. case kVLineGrPlId:
  343. {
  344. if( cmIsNotFlag(op->cfgFlags,kNoFillGrPlFl) )
  345. {
  346. // set the fill color
  347. cmGrDcSetColor( dcH, _cmGrPlotColor(op,op->fillColors) );
  348. // draw the fill
  349. switch(op->typeId)
  350. {
  351. case kEllipseGrPlId:
  352. cmGrDcFillEllipse( dcH, pext.loc.x, pext.loc.y, pext.sz.w, pext.sz.h);
  353. break;
  354. case kDiamondGrPlId:
  355. cmGrDcFillDiamond( dcH, pext.loc.x, pext.loc.y, pext.sz.w, pext.sz.h);
  356. break;
  357. case kUTriGrPlId:
  358. case kDTriGrPlId:
  359. case kLTriGrPlId:
  360. case kRTriGrPlId:
  361. cmGrDcFillTriangle( dcH, pext.loc.x, pext.loc.y, pext.sz.w, pext.sz.h, _cmGrPlotObjTriShapeToFlags(op->typeId));
  362. break;
  363. case kStarGrPlId:
  364. case kCrossGrPlId:
  365. case kPlusGrPlId:
  366. case kRectGrPlId:
  367. case kHLineGrPlId:
  368. case kVLineGrPlId:
  369. cmGrDcFillRect( dcH, pext.loc.x, pext.loc.y, pext.sz.w, pext.sz.h);
  370. break;
  371. default:
  372. { assert(0); }
  373. }
  374. }
  375. if( cmIsNotFlag(op->cfgFlags,kNoBorderGrPlFl) )
  376. {
  377. // set the border color
  378. cmGrDcSetColor( dcH, _cmGrPlotColor(op,op->drawColors) );
  379. // draw the border
  380. switch(op->typeId)
  381. {
  382. case kEllipseGrPlId:
  383. cmGrDcDrawEllipse( dcH, pext.loc.x, pext.loc.y, pext.sz.w, pext.sz.h);
  384. break;
  385. case kDiamondGrPlId:
  386. cmGrDcDrawDiamond( dcH, pext.loc.x, pext.loc.y, pext.sz.w, pext.sz.h);
  387. break;
  388. case kUTriGrPlId:
  389. case kDTriGrPlId:
  390. case kLTriGrPlId:
  391. case kRTriGrPlId:
  392. cmGrDcDrawTriangle( dcH, pext.loc.x, pext.loc.y, pext.sz.w, pext.sz.h, _cmGrPlotObjTriShapeToFlags(op->typeId));
  393. break;
  394. case kStarGrPlId:
  395. cmGrDcDrawLine( dcH, cmGrPExtL(&pext), cmGrPExtT(&pext), cmGrPExtR(&pext), cmGrPExtB(&pext));
  396. cmGrDcDrawLine( dcH, cmGrPExtL(&pext), cmGrPExtB(&pext), cmGrPExtR(&pext), cmGrPExtT(&pext));
  397. cmGrDcDrawLine( dcH, cmGrPExtL(&pext) + cmGrPExtW(&pext)/2, cmGrPExtT(&pext), cmGrPExtL(&pext) + cmGrPExtW(&pext)/2, cmGrPExtB(&pext));
  398. cmGrDcDrawLine( dcH, cmGrPExtL(&pext), cmGrPExtT(&pext) + cmGrPExtH(&pext)/2, cmGrPExtR(&pext), cmGrPExtT(&pext) + cmGrPExtH(&pext)/2);
  399. break;
  400. case kCrossGrPlId:
  401. cmGrDcDrawLine( dcH, cmGrPExtL(&pext), cmGrPExtT(&pext), cmGrPExtR(&pext), cmGrPExtB(&pext));
  402. cmGrDcDrawLine( dcH, cmGrPExtR(&pext), cmGrPExtT(&pext), cmGrPExtL(&pext), cmGrPExtB(&pext));
  403. break;
  404. case kPlusGrPlId:
  405. cmGrDcDrawLine( dcH, cmGrPExtL(&pext) + cmGrPExtW(&pext)/2, cmGrPExtT(&pext), cmGrPExtL(&pext) + cmGrPExtW(&pext)/2, cmGrPExtB(&pext));
  406. cmGrDcDrawLine( dcH, cmGrPExtL(&pext), cmGrPExtT(&pext) + cmGrPExtH(&pext)/2, cmGrPExtR(&pext), cmGrPExtT(&pext) + cmGrPExtH(&pext)/2);
  407. break;
  408. case kRectGrPlId:
  409. case kHLineGrPlId:
  410. case kVLineGrPlId:
  411. cmGrDcDrawRect( dcH, pext.loc.x, pext.loc.y, pext.sz.w, pext.sz.h);
  412. break;
  413. default:
  414. { assert(0); }
  415. }
  416. }
  417. if( (op->label != NULL) && cmIsNotFlag(op->cfgFlags, kNoLabelGrPlFl) )
  418. {
  419. unsigned cc = cmGrDcColor(dcH);
  420. cmGrDcSetColor(dcH,op->labelColor);
  421. cmGrDcDrawTextJustify( dcH, op->fontId, op->fontSize, op->fontStyle, op->label, &pext, op->labelFlags );
  422. cmGrDcSetColor(dcH,cc);
  423. /*
  424. cmGrPSz_t sz;
  425. cmGrPPt_t pt;
  426. cmGrDcFontSetAndMeasure( dcH, op->fontId, op->fontSize, op->fontStyle, op->label, &sz );
  427. cmGrPExtCtr( &pext, &pt );
  428. cmGrDcDrawText( dcH, op->label, pt.x - sz.w/2, pt.y + sz.h/2 );
  429. */
  430. }
  431. }
  432. break;
  433. default:
  434. { assert(0); }
  435. }
  436. return true;
  437. }
  438. int _cmGrPlotObjDistance( cmGrObjFuncArgs_t* args, int x, int y )
  439. {
  440. return 0;
  441. }
  442. bool _cmGrPlotObjEvent( cmGrObjFuncArgs_t* args, unsigned flags, unsigned key, int px, int py )
  443. {
  444. cmGrPlotObj_t* op = args->cbArg;
  445. bool fl = false;
  446. cmGrPlotCbArg_t a;
  447. if( op->cbFunc != NULL )
  448. {
  449. cmGrPlotObj_t* cb_op = op;
  450. // if this is a key up/dn event and 'op' is not the 'focused op' then callback
  451. // callback on the 'focused op' instead of this 'op'.
  452. if( (cmIsFlag(flags,kKeyDnGrFl) || cmIsFlag(flags,kKeyUpGrFl)) && op->p->fop != op )
  453. cb_op = op->p->fop;
  454. _cmGrPlotObjSetupCbArg(&a,cb_op,kPreEventCbSelGrPlId);
  455. a.eventFlags = flags;
  456. a.eventKey = key;
  457. a.eventX = px;
  458. a.eventY = py;
  459. if( op->cbFunc(&a) == false )
  460. return true;
  461. }
  462. switch( flags & kEvtMask )
  463. {
  464. case kMsDownGrFl:
  465. break;
  466. case kMsUpGrFl:
  467. _cmGrPlotObjSetFocus( op );
  468. fl = true;
  469. break;
  470. case kMsClickGrFl:
  471. _cmGrPlotObjSetSelect(op, cmIsNotFlag(flags,kCtlKeyGrFl) );
  472. fl = true;
  473. break;
  474. case kMsDragGrFl:
  475. {
  476. cmGrVExt_t vext;
  477. cmGrVExt_t wext;
  478. if( cmIsFlag(op->cfgFlags,kNoDragGrPlFl | kNoDrawGrPlFl) )
  479. return false;
  480. // get the parent world extents
  481. cmGrObjWorldExt( cmGrObjParent( args->objH ), &wext );
  482. // calc the new position of the obj
  483. cmGrV_t x = args->msVPt.x - args->msDnVOffs.w;
  484. cmGrV_t y = args->msVPt.y - args->msDnVOffs.h;
  485. cmGrVExtSet(&vext,x,y,op->vext.sz.w,op->vext.sz.h);
  486. // the obj must be remain inside the parent wext
  487. cmGrVExtContain(&wext,&vext);
  488. // calculate the obj's location as an offset from it's anchors
  489. cmGrPlotObj_t* ap = op->xAnchor;
  490. for(; ap!=NULL; ap=ap->xAnchor)
  491. vext.loc.x -= ap->vext.loc.x;
  492. ap = op->yAnchor;
  493. for(; ap!=NULL; ap=ap->yAnchor)
  494. vext.loc.y -= ap->vext.loc.y;
  495. if( !cmGrVExtIsEqual(&op->vext,&vext) )
  496. {
  497. // move the object
  498. op->vext.loc.x = vext.loc.x;
  499. op->vext.loc.y = vext.loc.y;
  500. fl = true;
  501. }
  502. }
  503. break;
  504. case kKeyDnGrFl:
  505. case kKeyUpGrFl:
  506. break;
  507. }
  508. // notify the app of the event
  509. if( op->cbFunc != NULL )
  510. {
  511. a.selId = kEventCbSelGrPlId;
  512. op->cbFunc(&a);
  513. }
  514. return fl;
  515. }
  516. bool _cmGrPlotObjIsInside( cmGrObjFuncArgs_t* args, int px, int py, cmGrV_t vx, cmGrV_t vy )
  517. {
  518. cmGrVExt_t vext;
  519. cmGrPExt_t pext;
  520. cmGrPlotObj_t* op = args->cbArg;
  521. // get the virtual extents of this object
  522. _cmGrPlotObjVExt( args, &vext );
  523. // convert the virtual ext's to phys ext's
  524. cmGrVExt_VtoP(args->grH,args->objH,&vext,&pext);
  525. // expand the ext's according to the off's
  526. cmGrPExtExpand(&pext,op->loffs,op->toffs,op->roffs,op->boffs);
  527. if( op->typeId == kLineGrPlId )
  528. if( cmVOR_PtToLineDistance(cmGrPExtL(&pext),cmGrPExtT(&pext),cmGrPExtR(&pext),cmGrPExtB(&pext),px,py) < 3 )
  529. return true;
  530. // check if the px,py is inside pext
  531. return cmGrPExtIsXyInside(&pext,px,py);
  532. }
  533. void _cmGrPlotFuncObjSetupDefault(cmGrObjFunc_t *f, void* arg )
  534. {
  535. f->createCbFunc = _cmGrPlotObjCreate;
  536. f->createCbArg = arg;
  537. f->destroyCbFunc = _cmGrPlotObjDestroy;
  538. f->destroyCbArg = arg;
  539. f->renderCbFunc = _cmGrPlotObjRender;
  540. f->renderCbArg = arg;
  541. f->distanceCbFunc = _cmGrPlotObjDistance;
  542. f->distanceCbArg = arg;
  543. f->eventCbFunc = _cmGrPlotObjEvent;
  544. f->eventCbArg = arg;
  545. f->vextCbFunc = _cmGrPlotObjVExt;
  546. f->vextCbArg = arg;
  547. f->isInsideCbFunc = _cmGrPlotObjIsInside;
  548. f->isInsideCbArg = arg;
  549. }
  550. //------------------------------------------------------------------------------------------------------------------
  551. // Plot Object Public Functions
  552. //------------------------------------------------------------------------------------------------------------------
  553. cmGrPlRC_t cmGrPlotObjCreate(
  554. cmGrPlH_t hh,
  555. cmGrH_t grH,
  556. cmGrPlObjH_t* hp,
  557. unsigned id,
  558. cmGrPlObjH_t parentPlObjH,
  559. cmGrPlObjH_t xAnchorPlObjH,
  560. cmGrPlObjH_t yAnchorPlObjH,
  561. cmGrPlObjTypeId_t typeId,
  562. unsigned cfgFlags,
  563. cmReal_t x,
  564. cmReal_t y,
  565. cmReal_t w,
  566. cmReal_t h,
  567. const cmChar_t* label,
  568. const cmGrVExt_t* wext )
  569. {
  570. cmGrPlRC_t rc;
  571. cmGrObjFunc_t funcs;
  572. if((rc = cmGrPlotObjDestroy(hp)) != kOkGrPlRC )
  573. return rc;
  574. cmGrPl_t* p = _cmGrPlHandleToPtr(hh);
  575. cmGrPlotObj_t* op = cmMemAllocZ(cmGrPlotObj_t,1);
  576. _cmGrPlotObjLink(p,op);
  577. _cmGrPlotFuncObjSetupDefault(&funcs,op);
  578. // setup the object
  579. op->grH = grH;
  580. op->typeId = typeId;
  581. op->cfgFlags = cfgFlags;
  582. op->stateFlags = kEnabledGrPlFl;
  583. op->label = label==NULL ?NULL : cmMemAllocStr(label);
  584. op->labelFlags = kHorzCtrJsGrFl | kVertCtrJsGrFl;
  585. op->labelAngle = 0;
  586. op->labelColor = kBlackGrId;
  587. op->grObjH = cmGrObjNullHandle;
  588. op->parent = cmGrPlotObjIsValid(parentPlObjH) ? _cmGrPlObjHandleToPtr(parentPlObjH) : NULL;
  589. op->xAnchor = cmGrPlotObjIsValid(xAnchorPlObjH) ? _cmGrPlObjHandleToPtr(xAnchorPlObjH) : NULL;
  590. op->yAnchor = cmGrPlotObjIsValid(yAnchorPlObjH) ? _cmGrPlObjHandleToPtr(yAnchorPlObjH) : NULL;
  591. op->p = p;
  592. op->fontId = kHelveticaFfGrId;
  593. op->fontSize = 12;
  594. op->fontStyle = kNormalFsGrFl;
  595. if( cmIsFlag(op->cfgFlags,kSymbolGrPlFl) )
  596. {
  597. int ww = w==0 ? kDefaultSymW : w;
  598. int hh = h==0 ? kDefaultSymH : h;
  599. op->loffs = ww/2;
  600. op->roffs = ww/2;
  601. op->toffs = hh/2;
  602. op->boffs = hh/2;
  603. w = 0;
  604. h = 0;
  605. }
  606. cmGrVExtSet(&op->vext,x,y,w,h);
  607. // set the default colors
  608. op->drawColors[kFocusPlGrId] = 0xcd853f;
  609. op->fillColors[kFocusPlGrId] = 0xdeb887;
  610. op->drawColors[kSelectPlGrId] = 0x483d8b;
  611. op->fillColors[kSelectPlGrId] = 0x8470ff;
  612. op->drawColors[kEnablePlGrId] = 0x000000;
  613. op->fillColors[kEnablePlGrId] = 0x009ff7;
  614. op->drawColors[kDisablePlGrId] = 0xbebebe;
  615. op->fillColors[kDisablePlGrId] = 0xd3d3de;
  616. unsigned grObjCfgFlags = 0;
  617. cmGrObjH_t parentGrH = op->parent == NULL ? cmGrObjNullHandle : op->parent->grObjH;
  618. // create the graphics system object - during this call a
  619. // call is made to funcs.create().
  620. if( cmGrObjCreate(grH, &op->grObjH, parentGrH, &funcs, id, grObjCfgFlags, wext ) != kOkGrRC )
  621. {
  622. rc = cmErrMsg(&p->err,kGrFailGrPlRC,"Graphic system object create failed for object (id=%i).",id);
  623. goto errLabel;
  624. }
  625. if( hp != NULL )
  626. hp->h = op;
  627. errLabel:
  628. if( rc != kOkGrPlRC )
  629. _cmGrPlotObjDelete(op);
  630. return rc;
  631. }
  632. cmGrPlRC_t cmGrPlotObjDestroy( cmGrPlObjH_t* hp )
  633. {
  634. cmGrPlRC_t rc = kOkGrPlRC;
  635. if( hp==NULL || cmGrPlotObjIsValid(*hp)==false )
  636. return kOkGrPlRC;
  637. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(*hp);
  638. if((rc = _cmGrPlotObjDelete(op)) != kOkGrPlRC )
  639. return rc;
  640. hp->h = NULL;
  641. return rc;
  642. }
  643. bool cmGrPlotObjIsValid( cmGrPlObjH_t h )
  644. { return h.h != NULL; }
  645. cmGrPlH_t cmGrPlotObjMgrHandle( cmGrPlObjH_t oh )
  646. {
  647. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  648. cmGrPlH_t grPlH;
  649. grPlH.h = op->p;
  650. return grPlH;
  651. }
  652. cmGrObjH_t cmGrPlotObjHandle( cmGrPlObjH_t oh )
  653. {
  654. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  655. return op->grObjH;
  656. }
  657. void cmGrPlotObjSetId( cmGrPlObjH_t oh, unsigned id )
  658. {
  659. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  660. cmGrObjSetId( op->grObjH, id );
  661. }
  662. void cmGrPlotObjSetUserPtr( cmGrPlObjH_t oh, void* userPtr )
  663. {
  664. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  665. op->userPtr = userPtr;
  666. }
  667. void* cmGrPlotObjUserPtr( cmGrPlObjH_t oh )
  668. {
  669. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  670. return op->userPtr;
  671. }
  672. unsigned cmGrPlotObjId( cmGrPlObjH_t oh )
  673. {
  674. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  675. return cmGrObjId(op->grObjH);
  676. }
  677. void cmGrPlotObjSetLabel( cmGrPlObjH_t oh, const cmChar_t* label )
  678. {
  679. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  680. if( label == op->label || (label != NULL && op->label!=NULL && strcmp(label,op->label)==0 ))
  681. return;
  682. cmMemPtrFree(&op->label);
  683. if( label != NULL )
  684. {
  685. assert( op->label == NULL );
  686. op->label = cmMemAllocStr(label);
  687. }
  688. }
  689. const cmChar_t* cmGrPlotObjLabel( cmGrPlObjH_t oh )
  690. {
  691. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  692. return op->label;
  693. }
  694. void cmGrPlotObjSetLabelAttr( cmGrPlObjH_t oh, unsigned flags, int angle, const cmGrColor_t color )
  695. {
  696. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  697. op->labelFlags = flags;
  698. op->labelAngle = angle;
  699. op->labelColor = color;
  700. }
  701. unsigned cmGrPlotObjLabelFlags( cmGrPlObjH_t oh )
  702. {
  703. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  704. return op->labelFlags;
  705. }
  706. int cmGrPlotObjLabelAngle( cmGrPlObjH_t oh )
  707. {
  708. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  709. return op->labelAngle;
  710. }
  711. const cmGrColor_t cmGrPlotObjLabelColor( cmGrPlObjH_t oh )
  712. {
  713. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  714. return op->labelColor;
  715. }
  716. void cmGrPlotObjSetStateFlags( cmGrPlObjH_t oh, unsigned flags )
  717. {
  718. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  719. if( cmIsFlag(flags,kVisibleGrPlFl) != _cmGrPlotObjIsVisible(op) )
  720. {
  721. if( _cmGrPlotObjCb(op, kStateChangeGrPlId, kVisibleGrPlFl ) == false )
  722. return;
  723. op->cfgFlags = cmTogFlag(op->cfgFlags,kNoDrawGrPlFl);
  724. }
  725. if( cmIsFlag(flags,kEnabledGrPlFl) != _cmGrPlotObjIsEnabled(op) )
  726. {
  727. if( _cmGrPlotObjCb(op, kStateChangeGrPlId, kEnabledGrPlFl ) == false )
  728. return;
  729. op->stateFlags = cmTogFlag(op->cfgFlags,kEnabledGrPlFl);
  730. }
  731. bool fl;
  732. if( cmIsFlag(flags,kSelectGrPlFl) != (fl=_cmGrPlotObjIsSelected(op)) )
  733. _cmGrPlotObjSetSelect(op, !fl );
  734. if( cmIsFlag(flags,kFocusGrPlFl) != (fl=_cmGrPlotObjIsFocused(op)) )
  735. if( fl )
  736. _cmGrPlotObjSetFocus(op);
  737. }
  738. unsigned cmGrPlotObjStateFlags( cmGrPlObjH_t oh )
  739. {
  740. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  741. return
  742. (_cmGrPlotObjIsEnabled(op) ? kEnabledGrPlFl : 0)
  743. | (_cmGrPlotObjIsVisible(op) ? kVisibleGrPlFl : 0)
  744. | (_cmGrPlotObjIsFocused(op) ? kFocusGrPlFl : 0)
  745. | (_cmGrPlotObjIsSelected(op) ? kSelectGrPlFl : 0);
  746. }
  747. void cmGrPlotObjSetCfgFlags( cmGrPlObjH_t oh, unsigned flags )
  748. {
  749. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  750. op->cfgFlags = flags;
  751. }
  752. void cmGrPlotObjClrCfgFlags( cmGrPlObjH_t oh, unsigned flags )
  753. {
  754. unsigned curFlags = cmGrPlotObjCfgFlags(oh);
  755. cmGrPlotObjSetCfgFlags(oh, cmClrFlag(curFlags,flags));
  756. }
  757. void cmGrPlotObjTogCfgFlags( cmGrPlObjH_t oh, unsigned flags )
  758. {
  759. unsigned curFlags = cmGrPlotObjCfgFlags(oh);
  760. cmGrPlotObjSetCfgFlags(oh, cmTogFlag(curFlags,flags));
  761. }
  762. unsigned cmGrPlotObjCfgFlags( cmGrPlObjH_t oh )
  763. {
  764. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  765. return op->cfgFlags;
  766. }
  767. cmGrPlRC_t cmGrPlotObjSetPhysExt( cmGrPlObjH_t oh, int loffs, int toffs, int roffs, int boffs )
  768. {
  769. cmGrPlRC_t rc = kOkGrPlRC;
  770. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  771. op->loffs = loffs;
  772. op->toffs = toffs;
  773. op->roffs = roffs;
  774. op->boffs = boffs;
  775. return rc;
  776. }
  777. void cmGrPlotObjPhysExt( cmGrPlObjH_t oh, int* loffs, int* toffs, int* roffs, int* boffs )
  778. {
  779. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  780. if( loffs != NULL )
  781. *loffs = op->loffs;
  782. if( toffs != NULL )
  783. *toffs = op->toffs;
  784. if( roffs != NULL )
  785. *roffs = op->roffs;
  786. if( boffs != NULL )
  787. *boffs = op->boffs;
  788. }
  789. void cmGrPlotObjVExt( cmGrPlObjH_t oh, cmGrVExt_t* vext )
  790. {
  791. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  792. _cmGrPlotObjGetVExt(op, vext);
  793. }
  794. void cmGrPlotObjSetFontFamily( cmGrPlObjH_t oh, unsigned id )
  795. {
  796. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  797. op->fontId = id;
  798. }
  799. unsigned cmGrPlotObjFontFamily( cmGrPlObjH_t oh )
  800. {
  801. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  802. return op->fontId;
  803. }
  804. void cmGrPlotObjSetFontStyle( cmGrPlObjH_t oh, unsigned style )
  805. {
  806. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  807. op->fontStyle = style;
  808. }
  809. unsigned cmGrPlotObjFontStyle( cmGrPlObjH_t oh )
  810. {
  811. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  812. return op->fontStyle;
  813. }
  814. void cmGrPlotObjSetFontSize( cmGrPlObjH_t oh, unsigned size )
  815. {
  816. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  817. op->fontSize = size;
  818. }
  819. unsigned cmGrPlotObjFontSize( cmGrPlObjH_t oh )
  820. {
  821. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  822. return op->fontSize;
  823. }
  824. void cmGrPlotObjSetLineColor( cmGrPlObjH_t oh, cmGrPlStateId_t id, const cmGrColor_t c )
  825. {
  826. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  827. assert( id < kMaxPlGrId );
  828. op->drawColors[ id ] = c;
  829. }
  830. const cmGrColor_t cmGrPlotObjLineColor( cmGrPlObjH_t oh, cmGrPlStateId_t id )
  831. {
  832. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  833. assert( id < kMaxPlGrId );
  834. return op->drawColors[id];
  835. }
  836. const cmGrColor_t cmGrPlotObjCurLineColor( cmGrPlObjH_t h )
  837. {
  838. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(h);
  839. return _cmGrPlotColor(op,op->drawColors);
  840. }
  841. void cmGrPlotObjSetFillColor( cmGrPlObjH_t oh, cmGrPlStateId_t id, const cmGrColor_t c )
  842. {
  843. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  844. assert( id < kMaxPlGrId );
  845. op->fillColors[ id ] = c;
  846. }
  847. const cmGrColor_t cmGrPlotObjFillColor( cmGrPlObjH_t oh, cmGrPlStateId_t id )
  848. {
  849. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(oh);
  850. assert( id < kMaxPlGrId );
  851. return op->fillColors[id];
  852. }
  853. const cmGrColor_t cmGrPlotObjCurFillColor( cmGrPlObjH_t h )
  854. {
  855. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(h);
  856. return _cmGrPlotColor(op,op->fillColors);
  857. }
  858. void cmGrPlotObjSetCb( cmGrPlObjH_t h, cmGrPlotCbFunc_t func, void* arg )
  859. {
  860. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(h);
  861. op->cbFunc = func;
  862. op->cbArg = arg;
  863. }
  864. cmGrPlotCbFunc_t cmGrPlotObjCbFunc( cmGrPlObjH_t h )
  865. {
  866. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(h);
  867. return op->cbFunc;
  868. }
  869. void* cmGrPlotObjCbArg( cmGrPlObjH_t h )
  870. {
  871. cmGrPlotObj_t* op = _cmGrPlObjHandleToPtr(h);
  872. return op->cbArg;
  873. }
  874. void cmGrPlotObjDrawAbove( cmGrPlObjH_t bH, cmGrPlObjH_t aH )
  875. {
  876. cmGrPlotObj_t* bop = _cmGrPlObjHandleToPtr(bH);
  877. cmGrPlotObj_t* aop = _cmGrPlObjHandleToPtr(aH);
  878. cmGrObjDrawAbove(bop->grObjH,aop->grObjH);
  879. }
  880. //------------------------------------------------------------------------------------------------------------------
  881. // Plot Object Manager Functions
  882. //------------------------------------------------------------------------------------------------------------------
  883. cmGrPlRC_t cmGrPlotCreate( cmCtx_t* ctx, cmGrPlH_t* hp )
  884. {
  885. cmGrPlRC_t rc;
  886. if((rc = cmGrPlotDestroy(hp)) != kOkGrPlRC )
  887. return rc;
  888. cmGrPl_t* p = cmMemAllocZ(cmGrPl_t,1);
  889. cmErrSetup(&p->err,&ctx->rpt,"cmGrPlot");
  890. p->ctx = ctx;
  891. hp->h = p;
  892. if( rc != kOkGrPlRC )
  893. _cmGrPlotDestroy(p);
  894. return rc;
  895. }
  896. cmGrPlRC_t cmGrPlotDestroy( cmGrPlH_t* hp )
  897. {
  898. cmGrPlRC_t rc;
  899. if( hp==NULL || cmGrPlotIsValid(*hp) == false )
  900. return kOkGrPlRC;
  901. cmGrPl_t* p = _cmGrPlHandleToPtr(*hp);
  902. if((rc = _cmGrPlotDestroy(p)) != kOkGrPlRC )
  903. return rc;
  904. hp->h = NULL;
  905. return rc;
  906. }
  907. bool cmGrPlotIsValid( cmGrPlH_t h )
  908. { return h.h != NULL; }
  909. cmGrPlRC_t cmGrPlotClear( cmGrPlH_t h )
  910. {
  911. cmGrPl_t* p = _cmGrPlHandleToPtr(h);
  912. return _cmGrPlotClear(p);
  913. }
  914. cmErr_t* cmGrPlotErr( cmGrPlH_t h )
  915. {
  916. cmGrPl_t* p = _cmGrPlHandleToPtr(h);
  917. return &p->err;
  918. }
  919. cmRpt_t* cmGrPlotRpt( cmGrPlH_t h )
  920. {
  921. cmGrPl_t* p = _cmGrPlHandleToPtr(h);
  922. return p->err.rpt;
  923. }
  924. cmGrPlObjH_t cmGrPlotObjectIdToHandle( cmGrPlH_t h, unsigned id )
  925. {
  926. cmGrPl_t* p = _cmGrPlHandleToPtr(h);
  927. cmGrPlObjH_t oh = cmGrPlObjNullHandle;
  928. cmGrPlotObj_t* op = p->list;
  929. for(; op!=NULL; op=op->next)
  930. if( cmGrObjId(op->grObjH) == id )
  931. {
  932. oh.h = op;
  933. break;
  934. }
  935. return oh;
  936. }
  937. unsigned cmGrPlotObjectCount( cmGrPlH_t h )
  938. {
  939. cmGrPl_t* p = _cmGrPlHandleToPtr(h);
  940. cmGrPlotObj_t* op = p->list;
  941. unsigned n = 0;
  942. for(; op!=NULL; ++n )
  943. op=op->next;
  944. return n;
  945. }
  946. cmGrPlObjH_t cmGrPlotObjectIndexToHandle( cmGrPlH_t h, unsigned index )
  947. {
  948. cmGrPl_t* p = _cmGrPlHandleToPtr(h);
  949. cmGrPlotObj_t* op = p->list;
  950. unsigned i = 0;
  951. cmGrPlObjH_t oh = cmGrPlObjNullHandle;
  952. for(; i<index && op!=NULL; ++i)
  953. op = op->next;
  954. if( op != NULL )
  955. oh.h = op;
  956. return oh;
  957. }
  958. void cmGrPlotKeyEvent( cmGrPlH_t h, cmGrH_t grH, unsigned eventFlags, cmGrKeyCodeId_t keycode )
  959. {
  960. assert( cmIsFlag(eventFlags,kKeyDnGrFl | kKeyUpGrFl));
  961. cmGrPl_t* p = _cmGrPlHandleToPtr(h);
  962. if( p->fop != NULL && cmHandlesAreEqual(p->fop->grH,grH) )
  963. {
  964. cmGrObjFuncArgs_t a;
  965. memset(&a,0,sizeof(a));
  966. a.cbArg = p->fop;
  967. a.ctx = p->ctx;
  968. a.grH = grH;
  969. a.objH = p->fop->grObjH;
  970. _cmGrPlotObjEvent(&a, eventFlags, keycode, 0, 0 );
  971. }
  972. }