libcm is a C development framework with an emphasis on audio signal processing applications.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

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. }