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

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