libcm is a C development framework with an emphasis on audio signal processing applications.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

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