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 33KB

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