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

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