PageRenderTime 59ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/ATF2/control-software/epics-3.14.10/extensions/src/edm/doc/edmBoxComplete.cc

http://atf2flightsim.googlecode.com/
C++ | 2091 lines | 1407 code | 531 blank | 153 comment | 218 complexity | 0c332fc11eac00f7d882d71948138f67 MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-2.0, IPL-1.0, BSD-3-Clause
  1. // object: 2ed7d2e8-f439-11d2-8fed-00104b8742df
  2. // lib: 3014b6ee-f439-11d2-ad99-00104b8742df
  3. // define SMARTDRAW if the widget may be part of an overlapping
  4. // stack of widgets
  5. //#define SMARTDRAW 1
  6. #define __edmBoxComplete_cc 1
  7. #include "edmBoxComplete.h"
  8. //---------------------------------------------------------------------------
  9. // default constructor
  10. edmBoxClass::edmBoxClass ( void ) {
  11. // Allocate space for the component name and init
  12. name = new char[strlen("2ed7d2e8_f439_11d2_8fed_00104b8742df")+1];
  13. strcpy( name, "2ed7d2e8_f439_11d2_8fed_00104b8742df" );
  14. // Init class member data
  15. editBuf = NULL;
  16. pvExists = 0;
  17. active = 0;
  18. activeMode = 0;
  19. fill = 0;
  20. lineColorMode = COLORMODE_STATIC;
  21. fillColorMode = COLORMODE_STATIC;
  22. lineWidth = 1;
  23. lineStyle = LineSolid;
  24. readMin = 0;
  25. readMax = 10;
  26. precision = 1;
  27. efReadMin.setNull(1);
  28. efReadMax.setNull(1);
  29. strcpy( fontTag, "" );
  30. strcpy( label, "" );
  31. fs = NULL;
  32. labelX = 0;
  33. labelY = 0;
  34. alignment = XmALIGNMENT_BEGINNING;
  35. unconnectedTimer = 0;
  36. // This makes the blinking color magic work
  37. setBlinkFunction( (void *) doBlink );
  38. }
  39. //---------------------------------------------------------------------------
  40. // copy constructor
  41. edmBoxClass::edmBoxClass
  42. ( const edmBoxClass *source ) {
  43. activeGraphicClass *ago = (activeGraphicClass *) this;
  44. // clone base class data
  45. ago->clone( (activeGraphicClass *) source );
  46. // Allocate space for the component name and init
  47. name = new char[strlen("2ed7d2e8_f439_11d2_8fed_00104b8742df")+1];
  48. strcpy( name, "2ed7d2e8_f439_11d2_8fed_00104b8742df" );
  49. editBuf = NULL;
  50. // copy edit mode data and initialize execute mode data
  51. lineColor.copy(source->lineColor);
  52. fillColor.copy(source->fillColor);
  53. lineCb = source->lineCb;
  54. fillCb = source->fillCb;
  55. fill = source->fill;
  56. lineColorMode = source->lineColorMode;
  57. fillColorMode = source->fillColorMode;
  58. strncpy( fontTag, source->fontTag, 63 );
  59. fontTag[63] = 0;
  60. strncpy( label, source->label, 63 );
  61. label[63] = 0;
  62. fs = actWin->fi->getXFontStruct( fontTag );
  63. stringLength = source->stringLength;
  64. fontAscent = source->fontAscent;
  65. fontDescent = source->fontDescent;
  66. fontHeight = source->fontHeight;
  67. stringWidth = source->stringWidth;
  68. labelX = source->labelX;
  69. labelY = source->labelY;
  70. alignment = source->alignment;
  71. lineWidth = source->lineWidth;
  72. lineStyle = source->lineStyle;
  73. pvExpStr.setRaw( source->pvExpStr.rawString );
  74. pvExists = 0;
  75. active = 0;
  76. activeMode = 0;
  77. readMin = source->readMin;
  78. readMax = source->readMax;
  79. precision = source->precision;
  80. efReadMin = source->efReadMin;
  81. efReadMax = source->efReadMax;
  82. efPrecision = source->efPrecision;
  83. unconnectedTimer = 0;
  84. // This makes the blinking color magic work
  85. setBlinkFunction( (void *) doBlink );
  86. }
  87. //---------------------------------------------------------------------------
  88. // Destructor
  89. edmBoxClass::~edmBoxClass ( void ) {
  90. // deallocate dynamic memory
  91. if ( name ) delete[] name;
  92. if ( unconnectedTimer ) {
  93. XtRemoveTimeOut( unconnectedTimer );
  94. unconnectedTimer = 0;
  95. }
  96. if ( editBuf ) delete editBuf;
  97. // disable blink function
  98. updateBlink( 0 );
  99. }
  100. //---------------------------------------------------------------------------
  101. char *edmBoxClass::objName ( void ) {
  102. // Return component name
  103. return name;
  104. }
  105. //---------------------------------------------------------------------------
  106. int edmBoxClass::createInteractive (
  107. activeWindowClass *aw_obj,
  108. int _x,
  109. int _y,
  110. int _w,
  111. int _h ) {
  112. // All widgets must copy active window object
  113. actWin = (activeWindowClass *) aw_obj;
  114. // Initialize edit mode data so an initial edit mode image
  115. // may be drawn
  116. x = _x;
  117. y = _y;
  118. w = _w;
  119. h = _h;
  120. lineColor.setColorIndex( actWin->defaultFg1Color, actWin->ci );
  121. fillColor.setColorIndex( actWin->defaultBgColor, actWin->ci );
  122. strcpy( fontTag, actWin->defaultCtlFontTag );
  123. alignment = actWin->defaultCtlAlignment;
  124. fs = actWin->fi->getXFontStruct( fontTag );
  125. updateFont( " ", fontTag, &fs,
  126. &fontAscent, &fontDescent, &fontHeight,
  127. &stringWidth );
  128. boxH = h - fontHeight - fontHeight;
  129. if ( boxH < 5 ) {
  130. boxH = 5;
  131. h = boxH + fontHeight + fontHeight;
  132. sboxH = h;
  133. }
  134. boxY = y + fontHeight;
  135. if ( w < 5 ) {
  136. w = 5;
  137. sboxW = 5;
  138. }
  139. // Draw initial edit mode image
  140. this->draw();
  141. // create and popup the property dialog for a newly created object
  142. this->editCreate();
  143. return 1;
  144. }
  145. //---------------------------------------------------------------------------
  146. int edmBoxClass::editCreate ( void ) {
  147. this->genericEdit();
  148. // Map dialog box form buttons to callbacks
  149. ef.finished( editOk, editApply, editCancelDelete, this );
  150. // Required by display engine
  151. actWin->currentEf = NULL;
  152. // Pop-up the dialog box
  153. ef.popup();
  154. return 1;
  155. }
  156. //---------------------------------------------------------------------------
  157. int edmBoxClass::edit ( void ) {
  158. this->genericEdit();
  159. // Map dialog box form buttons to callbacks
  160. ef.finished( editOk, editApply, editCancel, this );
  161. // Required by display engine
  162. actWin->currentEf = &ef;
  163. // Pop-up the dialog box
  164. ef.popup();
  165. return 1;
  166. }
  167. //---------------------------------------------------------------------------
  168. int edmBoxClass::genericEdit ( void ) {
  169. // Create the property dialog box so that user may edit widget attributes
  170. char title[32], *ptr;
  171. // Allocate the edit buffer, this holds values until the OK or Cancel button
  172. // is pressed
  173. if ( !editBuf ) {
  174. editBuf = new editBufType;
  175. }
  176. // Build property dialog title - this will become "Box Properties"
  177. // Get the widget nickname from the component name
  178. ptr = actWin->obj.getNameFromClass( "2ed7d2e8_f439_11d2_8fed_00104b8742df" );
  179. if ( ptr )
  180. strncpy( title, ptr, 31 );
  181. else
  182. strncpy( title, edmBoxComplete_str2, 31 );
  183. Strncat( title, edmBoxComplete_str3, 31 );
  184. // Copy current property values into edit buffer; on OK or Apply
  185. // edit buffer values will be copied back into current property values
  186. editBuf->bufX = x;
  187. editBuf->bufY = y;
  188. editBuf->bufW = w;
  189. editBuf->bufH = h;
  190. editBuf->bufLineColor = lineColor.pixelIndex();
  191. editBuf->bufLineColorMode = lineColorMode;
  192. editBuf->bufFillColor = fillColor.pixelIndex();
  193. editBuf->bufFillColorMode = fillColorMode;
  194. editBuf->bufFill = fill;
  195. editBuf->bufLineWidth = lineWidth;
  196. editBuf->bufLineStyle = lineStyle;
  197. if ( pvExpStr.getRaw() )
  198. strncpy( editBuf->bufPvName, pvExpStr.getRaw(), PV_Factory::MAX_PV_NAME );
  199. else
  200. strcpy( editBuf->bufPvName, "" );
  201. editBuf->bufEfReadMin = efReadMin;
  202. editBuf->bufEfReadMax = efReadMax;
  203. editBuf->bufEfPrecision = efPrecision;
  204. strncpy( editBuf->bufLabel, label, 63 );
  205. editBuf->bufLabel[63] = 0;
  206. // Create the property dialog data entry form
  207. ef.create( actWin->top, actWin->appCtx->ci.getColorMap(),
  208. &actWin->appCtx->entryFormX,
  209. &actWin->appCtx->entryFormY, &actWin->appCtx->entryFormW,
  210. &actWin->appCtx->entryFormH, &actWin->appCtx->largestH,
  211. title, NULL, NULL, NULL );
  212. // Add fields to the form
  213. ef.addTextField( edmBoxComplete_str4, 30, &editBuf->bufX );
  214. ef.addTextField( edmBoxComplete_str5, 30, &editBuf->bufY );
  215. ef.addTextField( edmBoxComplete_str6, 30, &editBuf->bufW );
  216. ef.addTextField( edmBoxComplete_str7, 30, &editBuf->bufH );
  217. ef.addOption( edmBoxComplete_str8, edmBoxComplete_str19,
  218. &editBuf->bufLineWidth );
  219. ef.addOption( edmBoxComplete_str9, edmBoxComplete_str20,
  220. &editBuf->bufLineStyle );
  221. ef.addColorButton( edmBoxComplete_str10, actWin->ci, &lineCb,
  222. &editBuf->bufLineColor );
  223. ef.addToggle( edmBoxComplete_str11, &editBuf->bufLineColorMode );
  224. ef.addToggle( edmBoxComplete_str12, &editBuf->bufFill );
  225. ef.addColorButton( edmBoxComplete_str13, actWin->ci, &fillCb,
  226. &editBuf->bufFillColor );
  227. ef.addToggle( edmBoxComplete_str11, &editBuf->bufFillColorMode );
  228. ef.addTextField( edmBoxComplete_str14, 30, editBuf->bufPvName,
  229. PV_Factory::MAX_PV_NAME );
  230. ef.addTextField( edmBoxComplete_str15, 30, &editBuf->bufEfReadMin );
  231. ef.addTextField( edmBoxComplete_str16, 30, &editBuf->bufEfReadMax );
  232. ef.addTextField( edmBoxComplete_str23, 30, &editBuf->bufEfPrecision );
  233. ef.addFontMenu( edmBoxComplete_str17, actWin->fi, &fm, fontTag );
  234. fm.setFontAlignment( alignment );
  235. ef.addTextField( edmBoxComplete_str18, 30, editBuf->bufLabel, 63 );
  236. return 1;
  237. }
  238. //---------------------------------------------------------------------------
  239. // called by editApply and editOK
  240. void edmBoxClass::editUpdate (
  241. Widget w,
  242. XtPointer client,
  243. XtPointer call )
  244. {
  245. edmBoxClass *ebo = (edmBoxClass *) client;
  246. // Widget data has changed
  247. ebo->actWin->setChanged();
  248. // All widgets must include next two lines
  249. ebo->eraseSelectBoxCorners();
  250. ebo->erase();
  251. // Copy edit buffer into current property values
  252. ebo->lineColorMode = ebo->editBuf->bufLineColorMode;
  253. if ( ebo->lineColorMode == COLORMODE_ALARM )
  254. ebo->lineColor.setAlarmSensitive();
  255. else
  256. ebo->lineColor.setAlarmInsensitive();
  257. ebo->lineColor.setColorIndex( ebo->editBuf->bufLineColor, ebo->actWin->ci );
  258. ebo->fill = ebo->editBuf->bufFill;
  259. ebo->fillColorMode = ebo->editBuf->bufFillColorMode;
  260. if ( ebo->fillColorMode == COLORMODE_ALARM )
  261. ebo->fillColor.setAlarmSensitive();
  262. else
  263. ebo->fillColor.setAlarmInsensitive();
  264. ebo->fillColor.setColorIndex( ebo->editBuf->bufFillColor, ebo->actWin->ci );
  265. ebo->lineWidth = ebo->editBuf->bufLineWidth;
  266. if ( ebo->editBuf->bufLineStyle == 0 )
  267. ebo->lineStyle = LineSolid;
  268. else if ( ebo->editBuf->bufLineStyle == 1 )
  269. ebo->lineStyle = LineOnOffDash;
  270. ebo->pvExpStr.setRaw( ebo->editBuf->bufPvName );
  271. ebo->efReadMin = ebo->editBuf->bufEfReadMin;
  272. ebo->efReadMax = ebo->editBuf->bufEfReadMax;
  273. ebo->efPrecision = ebo->editBuf->bufEfPrecision;
  274. if ( ebo->efReadMin.isNull() ) {
  275. ebo->readMin = 0;
  276. }
  277. else{
  278. ebo->readMin = ebo->efReadMin.value();
  279. }
  280. if ( ebo->efReadMax.isNull() ) {
  281. ebo->readMax = 10;
  282. }
  283. else{
  284. ebo->readMax = ebo->efReadMax.value();
  285. }
  286. if ( ( ebo->efPrecision.isNull() ) ) {
  287. ebo->precision = 1;
  288. }
  289. else{
  290. ebo->precision = ebo->efPrecision.value();
  291. }
  292. strncpy( ebo->fontTag, ebo->fm.currentFontTag(), 63 );
  293. ebo->fontTag[63] = 0;
  294. ebo->actWin->fi->loadFontTag( ebo->fontTag );
  295. ebo->alignment = ebo->fm.currentFontAlignment();
  296. ebo->fs = ebo->actWin->fi->getXFontStruct( ebo->fontTag );
  297. strncpy( ebo->label, ebo->editBuf->bufLabel, 63 );
  298. ebo->label[63] = 0;
  299. ebo->stringLength = strlen( ebo->label );
  300. ebo->updateFont( ebo->label, ebo->fontTag, &ebo->fs,
  301. &ebo->fontAscent, &ebo->fontDescent, &ebo->fontHeight,
  302. &ebo->stringWidth );
  303. // copy into object dimensions and select box dimensions
  304. ebo->x = ebo->editBuf->bufX;
  305. ebo->sboxX = ebo->editBuf->bufX;
  306. ebo->y = ebo->editBuf->bufY;
  307. ebo->sboxY = ebo->editBuf->bufY;
  308. ebo->w = ebo->editBuf->bufW;
  309. ebo->sboxW = ebo->editBuf->bufW;
  310. ebo->h = ebo->editBuf->bufH;
  311. ebo->sboxH = ebo->editBuf->bufH;
  312. // Check values and do a few calculations
  313. if ( ebo->w < 5 ) {
  314. ebo->w = 5;
  315. ebo->sboxW = ebo->w;
  316. }
  317. ebo->boxH = ebo->h - ebo->fontHeight - ebo->fontHeight;
  318. if ( ebo->boxH < 5 ) {
  319. ebo->boxH = 5;
  320. ebo->h = ebo->boxH + ebo->fontHeight + ebo->fontHeight;
  321. ebo->sboxH = ebo->h;
  322. }
  323. ebo->boxY = ebo->y + ebo->fontHeight;
  324. if ( ebo->readMax > ebo->readMin ) {
  325. ebo->factorW = (double) ( ebo->w - 2 ) / ( ebo->readMax - ebo->readMin );
  326. ebo->factorH = (double) ebo->boxH / ( ebo->readMax - ebo->readMin );
  327. }
  328. else {
  329. ebo->factorW = 1;
  330. ebo->factorH = 1;
  331. }
  332. ebo->centerX = ebo->x + (int) ( ebo->w * 0.5 + 0.5 );
  333. ebo->centerY = ebo->boxY + (int) ( ebo->boxH * 0.5 + 0.5 );
  334. // updateDimensions should be called whenever the widget size
  335. // or text fonts might have changed
  336. ebo->updateDimensions();
  337. }
  338. //---------------------------------------------------------------------------
  339. // X Windows callback function for the apply button on the property dialog
  340. void edmBoxClass::editApply (
  341. Widget w,
  342. XtPointer client,
  343. XtPointer call )
  344. {
  345. edmBoxClass *ebo = (edmBoxClass *) client;
  346. edmBoxClass::editUpdate( w, client, call );
  347. ebo->refresh( ebo );
  348. }
  349. //---------------------------------------------------------------------------
  350. // X Windows callback function for the OK button on the property dialog
  351. void edmBoxClass::editOk (
  352. Widget w,
  353. XtPointer client,
  354. XtPointer call )
  355. {
  356. edmBoxClass *ebo = (edmBoxClass *) client;
  357. edmBoxClass::editUpdate( w, client, call );
  358. delete ebo->editBuf;
  359. ebo->editBuf = NULL;
  360. ebo->ef.popdown();
  361. ebo->operationComplete();
  362. }
  363. //---------------------------------------------------------------------------
  364. // X Windows callback function for the cancel button on the property dialog
  365. void edmBoxClass::editCancel (
  366. Widget w,
  367. XtPointer client,
  368. XtPointer call )
  369. {
  370. edmBoxClass *ebo = (edmBoxClass *) client;
  371. delete ebo->editBuf;
  372. ebo->editBuf = NULL;
  373. ebo->ef.popdown();
  374. ebo->operationCancel();
  375. }
  376. //---------------------------------------------------------------------------
  377. // X Windows callback function for the cancel button on the property dialog
  378. // when the object is being created. If user cancels edit, object creation
  379. // is being canceled thus deleteRequest must be set.
  380. void edmBoxClass::editCancelDelete (
  381. Widget w,
  382. XtPointer client,
  383. XtPointer call )
  384. {
  385. edmBoxClass *ebo = (edmBoxClass *) client;
  386. delete ebo->editBuf;
  387. ebo->editBuf = NULL;
  388. ebo->erase();
  389. ebo->deleteRequest = 1;
  390. ebo->ef.popdown();
  391. ebo->operationCancel();
  392. ebo->drawAll();
  393. }
  394. //---------------------------------------------------------------------------
  395. int edmBoxClass::createFromFile (
  396. FILE *f,
  397. char *name,
  398. activeWindowClass *_actWin )
  399. {
  400. // Read widget properties from file
  401. int major, minor, release, stat;
  402. tagClass tag;
  403. int zero = 0;
  404. int one = 1;
  405. static char *emptyStr = "";
  406. int solid = LineSolid;
  407. static char *styleEnumStr[2] = {
  408. "solid",
  409. "dash"
  410. };
  411. static int styleEnum[2] = {
  412. LineSolid,
  413. LineOnOffDash
  414. };
  415. static int left = XmALIGNMENT_BEGINNING;
  416. static char *alignEnumStr[3] = {
  417. "left",
  418. "center",
  419. "right"
  420. };
  421. static int alignEnum[3] = {
  422. XmALIGNMENT_BEGINNING,
  423. XmALIGNMENT_CENTER,
  424. XmALIGNMENT_END
  425. };
  426. this->actWin = _actWin;
  427. tag.init();
  428. tag.loadR( "beginObjectProperties" );
  429. tag.loadR( "major", &major );
  430. tag.loadR( "minor", &minor );
  431. tag.loadR( "release", &release );
  432. tag.loadR( "x", &x );
  433. tag.loadR( "y", &y );
  434. tag.loadR( "w", &w );
  435. tag.loadR( "h", &h );
  436. tag.loadR( "controlPv", &pvExpStr, emptyStr );
  437. tag.loadR( "lineColor", actWin->ci, &lineColor );
  438. tag.loadR( "lineAlarm", &lineColorMode, &zero );
  439. tag.loadR( "fill", &fill, &zero );
  440. tag.loadR( "fillColor", actWin->ci, &fillColor );
  441. tag.loadR( "fillAlarm", &fillColorMode, &zero );
  442. tag.loadR( "lineWidth", &lineWidth, &one );
  443. tag.loadR( "lineStyle", 2, styleEnumStr, styleEnum, &lineStyle, &solid );
  444. tag.loadR( "min", &efReadMin );
  445. tag.loadR( "max", &efReadMax );
  446. tag.loadR( "precision", &efPrecision );
  447. tag.loadR( "font", 63, fontTag );
  448. tag.loadR( "fontAlign", 3, alignEnumStr, alignEnum, &alignment, &left );
  449. tag.loadR( "label", 63, label, emptyStr );
  450. tag.loadR( "endObjectProperties" );
  451. stat = tag.readTags( f, "endObjectProperties" );
  452. if ( !( stat & 1 ) ) {
  453. actWin->appCtx->postMessage( tag.errMsg() );
  454. }
  455. // If new object version is greater than current version then abort
  456. if ( major > MAJOR_VERSION ) {
  457. postIncompatable();
  458. return 0;
  459. }
  460. // If new object version is "old file format" then abort
  461. if ( major < 4 ) {
  462. postIncompatable();
  463. return 0;
  464. }
  465. // initSelectBox must always be call after getting x,y,w,h
  466. this->initSelectBox(); // call after getting x,y,w,h
  467. // Process pv alarm information
  468. if ( lineColorMode == COLORMODE_ALARM )
  469. lineColor.setAlarmSensitive();
  470. else
  471. lineColor.setAlarmInsensitive();
  472. if ( fillColorMode == COLORMODE_ALARM )
  473. fillColor.setAlarmSensitive();
  474. else
  475. fillColor.setAlarmInsensitive();
  476. // Process min, max, precision
  477. if ( efReadMin.isNull() ) {
  478. readMin = 0;
  479. }
  480. else{
  481. readMin = efReadMin.value();
  482. }
  483. if ( efReadMax.isNull() ) {
  484. readMax = 10;
  485. }
  486. else{
  487. readMax = efReadMax.value();
  488. }
  489. if ( ( efPrecision.isNull() ) ) {
  490. precision = 1;
  491. }
  492. else{
  493. precision = efPrecision.value();
  494. }
  495. // Make fonts available to X Server, get font struct and font metrics
  496. actWin->fi->loadFontTag( fontTag );
  497. fs = actWin->fi->getXFontStruct( fontTag );
  498. stringLength = strlen( label );
  499. updateFont( label, fontTag, &fs,
  500. &fontAscent, &fontDescent, &fontHeight,
  501. &stringWidth );
  502. // updateDimensions should be called whenever the widget size
  503. // or text fonts might have changed
  504. updateDimensions();
  505. // Do various calculations
  506. if ( readMax > readMin ) {
  507. factorW = (double) ( w - 2 ) / ( readMax - readMin );
  508. factorH = (double) boxH / ( readMax - readMin );
  509. }
  510. else {
  511. factorW = 1;
  512. factorH = 1;
  513. }
  514. centerX = x + (int) ( w * 0.5 + 0.5 );
  515. centerY = boxY + (int) ( boxH * 0.5 + 0.5 );
  516. curValue = 0;
  517. return stat;
  518. }
  519. //---------------------------------------------------------------------------
  520. int edmBoxClass::old_createFromFile (
  521. FILE *f,
  522. char *name,
  523. activeWindowClass *_actWin )
  524. {
  525. int r, g, b, index;
  526. int major, minor, release;
  527. unsigned int pixel;
  528. char oneName[PV_Factory::MAX_PV_NAME+1];
  529. this->actWin = _actWin;
  530. fscanf( f, "%d %d %d\n", &major, &minor, &release ); actWin->incLine();
  531. if ( major > MAJOR_VERSION ) {
  532. postIncompatable();
  533. return 0;
  534. }
  535. fscanf( f, "%d\n", &x ); actWin->incLine();
  536. fscanf( f, "%d\n", &y ); actWin->incLine();
  537. fscanf( f, "%d\n", &w ); actWin->incLine();
  538. fscanf( f, "%d\n", &h ); actWin->incLine();
  539. this->initSelectBox(); // call after getting x,y,w,h
  540. if ( ( major > 2 ) || ( ( major == 2 ) && ( minor > 0 ) ) ) {
  541. actWin->ci->readColorIndex( f, &index );
  542. actWin->incLine(); actWin->incLine();
  543. lineColor.setColorIndex( index, actWin->ci );
  544. fscanf( f, "%d\n", &lineColorMode ); actWin->incLine();
  545. if ( lineColorMode == COLORMODE_ALARM )
  546. lineColor.setAlarmSensitive();
  547. else
  548. lineColor.setAlarmInsensitive();
  549. fscanf( f, "%d\n", &fill ); actWin->incLine();
  550. actWin->ci->readColorIndex( f, &index );
  551. actWin->incLine(); actWin->incLine();
  552. fillColor.setColorIndex( index, actWin->ci );
  553. }
  554. else if ( major > 1 ) {
  555. fscanf( f, "%d\n", &index ); actWin->incLine();
  556. lineColor.setColorIndex( index, actWin->ci );
  557. fscanf( f, "%d\n", &lineColorMode ); actWin->incLine();
  558. if ( lineColorMode == COLORMODE_ALARM )
  559. lineColor.setAlarmSensitive();
  560. else
  561. lineColor.setAlarmInsensitive();
  562. fscanf( f, "%d\n", &fill ); actWin->incLine();
  563. fscanf( f, "%d\n", &index ); actWin->incLine();
  564. fillColor.setColorIndex( index, actWin->ci );
  565. }
  566. else {
  567. fscanf( f, "%d %d %d\n", &r, &g, &b ); actWin->incLine();
  568. actWin->ci->setRGB( r, g, b, &pixel );
  569. index = actWin->ci->pixIndex( pixel );
  570. lineColor.setColorIndex( index, actWin->ci );
  571. fscanf( f, "%d\n", &lineColorMode ); actWin->incLine();
  572. if ( lineColorMode == COLORMODE_ALARM )
  573. lineColor.setAlarmSensitive();
  574. else
  575. lineColor.setAlarmInsensitive();
  576. fscanf( f, "%d\n", &fill ); actWin->incLine();
  577. fscanf( f, "%d %d %d\n", &r, &g, &b ); actWin->incLine();
  578. actWin->ci->setRGB( r, g, b, &pixel );
  579. index = actWin->ci->pixIndex( pixel );
  580. fillColor.setColorIndex( index, actWin->ci );
  581. }
  582. fscanf( f, "%d\n", &fillColorMode ); actWin->incLine();
  583. if ( fillColorMode == COLORMODE_ALARM )
  584. fillColor.setAlarmSensitive();
  585. else
  586. fillColor.setAlarmInsensitive();
  587. readStringFromFile( oneName, PV_Factory::MAX_PV_NAME+1, f );
  588. actWin->incLine();
  589. pvExpStr.setRaw( oneName );
  590. fscanf( f, "%d\n", &lineWidth ); actWin->incLine();
  591. fscanf( f, "%d\n", &lineStyle ); actWin->incLine();
  592. efReadMin.read( f ); actWin->incLine();
  593. efReadMax.read( f ); actWin->incLine();
  594. if ( ( efReadMin.isNull() ) && ( efReadMax.isNull() ) ) {
  595. readMin = 0;
  596. readMax = 10;
  597. }
  598. else{
  599. readMin = efReadMin.value();
  600. readMax = efReadMax.value();
  601. }
  602. if ( ( major > 1 ) || ( minor > 3 ) ) {
  603. readStringFromFile( fontTag, 63+1, f ); actWin->incLine();
  604. readStringFromFile( label, 63+1, f ); actWin->incLine();
  605. actWin->fi->loadFontTag( fontTag );
  606. fs = actWin->fi->getXFontStruct( fontTag );
  607. stringLength = strlen( label );
  608. updateFont( label, fontTag, &fs,
  609. &fontAscent, &fontDescent, &fontHeight,
  610. &stringWidth );
  611. }
  612. else {
  613. strcpy( label, "" );
  614. stringLength = 0;
  615. strcpy( fontTag, actWin->defaultFontTag );
  616. fs = actWin->fi->getXFontStruct( fontTag );
  617. updateFont( label, fontTag, &fs,
  618. &fontAscent, &fontDescent, &fontHeight,
  619. &stringWidth );
  620. }
  621. if ( ( major > 1 ) || ( minor > 4 ) ) {
  622. fscanf( f, "%d\n", &alignment ); actWin->incLine();
  623. }
  624. else {
  625. alignment = XmALIGNMENT_BEGINNING;
  626. }
  627. if ( alignment == XmALIGNMENT_BEGINNING )
  628. labelX = x;
  629. else if ( alignment == XmALIGNMENT_CENTER )
  630. labelX = x + w/2 - stringWidth/2;
  631. else if ( alignment == XmALIGNMENT_END )
  632. labelX = x + w - stringWidth;
  633. labelY = y + h;
  634. boxH = h - fontHeight - fontHeight;
  635. if ( boxH < 5 ) {
  636. boxH = 5;
  637. h = boxH + fontHeight + fontHeight;
  638. }
  639. boxY = y + fontHeight;
  640. if ( readMax > readMin ) {
  641. factorW = (double) ( w - 2 ) / ( readMax - readMin );
  642. factorH = (double) boxH / ( readMax - readMin );
  643. }
  644. else {
  645. factorW = 1;
  646. factorH = 1;
  647. }
  648. centerX = x + (int) ( w * 0.5 + 0.5 );
  649. centerY = boxY + (int) ( boxH * 0.5 + 0.5 );
  650. curValue = 0;
  651. return 1;
  652. }
  653. //---------------------------------------------------------------------------
  654. int edmBoxClass::save (
  655. FILE *f )
  656. {
  657. // Save widget properties to file
  658. int major, minor, release, stat;
  659. tagClass tag;
  660. int zero = 0;
  661. int one = 1;
  662. static char *emptyStr = "";
  663. int solid = LineSolid;
  664. static char *styleEnumStr[2] = {
  665. "solid",
  666. "dash"
  667. };
  668. static int styleEnum[2] = {
  669. LineSolid,
  670. LineOnOffDash
  671. };
  672. static int left = XmALIGNMENT_BEGINNING;
  673. static char *alignEnumStr[3] = {
  674. "left",
  675. "center",
  676. "right"
  677. };
  678. static int alignEnum[3] = {
  679. XmALIGNMENT_BEGINNING,
  680. XmALIGNMENT_CENTER,
  681. XmALIGNMENT_END
  682. };
  683. major = MAJOR_VERSION;
  684. minor = MINOR_VERSION;
  685. release = RELEASE;
  686. tag.init();
  687. tag.loadW( "beginObjectProperties" );
  688. tag.loadW( "major", &major );
  689. tag.loadW( "minor", &minor );
  690. tag.loadW( "release", &release );
  691. tag.loadW( "x", &x );
  692. tag.loadW( "y", &y );
  693. tag.loadW( "w", &w );
  694. tag.loadW( "h", &h );
  695. tag.loadW( "controlPv", &pvExpStr, emptyStr );
  696. tag.loadW( "lineColor", actWin->ci, &lineColor );
  697. tag.loadBoolW( "lineAlarm", &lineColorMode, &zero );
  698. tag.loadBoolW( "fill", &fill, &zero );
  699. tag.loadW( "fillColor", actWin->ci, &fillColor );
  700. tag.loadBoolW( "fillAlarm", &fillColorMode, &zero );
  701. tag.loadW( "lineWidth", &lineWidth, &one );
  702. tag.loadW( "lineStyle", 2, styleEnumStr, styleEnum, &lineStyle, &solid );
  703. tag.loadW( "min", &efReadMin );
  704. tag.loadW( "max", &efReadMax );
  705. tag.loadW( "precision", &efPrecision );
  706. tag.loadW( "font", fontTag );
  707. tag.loadW( "fontAlign", 3, alignEnumStr, alignEnum, &alignment, &left );
  708. tag.loadW( "label", label, emptyStr );
  709. tag.loadW( "endObjectProperties" );
  710. tag.loadW( "" );
  711. stat = tag.writeTags( f );
  712. return stat;
  713. }
  714. //---------------------------------------------------------------------------
  715. int edmBoxClass::old_save (
  716. FILE *f )
  717. {
  718. int index, stat;
  719. fprintf( f, "%-d %-d %-d\n", MAJOR_VERSION, MINOR_VERSION, RELEASE );
  720. fprintf( f, "%-d\n", x );
  721. fprintf( f, "%-d\n", y );
  722. fprintf( f, "%-d\n", w );
  723. fprintf( f, "%-d\n", h );
  724. index = lineColor.pixelIndex();
  725. actWin->ci->writeColorIndex( f, index );
  726. //fprintf( f, "%-d\n", index );
  727. fprintf( f, "%-d\n", lineColorMode );
  728. fprintf( f, "%-d\n", fill );
  729. index = fillColor.pixelIndex();
  730. actWin->ci->writeColorIndex( f, index );
  731. //fprintf( f, "%-d\n", index );
  732. fprintf( f, "%-d\n", fillColorMode );
  733. if ( pvExpStr.getRaw() )
  734. writeStringToFile( f, pvExpStr.getRaw() );
  735. else
  736. writeStringToFile( f, "" );
  737. fprintf( f, "%-d\n", lineWidth );
  738. fprintf( f, "%-d\n", lineStyle );
  739. stat = efReadMin.write( f );
  740. stat = efReadMax.write( f );
  741. writeStringToFile( f, fontTag );
  742. writeStringToFile( f, label );
  743. fprintf( f, "%-d\n", alignment );
  744. return 1;
  745. }
  746. //---------------------------------------------------------------------------
  747. int edmBoxClass::draw ( void ) {
  748. // Draw edit mode image
  749. XRectangle xR = { x, y, w, h };
  750. int clipStat;
  751. int blink = 0;
  752. // if widget is being activated or has been deleted, return
  753. if ( activeMode || deleteRequest ) return 1;
  754. // Save foreground color
  755. actWin->drawGc.saveFg();
  756. // Set clipping region
  757. clipStat = actWin->drawGc.addNormXClipRectangle( xR );
  758. // If filled, fill in rectangle with specified color
  759. if ( fill ) {
  760. actWin->drawGc.setFG( fillColor.pixelIndex(), &blink );
  761. XFillRectangle( actWin->d, XtWindow(actWin->drawWidget),
  762. actWin->drawGc.normGC(), x+1, boxY, w-2, boxH );
  763. }
  764. // Set line color, style, and width to specified values
  765. actWin->drawGc.setFG( lineColor.pixelIndex(), &blink );
  766. actWin->drawGc.setLineWidth( lineWidth );
  767. actWin->drawGc.setLineStyle( lineStyle );
  768. // Draw rectangle outline
  769. XDrawRectangle( actWin->d, XtWindow(actWin->drawWidget),
  770. actWin->drawGc.normGC(), x+1, boxY, w-2, boxH );
  771. // Set graphic context font
  772. if ( strcmp( fontTag, "" ) != 0 ) {
  773. actWin->drawGc.setFontTag( fontTag, actWin->fi );
  774. }
  775. // Draw label text
  776. xDrawText( actWin->d, XtWindow(actWin->drawWidget),
  777. &actWin->drawGc, fs, labelX, labelY, alignment,
  778. label );
  779. // Remove clippling region
  780. if ( clipStat & 1 ) actWin->drawGc.removeNormXClipRectangle();
  781. // restore graphic context values
  782. actWin->drawGc.setLineWidth( 1 );
  783. actWin->drawGc.setLineStyle( LineSolid );
  784. actWin->drawGc.restoreFg();
  785. // This makes the blink magic work
  786. updateBlink( blink );
  787. return 1;
  788. }
  789. //---------------------------------------------------------------------------
  790. int edmBoxClass::erase ( void ) {
  791. // Draw edit mode image
  792. // Colors are not set because the eraseGC is used; the eraseGC contains
  793. // the color of the display background
  794. XRectangle xR = { x, y, w, h };
  795. int clipStat;
  796. // if widget is being activated or has been deleted, return
  797. if ( activeMode || deleteRequest ) return 1;
  798. // Set clipping region
  799. clipStat = actWin->drawGc.addEraseXClipRectangle( xR );
  800. // If filled, erase fill
  801. if ( fill ) {
  802. XFillRectangle( actWin->d, XtWindow(actWin->drawWidget),
  803. actWin->drawGc.eraseGC(), x+1, boxY, w-2, boxH );
  804. }
  805. // Set line style and width to specified values
  806. actWin->drawGc.setLineWidth( lineWidth );
  807. actWin->drawGc.setLineStyle( lineStyle );
  808. // Erase rectangle outline
  809. XDrawRectangle( actWin->d, XtWindow(actWin->drawWidget),
  810. actWin->drawGc.eraseGC(), x+1, boxY, w-2, boxH );
  811. // Set graphic context font
  812. if ( strcmp( fontTag, "" ) != 0 ) {
  813. actWin->drawGc.setFontTag( fontTag, actWin->fi );
  814. }
  815. // Erase label text
  816. xEraseText( actWin->d, XtWindow(actWin->drawWidget),
  817. &actWin->drawGc, fs, labelX, labelY, alignment,
  818. label );
  819. // Remove clippling region
  820. if ( clipStat & 1 ) actWin->drawGc.removeEraseXClipRectangle();
  821. // restore graphic context values
  822. actWin->drawGc.setLineWidth( 1 );
  823. actWin->drawGc.setLineStyle( LineSolid );
  824. return 1;
  825. }
  826. //---------------------------------------------------------------------------
  827. int edmBoxClass::checkResizeSelectBox (
  828. int _x,
  829. int _y,
  830. int _w,
  831. int _h ) {
  832. // Constrain minimum widget area size, input parameters are
  833. // delta values
  834. int tmpw, tmph, tmpBoxH, ret_stat;
  835. ret_stat = 1;
  836. tmpw = sboxW;
  837. tmph = sboxH;
  838. tmpw += _w;
  839. tmph += _h;
  840. tmpBoxH = tmph - fontHeight - fontHeight;
  841. if ( tmpBoxH < 5 ) ret_stat = 0;
  842. if ( tmpw < 5 ) ret_stat = 0;
  843. return ret_stat;
  844. }
  845. //---------------------------------------------------------------------------
  846. int edmBoxClass::checkResizeSelectBoxAbs (
  847. int _x,
  848. int _y,
  849. int _w,
  850. int _h ) {
  851. // Constrain minimum widget area size, input parameters are
  852. // absolute values
  853. int tmpw, tmph, tmpBoxH, ret_stat;
  854. ret_stat = 1;
  855. tmpw = _w;
  856. tmph = _h;
  857. if ( tmph != -1 ) {
  858. tmpBoxH = tmph - fontHeight - fontHeight;
  859. if ( tmpBoxH < 5 ) ret_stat = 0;
  860. }
  861. if ( tmpw != -1 ) {
  862. if ( tmpw < 5 ) ret_stat = 0;
  863. }
  864. return ret_stat;
  865. }
  866. //---------------------------------------------------------------------------
  867. void edmBoxClass::updateDimensions ( void ) {
  868. // Update values of position and size of widget internal details
  869. boxY = y + fontHeight;
  870. labelY = y + h - fontHeight;
  871. textValueY = y;
  872. if ( alignment == XmALIGNMENT_BEGINNING )
  873. textValueX = x;
  874. else if ( alignment == XmALIGNMENT_CENTER )
  875. textValueX = x + w/2;
  876. else if ( alignment == XmALIGNMENT_END )
  877. textValueX = x + w;
  878. if ( alignment == XmALIGNMENT_BEGINNING )
  879. labelX = x;
  880. else if ( alignment == XmALIGNMENT_CENTER )
  881. labelX = x + w/2;
  882. else if ( alignment == XmALIGNMENT_END )
  883. labelX = x + w;
  884. boxH = h - fontHeight - fontHeight;
  885. if ( boxH < 5 ) {
  886. boxH = 5;
  887. h = boxH + fontHeight + fontHeight;
  888. sboxH = h;
  889. }
  890. if ( w < 5 ) {
  891. w = 5;
  892. sboxW = 5;
  893. }
  894. }
  895. //---------------------------------------------------------------------------
  896. void edmBoxClass::changeDisplayParams (
  897. unsigned int _flag,
  898. char *_fontTag,
  899. int _alignment,
  900. char *_ctlFontTag,
  901. int _ctlAlignment,
  902. char *_btnFontTag,
  903. int _btnAlignment,
  904. int _textFgColor,
  905. int _fg1Color,
  906. int _fg2Color,
  907. int _offsetColor,
  908. int _bgColor,
  909. int _topShadowColor,
  910. int _botShadowColor )
  911. {
  912. // Depending on flag bits set, update various display properties; widgets
  913. // ignore properties that are not applicable
  914. if ( _flag & ACTGRF_FG1COLOR_MASK )
  915. lineColor.setColorIndex( _fg1Color, actWin->ci );
  916. if ( _flag & ACTGRF_BGCOLOR_MASK )
  917. fillColor.setColorIndex( _bgColor, actWin->ci );
  918. if ( _flag & ACTGRF_CTLFONTTAG_MASK ) {
  919. strcpy( fontTag, _ctlFontTag );
  920. alignment = _ctlAlignment;
  921. fs = actWin->fi->getXFontStruct( fontTag );
  922. updateFont( " ", fontTag, &fs,
  923. &fontAscent, &fontDescent, &fontHeight,
  924. &stringWidth );
  925. updateDimensions();
  926. }
  927. }
  928. //---------------------------------------------------------------------------
  929. void edmBoxClass::changePvNames (
  930. int flag,
  931. int numCtlPvs,
  932. char *ctlPvs[],
  933. int numReadbackPvs,
  934. char *readbackPvs[],
  935. int numNullPvs,
  936. char *nullPvs[],
  937. int numVisPvs,
  938. char *visPvs[],
  939. int numAlarmPvs,
  940. char *alarmPvs[] )
  941. {
  942. // Depending on flag bits set, update various process variable
  943. // names; widgets ignore pv names that are not applicable
  944. if ( flag & ACTGRF_CTLPVS_MASK ) {
  945. if ( numCtlPvs ) {
  946. pvExpStr.setRaw( ctlPvs[0] );
  947. }
  948. }
  949. }
  950. //---------------------------------------------------------------------------
  951. int edmBoxClass::drawActive ( void ) {
  952. XRectangle xR = { x, y, w, h };
  953. int clipStat;
  954. char string[31+1];
  955. int ascent, descent, height, width;
  956. int blink = 0;
  957. if ( !init ) {
  958. if ( needToDrawUnconnected ) {
  959. actWin->executeGc.saveFg();
  960. actWin->executeGc.setFG( lineColor.getDisconnectedIndex(), &blink );
  961. actWin->executeGc.setLineWidth( 1 );
  962. actWin->executeGc.setLineStyle( LineSolid );
  963. XDrawRectangle( actWin->d, XtWindow(actWin->executeWidget),
  964. actWin->executeGc.normGC(), x, y, w, h );
  965. actWin->executeGc.restoreFg();
  966. needToEraseUnconnected = 1;
  967. updateBlink( blink );
  968. }
  969. }
  970. else if ( needToEraseUnconnected ) {
  971. actWin->executeGc.setLineWidth( 1 );
  972. actWin->executeGc.setLineStyle( LineSolid );
  973. XDrawRectangle( actWin->d, XtWindow(actWin->executeWidget),
  974. actWin->executeGc.eraseGC(), x, y, w, h );
  975. needToEraseUnconnected = 0;
  976. }
  977. if ( !enabled || !activeMode || !init ) return 1;
  978. actWin->executeGc.saveFg();
  979. clipStat = actWin->executeGc.addNormXClipRectangle( xR );
  980. if ( fill ) {
  981. actWin->executeGc.setFG( fillColor.getIndex(), &blink );
  982. XFillRectangle( actWin->d, XtWindow(actWin->executeWidget),
  983. actWin->executeGc.normGC(), valueBoxX, valueBoxY, valueBoxW, valueBoxH );
  984. }
  985. actWin->executeGc.setFG( lineColor.getIndex(), &blink );
  986. actWin->executeGc.setLineWidth( lineWidth );
  987. actWin->executeGc.setLineStyle( lineStyle );
  988. XDrawRectangle( actWin->d, XtWindow(actWin->executeWidget),
  989. actWin->executeGc.normGC(), valueBoxX, valueBoxY, valueBoxW, valueBoxH );
  990. actWin->executeGc.setLineWidth( 1 );
  991. actWin->executeGc.setLineStyle( LineSolid );
  992. snprintf( string, 31, format, value );
  993. if ( strcmp( fontTag, "" ) != 0 ) {
  994. actWin->executeGc.setFontTag( fontTag, actWin->fi );
  995. }
  996. updateFont( string, fontTag, &fs,
  997. &ascent, &descent, &height, &width );
  998. xDrawText( actWin->d, XtWindow(actWin->executeWidget),
  999. &actWin->executeGc, fs, textValueX, textValueY, alignment,
  1000. string );
  1001. prevValue = value;
  1002. if ( bufferInvalid ) {
  1003. xDrawText( actWin->d, XtWindow(actWin->executeWidget),
  1004. &actWin->executeGc, fs, labelX, labelY, alignment,
  1005. label );
  1006. bufferInvalid = 0;
  1007. }
  1008. if ( clipStat & 1 ) actWin->executeGc.removeNormXClipRectangle();
  1009. actWin->executeGc.restoreFg();
  1010. updateBlink( blink );
  1011. return 1;
  1012. }
  1013. //---------------------------------------------------------------------------
  1014. int edmBoxClass::eraseActive ( void ) {
  1015. XRectangle xR = { x, y, w, h };
  1016. int clipStat;
  1017. char string[31+1];
  1018. if ( !enabled || !activeMode || !init ) return 1;
  1019. clipStat = actWin->executeGc.addEraseXClipRectangle( xR );
  1020. if ( fill ) {
  1021. XFillRectangle( actWin->d, XtWindow(actWin->executeWidget),
  1022. actWin->executeGc.eraseGC(), valueBoxX, valueBoxY, valueBoxW, valueBoxH );
  1023. }
  1024. actWin->executeGc.setLineWidth( lineWidth );
  1025. actWin->executeGc.setLineStyle( lineStyle );
  1026. XDrawRectangle( actWin->d, XtWindow(actWin->executeWidget),
  1027. actWin->executeGc.eraseGC(), valueBoxX, valueBoxY, valueBoxW, valueBoxH );
  1028. actWin->executeGc.setLineWidth( 1 );
  1029. actWin->executeGc.setLineStyle( LineSolid );
  1030. snprintf( string, 31, format, prevValue );
  1031. if ( strcmp( fontTag, "" ) != 0 ) {
  1032. actWin->executeGc.setFontTag( fontTag, actWin->fi );
  1033. }
  1034. xEraseText( actWin->d, XtWindow(actWin->executeWidget),
  1035. &actWin->executeGc, fs, textValueX, textValueY, alignment,
  1036. string );
  1037. if ( bufferInvalid ) {
  1038. xEraseText( actWin->d, XtWindow(actWin->executeWidget),
  1039. &actWin->executeGc, fs, labelX, labelY, alignment,
  1040. label );
  1041. }
  1042. if ( clipStat & 1 ) actWin->executeGc.removeEraseXClipRectangle();
  1043. return 1;
  1044. }
  1045. //---------------------------------------------------------------------------
  1046. void edmBoxClass::bufInvalidate ( void )
  1047. {
  1048. bufferInvalid = 1;
  1049. }
  1050. //---------------------------------------------------------------------------
  1051. int edmBoxClass::expand1st (
  1052. int numMacros,
  1053. char *macros[],
  1054. char *expansions[] )
  1055. {
  1056. int stat;
  1057. stat = pvExpStr.expand1st( numMacros, macros, expansions );
  1058. return stat;
  1059. }
  1060. //---------------------------------------------------------------------------
  1061. int edmBoxClass::expand2nd (
  1062. int numMacros,
  1063. char *macros[],
  1064. char *expansions[] )
  1065. {
  1066. int stat;
  1067. stat = pvExpStr.expand2nd( numMacros, macros, expansions );
  1068. return stat;
  1069. }
  1070. //---------------------------------------------------------------------------
  1071. int edmBoxClass::containsMacros ( void ) {
  1072. if ( pvExpStr.containsPrimaryMacros() ) return 1;
  1073. return 0;
  1074. }
  1075. //---------------------------------------------------------------------------
  1076. int edmBoxClass::activate (
  1077. int pass,
  1078. void *ptr )
  1079. {
  1080. int stat;
  1081. switch ( pass ) {
  1082. case 1: // initialize
  1083. opComplete = 0;
  1084. break;
  1085. case 2: // connect to pv
  1086. if ( !opComplete ) {
  1087. initEnable();
  1088. aglPtr = ptr;
  1089. needConnectInit = needUpdate = needDraw = 0;
  1090. init = 0;
  1091. active = 0;
  1092. activeMode = 1;
  1093. bufferInvalid = 0;
  1094. pointerMotionDetected = 0;
  1095. pvId = NULL;
  1096. oldStat = oldSev = -1;
  1097. value = prevValue = 0;
  1098. needToDrawUnconnected = 0;
  1099. needToEraseUnconnected = 0;
  1100. unconnectedTimer = 0;
  1101. if ( !unconnectedTimer ) {
  1102. unconnectedTimer = appAddTimeOut( actWin->appCtx->appContext(),
  1103. 2000, unconnectedTimeout, this );
  1104. }
  1105. if ( !pvExpStr.getExpanded() ||
  1106. // ( strcmp( pvExpStr.getExpanded(), "" ) == 0 ) ) {
  1107. blankOrComment( pvExpStr.getExpanded() ) ) {
  1108. pvExists = 0;
  1109. }
  1110. else {
  1111. pvExists = 1;
  1112. lineColor.setConnectSensitive();
  1113. fillColor.setConnectSensitive();
  1114. }
  1115. if ( pvExists ) {
  1116. pvId = the_PV_Factory->create( pvExpStr.getExpanded() );
  1117. if ( pvId ) {
  1118. pvId->add_conn_state_callback( monitorPvConnectState, this );
  1119. pvId->add_value_callback( pvUpdate, this );
  1120. }
  1121. else {
  1122. printf( edmBoxComplete_str21 );
  1123. }
  1124. }
  1125. else {
  1126. active = 1;
  1127. init = 1;
  1128. valueBoxW = w-2;
  1129. valueBoxX = x+1;
  1130. valueBoxH = boxH;
  1131. valueBoxY = boxY;
  1132. stat = drawActive();
  1133. }
  1134. opComplete = 1;
  1135. }
  1136. break;
  1137. case 3:
  1138. case 4:
  1139. case 5:
  1140. case 6:
  1141. break;
  1142. }
  1143. return 1;
  1144. }
  1145. //---------------------------------------------------------------------------
  1146. int edmBoxClass::deactivate (
  1147. int pass )
  1148. {
  1149. if ( pass == 1 ) {
  1150. if ( unconnectedTimer ) {
  1151. XtRemoveTimeOut( unconnectedTimer );
  1152. unconnectedTimer = 0;
  1153. }
  1154. activeMode = 0;
  1155. if ( pvId ) {
  1156. pvId->remove_conn_state_callback( monitorPvConnectState, this );
  1157. pvId->remove_value_callback( pvUpdate, this );
  1158. pvId->release();
  1159. pvId = NULL;
  1160. }
  1161. }
  1162. return 1;
  1163. }
  1164. //---------------------------------------------------------------------------
  1165. void edmBoxClass::btnUp (
  1166. int x,
  1167. int y,
  1168. int buttonState,
  1169. int buttonNumber,
  1170. int *action )
  1171. {
  1172. double v, dInc;
  1173. *action = 0;
  1174. if ( !enabled ) return;
  1175. dInc = 10.0;
  1176. // wheel
  1177. if ( buttonNumber == 4 ) {
  1178. buttonNumber = 1;
  1179. dInc = 1.0;
  1180. }
  1181. if ( buttonNumber == 5 ) {
  1182. buttonNumber = 1;
  1183. buttonState |= ShiftMask;
  1184. dInc = 1.0;
  1185. }
  1186. // wheel
  1187. if ( buttonNumber != 1 ) return;
  1188. if ( pvExists && !pointerMotionDetected ) {
  1189. if ( buttonState & ShiftMask ) {
  1190. v = curValue - dInc;
  1191. if ( v < readMin ) v = readMin;
  1192. }
  1193. else {
  1194. v = curValue + dInc;
  1195. if ( v > readMax ) v = readMax;
  1196. }
  1197. pvId->put( v );
  1198. }
  1199. }
  1200. //---------------------------------------------------------------------------
  1201. void edmBoxClass::btnDown (
  1202. int x,
  1203. int y,
  1204. int buttonState,
  1205. int buttonNumber,
  1206. int *action )
  1207. {
  1208. if ( !enabled ) return;
  1209. if ( buttonNumber == 4 ) buttonNumber = 1;
  1210. if ( buttonNumber == 5 ) buttonNumber = 1;
  1211. if ( buttonNumber != 1 ) return;
  1212. pointerMotionDetected = 0;
  1213. }
  1214. //---------------------------------------------------------------------------
  1215. void edmBoxClass::btnDrag (
  1216. int x,
  1217. int y,
  1218. int buttonState,
  1219. int buttonNumber )
  1220. {
  1221. double v;
  1222. if ( !enabled ) return;
  1223. if ( buttonNumber != 1 ) return;
  1224. pointerMotionDetected = 1;
  1225. if ( pvExists ) {
  1226. if ( buttonState & ShiftMask ) {
  1227. v = curValue - 1.0;
  1228. if ( v < readMin ) v = readMin;
  1229. }
  1230. else {
  1231. v = curValue + 1.0;
  1232. if ( v > readMax ) v = readMax;
  1233. }
  1234. pvId->put( v );
  1235. }
  1236. }
  1237. //---------------------------------------------------------------------------
  1238. int edmBoxClass::getButtonActionRequest (
  1239. int *up,
  1240. int *down,
  1241. int *drag,
  1242. int *focus )
  1243. {
  1244. *drag = 1;
  1245. *down = 1;
  1246. *up = 1;
  1247. if ( pvExists )
  1248. *focus = 1;
  1249. else
  1250. *focus = 0;
  1251. return 1;
  1252. }
  1253. //---------------------------------------------------------------------------
  1254. void edmBoxClass::executeDeferred ( void ) {
  1255. int stat, nc, nu, nd;
  1256. if ( actWin->isIconified ) return;
  1257. actWin->appCtx->proc->lock();
  1258. if ( !activeMode ) {
  1259. actWin->remDefExeNode( aglPtr );
  1260. actWin->appCtx->proc->unlock();
  1261. return;
  1262. }
  1263. value = curValue;
  1264. nc = needConnectInit; needConnectInit = 0;
  1265. nu = needUpdate; needUpdate = 0;
  1266. nd = needDraw; needDraw = 0;
  1267. actWin->remDefExeNode( aglPtr );
  1268. actWin->appCtx->proc->unlock();
  1269. //--------------
  1270. if ( nc ) {
  1271. // require process variable to be numeric
  1272. if ( ( fieldType == ProcessVariable::Type::real ) ||
  1273. ( fieldType == ProcessVariable::Type::integer ) ) {
  1274. snprintf( format, 15, "%%.%-df", precision );
  1275. stat = eraseActive();
  1276. if ( readMax > readMin ) {
  1277. factorW = (double) ( w - 2 ) / ( readMax - readMin );
  1278. factorH = (double) boxH / ( readMax - readMin );
  1279. }
  1280. else {
  1281. factorW = 1;
  1282. factorH = 1;
  1283. }
  1284. centerX = x + (int) ( w * 0.5 + 0.5 );
  1285. centerY = boxY + (int) ( boxH * 0.5 + 0.5 );
  1286. if ( value > 0.0 ) {
  1287. valueBoxW = (int) ( value * factorW + 0.5 );
  1288. valueBoxX = centerX - (int) ( (double) valueBoxW * 0.5 + 0.5 );
  1289. valueBoxH = (int) ( value * factorH + 0.5 );
  1290. valueBoxY = centerY - (int) ( (double) valueBoxH * 0.5 + 0.5 );
  1291. }
  1292. else {
  1293. valueBoxW = 1;
  1294. valueBoxX = centerX;
  1295. valueBoxH = 1;
  1296. valueBoxY = centerY;
  1297. }
  1298. init = 1;
  1299. active = 1;
  1300. lineColor.setConnected();
  1301. fillColor.setConnected();
  1302. bufInvalidate();
  1303. #if SMARTDRAW
  1304. smartDrawAllActive();
  1305. #else
  1306. drawActive();
  1307. #endif
  1308. }
  1309. else { // force a draw in the non-active state & post error message
  1310. actWin->appCtx->postMessage(
  1311. edmBoxComplete_str22 );
  1312. active = 0;
  1313. init = 1;
  1314. valueBoxW = w-2;
  1315. valueBoxX = x+1;
  1316. valueBoxH = boxH;
  1317. valueBoxY = boxY;
  1318. lineColor.setDisconnected();
  1319. fillColor.setDisconnected();
  1320. #if SMARTDRAW
  1321. smartDrawAllActive();
  1322. #else
  1323. drawActive();
  1324. #endif
  1325. }
  1326. }
  1327. //--------------
  1328. if ( nu ) {
  1329. eraseActive();
  1330. if ( value > 0.0 ) {
  1331. valueBoxW = (int) ( value * factorW + 0.5 );
  1332. valueBoxX = centerX - (int) ( (double) valueBoxW * 0.5 + 0.5 );
  1333. valueBoxH = (int) ( value * factorH + 0.5 );
  1334. valueBoxY = centerY - (int) ( (double) valueBoxH * 0.5 + 0.5 );
  1335. }
  1336. else {
  1337. valueBoxW = 1;
  1338. valueBoxX = centerX;
  1339. valueBoxH = 1;
  1340. valueBoxY = centerY;
  1341. }
  1342. #if SMARTDRAW
  1343. smartDrawAllActive();
  1344. #else
  1345. drawActive();
  1346. #endif
  1347. }
  1348. //--------------
  1349. if ( nd ) {
  1350. #if SMARTDRAW
  1351. smartDrawAllActive();
  1352. #else
  1353. drawActive();
  1354. #endif
  1355. }
  1356. }
  1357. //---------------------------------------------------------------------------
  1358. char *edmBoxClass::firstDragName ( void ) {
  1359. if ( !enabled ) return NULL;
  1360. dragIndex = 0;
  1361. return dragName[dragIndex];
  1362. }
  1363. //---------------------------------------------------------------------------
  1364. char *edmBoxClass::nextDragName ( void ) {
  1365. return NULL;
  1366. }
  1367. //---------------------------------------------------------------------------
  1368. char *edmBoxClass::dragValue (
  1369. int i ) {
  1370. if ( !enabled ) return NULL;
  1371. if ( actWin->mode == AWC_EXECUTE ) {
  1372. return pvExpStr.getExpanded();
  1373. }
  1374. else {
  1375. return pvExpStr.getRaw();
  1376. }
  1377. }
  1378. //---------------------------------------------------------------------------
  1379. // X windows makes client code do blinking if color depth is
  1380. // anything other than 8 bits
  1381. void edmBoxClass::doBlink (
  1382. void *ptr
  1383. ) {
  1384. edmBoxClass *ebo = (edmBoxClass *) ptr;
  1385. if ( !ebo->activeMode ) {
  1386. if ( ebo->isSelected() ) ebo->drawSelectBoxCorners(); // erase via xor
  1387. #if SMARTDRAW
  1388. ebo->smartDrawAll();
  1389. #else
  1390. ebo->draw();
  1391. #endif
  1392. if ( ebo->isSelected() ) ebo->drawSelectBoxCorners();
  1393. }
  1394. else {
  1395. ebo->actWin->appCtx->proc->lock();
  1396. ebo->bufInvalidate();
  1397. ebo->needUpdate = 1;
  1398. ebo->actWin->addDefExeNode( ebo->aglPtr );
  1399. ebo->actWin->appCtx->proc->unlock();
  1400. }
  1401. }
  1402. //---------------------------------------------------------------------------
  1403. void edmBoxClass::unconnectedTimeout (
  1404. XtPointer client,
  1405. XtIntervalId *id )
  1406. {
  1407. edmBoxClass *ebo = (edmBoxClass *) client;
  1408. if ( !ebo->init ) {
  1409. ebo->actWin->appCtx->proc->lock();
  1410. ebo->bufInvalidate();
  1411. ebo->needToDrawUnconnected = 1;
  1412. ebo->needUpdate = 1;
  1413. ebo->actWin->addDefExeNode( ebo->aglPtr );
  1414. ebo->actWin->appCtx->proc->unlock();
  1415. }
  1416. ebo->unconnectedTimer = 0;
  1417. }
  1418. //---------------------------------------------------------------------------
  1419. void edmBoxClass::monitorPvConnectState (
  1420. ProcessVariable *pv,
  1421. void *userarg )
  1422. {
  1423. edmBoxClass *ebo = (edmBoxClass *) userarg;
  1424. ebo->actWin->appCtx->proc->lock();
  1425. if ( !ebo->activeMode ) {
  1426. ebo->actWin->appCtx->proc->unlock();
  1427. return;
  1428. }
  1429. if ( pv->is_valid() ) {
  1430. ebo->fieldType = (int) pv->get_type().type;
  1431. ebo->curValue = pv->get_double();
  1432. if ( ebo->efReadMin.isNull() ) {
  1433. ebo->readMin = pv->get_lower_disp_limit();
  1434. }
  1435. else {
  1436. ebo->readMin = ebo->efReadMin.value();
  1437. }
  1438. if ( ebo->efReadMax.isNull() ) {
  1439. ebo->readMax = pv->get_upper_disp_limit();
  1440. }
  1441. else {
  1442. ebo->readMax = ebo->efReadMax.value();
  1443. }
  1444. if ( ebo->efPrecision.isNull() ) {
  1445. ebo->precision = pv->get_precision();
  1446. }
  1447. else {
  1448. ebo->precision = ebo->efPrecision.value();
  1449. }
  1450. ebo->needConnectInit = 1;
  1451. }
  1452. else { // lost connection
  1453. ebo->active = 0;
  1454. ebo->lineColor.setDisconnected();
  1455. ebo->fillColor.setDisconnected();
  1456. ebo->bufInvalidate();
  1457. ebo->needDraw = 1;
  1458. }
  1459. ebo->actWin->addDefExeNode( ebo->aglPtr );
  1460. ebo->actWin->appCtx->proc->unlock();
  1461. }
  1462. //---------------------------------------------------------------------------
  1463. void edmBoxClass::pvUpdate (
  1464. ProcessVariable *pv,
  1465. void *userarg )
  1466. {
  1467. class edmBoxClass *ebo = (edmBoxClass *) userarg;
  1468. int st, sev;
  1469. if ( !ebo->activeMode ) return;
  1470. ebo->actWin->appCtx->proc->lock();
  1471. ebo->curValue = pv->get_double();
  1472. ebo->needUpdate = 1;
  1473. st = pv->get_status();
  1474. sev = pv->get_severity();
  1475. if ( ( st != ebo->oldStat ) || ( sev != ebo->oldSev ) ) {
  1476. ebo->oldStat = st;
  1477. ebo->oldSev = sev;
  1478. ebo->lineColor.setStatus( st, sev );
  1479. ebo->fillColor.setStatus( st, sev );
  1480. ebo->needDraw = 1;
  1481. ebo->bufInvalidate();
  1482. }
  1483. ebo->actWin->addDefExeNode( ebo->aglPtr );
  1484. ebo->actWin->appCtx->proc->unlock();
  1485. }
  1486. void edmBoxClass::getPvs (
  1487. int max,
  1488. ProcessVariable *pvs[],
  1489. int *n ) {
  1490. if ( max < 1 ) {
  1491. *n = 0;
  1492. return;
  1493. }
  1494. *n = 1;
  1495. pvs[0] = pvId;
  1496. }
  1497. //---------------------------------------------------------------------------
  1498. // "C" compatible class factory functions
  1499. extern "C" {
  1500. void *create_2ed7d2e8_f439_11d2_8fed_00104b8742dfPtr ( void ) {
  1501. edmBoxClass *ptr;
  1502. ptr = new edmBoxClass;
  1503. return (void *) ptr;
  1504. }
  1505. void *clone_2ed7d2e8_f439_11d2_8fed_00104b8742dfPtr (
  1506. void *_srcPtr )
  1507. {
  1508. edmBoxClass *ptr, *srcPtr;
  1509. srcPtr = (edmBoxClass *) _srcPtr;
  1510. ptr = new edmBoxClass( srcPtr );
  1511. return (void *) ptr;
  1512. }
  1513. }