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

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