PageRenderTime 28ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/lui5/newslider.c

https://github.com/drafnel/Vis5d
C | 454 lines | 307 code | 109 blank | 38 comment | 46 complexity | 7f78c7b87e1bd2087e4938e5f943fa68 MD5 | raw file
  1. /* newslider.c */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "lui.h"
  6. /* MJK 12.04.98 */
  7. /* 22Sep97 Phil McDonald */
  8. # include <math.h>
  9. #define X_MARGIN 10
  10. #define Y_MARGIN 4
  11. #define SLIDER_BAR_LEN(s) ( s->width - 2 * X_MARGIN )
  12. #define LUI_SLIDER_INACTIVE 0
  13. #define LUI_SLIDER_ACTIVE 1
  14. #define LUI_SLIDER_INT 0
  15. #define LUI_SLIDER_FLOAT 1
  16. /* MJK 12.04.98 */
  17. /* 22Sep97 Phil McDonald */
  18. static int make_string( LUI_NEWSLIDER *slider, float value, char *fmt,
  19. char *retstr )
  20. {
  21. if (slider->type == LUI_SLIDER_FLOAT) {
  22. char tmp[64], *c, *d;
  23. if (strlen (fmt) > 0)
  24. {
  25. sprintf (retstr, fmt, value);
  26. return strlen(retstr);
  27. }
  28. #ifdef JOHAN
  29. static int make_string( LUI_NEWSLIDER *slider, float value, char *retstr )
  30. {
  31. if (slider->type == LUI_SLIDER_FLOAT) {
  32. char tmp[64], *c, *d;
  33. #endif
  34. /* changed by BP on 10-15-91 to a format based upon value */
  35. if (value>=0.01 || value<=-0.01)
  36. sprintf(tmp, "%7.2f", value);
  37. else
  38. sprintf(tmp, "%7.5f", value);
  39. for (c = tmp; *c == ' '; ++c);
  40. /* remove trailing 0's - WLH 10-21-91 */
  41. while((d = strrchr(c, '0')) == (c + strlen(c) - 1) &&
  42. *(c + strlen(c) - 2) != '.') *d = 0;
  43. sprintf(retstr, "%s", c);
  44. }
  45. else
  46. sprintf(retstr, "%d", (int)(value+0.5));
  47. return(strlen(retstr));
  48. }
  49. static void draw_slider( LUI_NEWSLIDER *s )
  50. {
  51. XPoint pts[4];
  52. int x, y, w, h;
  53. int xc, yc, size;
  54. char caption[128], valstr[128];
  55. /* Fill the background and draw border */
  56. XFillRectangle( LUI_Display, s->window,
  57. #ifdef OLD
  58. /*s->hilite ? LUI_GC_white : */ LUI_GC_gray,
  59. #endif
  60. s->hilite ? LUI_GC_highgray : LUI_GC_gray,
  61. 0, 0, s->width, s->height );
  62. LUI_DrawFrame( s->window, 0, 0, s->width, s->height,
  63. LUI_Border, 1 );
  64. /* Draw slider bar groove */
  65. x = X_MARGIN + 6;
  66. y = Y_MARGIN + LUI_Font_height - 1;
  67. w = s->width - 2 * X_MARGIN - 12;
  68. h = 6;
  69. /* tiny end triangles */
  70. XFillRectangle(LUI_Display, s->window, LUI_GC_white, x-6, y, x+12, 2*h);
  71. XFillRectangle(LUI_Display, s->window, LUI_GC_md_grey, x+w, y, 6, 2*h);
  72. pts[0].x = x-6; pts[0].y = y;
  73. pts[1].x = x+w+6; pts[1].y = y;
  74. pts[2].x = x+w; pts[2].y = y+h;
  75. pts[3].x = x; pts[3].y = y+h;
  76. XFillPolygon(LUI_Display, s->window,
  77. LUI_GC_bottom, pts, 4, Convex, CoordModeOrigin);
  78. XDrawLines(LUI_Display, s->window,
  79. LUI_GC_black, pts, 4, CoordModeOrigin);
  80. y += h;
  81. pts[0].x = x; pts[0].y = y;
  82. pts[1].x = x+w; pts[1].y = y;
  83. pts[2].x = x+w+6; pts[2].y = y+h;
  84. pts[3].x = x-6; pts[3].y = y+h;
  85. XFillPolygon(LUI_Display, s->window, /*sl_grey*/
  86. LUI_GC_top, pts, 4, Convex, CoordModeOrigin);
  87. XDrawLines(LUI_Display, s->window,
  88. LUI_GC_black, pts, 4, CoordModeOrigin);
  89. XDrawRectangle(LUI_Display, s->window, LUI_GC_black,
  90. x-6, y-6, w+12, 2*h);
  91. /* Draw slider marker */
  92. if (s->high==s->low) {
  93. x = X_MARGIN;
  94. }
  95. else {
  96. x = X_MARGIN + (SLIDER_BAR_LEN(s)) * (s->value-s->low)
  97. / (s->high-s->low);
  98. }
  99. y = Y_MARGIN + LUI_Font_height - 1;
  100. w = 6;
  101. h = 6;
  102. /* changed to red tick by BEP 4-30-93 */
  103. pts[0].x = x; pts[0].y = y;
  104. pts[1].x = x+w; pts[1].y = y+h;
  105. pts[2].x = x; pts[2].y = y+h*2;
  106. pts[3].x = x-w; pts[3].y = y+h;
  107. XFillPolygon(LUI_Display, s->window,
  108. LUI_GC_black, pts, 4, Convex, CoordModeOrigin);
  109. pts[0].x = x; pts[0].y = y+3;
  110. pts[1].x = x+w-3; pts[1].y = y+h;
  111. pts[2].x = x; pts[2].y = y+h*2-3;
  112. pts[3].x = x-w+3; pts[3].y = y+h;
  113. XFillPolygon(LUI_Display, s->window,
  114. LUI_GC_red, pts, 4, Convex, CoordModeOrigin);
  115. yc = Y_MARGIN + LUI_Font_yoff - 1;
  116. /* MJK 12.04.98 */
  117. /* 22Sep97 Phil McDonald */
  118. {
  119. char fmt[20] = "";
  120. float range;
  121. int ndigits;
  122. range = (s->high > s->low) ? s->high - s->low : s->low - s->high;
  123. if (range == 0.0) range = 1.0;
  124. ndigits = (2.5 - log10 (range));
  125. if (ndigits < 0) ndigits = 0;
  126. if (ndigits > 9) ndigits = 9;
  127. sprintf (fmt, "%%.%df", ndigits);
  128. /* Label & current value */
  129. make_string( s, s->value, fmt, valstr );
  130. sprintf(caption, "%s = %s", s->label, valstr);
  131. if (s->units != NULL && strlen (s->units) > 0)
  132. {
  133. strcat (caption, " ");
  134. strcat (caption, s->units);
  135. }
  136. size = strlen(caption);
  137. xc = s->width / 2 - XTextWidth(LUI_Font, caption, size) / 2.0 + 0.5;
  138. XDrawString(LUI_Display, s->window, LUI_GC_black, xc, yc, caption, size);
  139. /* Low labels */
  140. size = make_string( s, s->low, fmt, valstr );
  141. xc = X_MARGIN - 3;
  142. XDrawString(LUI_Display, s->window, LUI_GC_black, xc, yc, valstr, size);
  143. /* High label */
  144. size = make_string( s, s->high, fmt, valstr );
  145. xc = X_MARGIN + SLIDER_BAR_LEN(s) - XTextWidth(LUI_Font, valstr, size) + 3;
  146. XDrawString(LUI_Display, s->window, LUI_GC_black, xc, yc, valstr, size);
  147. }
  148. #ifdef JOHAN
  149. /* Label & current value */
  150. make_string( s, s->value, valstr );
  151. sprintf(caption, "%s = %s", s->label, valstr);
  152. size = strlen(caption);
  153. xc = s->width / 2 - XTextWidth(LUI_Font, caption, size) / 2.0 + 0.5;
  154. XDrawString(LUI_Display, s->window, LUI_GC_black, xc, yc, caption, size);
  155. /* Low labels */
  156. size = make_string( s, s->low, valstr );
  157. xc = X_MARGIN - 3;
  158. XDrawString(LUI_Display, s->window, LUI_GC_black, xc, yc, valstr, size);
  159. /* High label */
  160. size = make_string( s, s->high, valstr );
  161. xc = X_MARGIN + SLIDER_BAR_LEN(s) - XTextWidth(LUI_Font, valstr, size) + 3;
  162. XDrawString(LUI_Display, s->window, LUI_GC_black, xc, yc, valstr, size);
  163. #endif
  164. }
  165. static int slider_process( LUI_NEWSLIDER *s, XEvent *event )
  166. {
  167. switch (event->type) {
  168. case EnterNotify:
  169. s->hilite = 1;
  170. draw_slider( s );
  171. break;
  172. case LeaveNotify:
  173. s->hilite = 0;
  174. draw_slider( s );
  175. break;
  176. case Expose:
  177. draw_slider( s );
  178. break;
  179. case ButtonPress:
  180. s->state = LUI_SLIDER_ACTIVE;
  181. s->button = event->xbutton.button; /* WLH added 12-12-91 */
  182. /* fall through to .... */
  183. case MotionNotify:
  184. if (s->state == LUI_SLIDER_ACTIVE) {
  185. float x_in_pixels; /* inside slide bar range */
  186. if (event->type==ButtonPress) {
  187. x_in_pixels = event->xbutton.x - X_MARGIN;
  188. }
  189. else {
  190. x_in_pixels = event->xmotion.x - X_MARGIN;
  191. }
  192. /* clamp value: */
  193. if (x_in_pixels<0) {
  194. x_in_pixels = 0;
  195. }
  196. else if (x_in_pixels > SLIDER_BAR_LEN(s)) {
  197. x_in_pixels = SLIDER_BAR_LEN(s);
  198. }
  199. /* map from slider pixels to application range: */
  200. s->value = s->low + (s->high-s->low) *
  201. x_in_pixels/(SLIDER_BAR_LEN(s));
  202. if (s->type == LUI_SLIDER_INT) {
  203. s->value = (int)(s->value + 0.5);
  204. }
  205. if (s->old_value != s->value) {
  206. if (s->callback) {
  207. (*(s->callback))(s, s->value);
  208. }
  209. draw_slider( s );
  210. }
  211. s->old_value = s->value;
  212. }
  213. break;
  214. case ButtonRelease:
  215. s->state = LUI_SLIDER_INACTIVE;
  216. /* s->hilite = 0;*/
  217. /* This might cause problems: Added to allow an application to */
  218. /* only do stuff on a button release */
  219. if (s->callback) {
  220. (*(s->callback))(s, s->value );
  221. }
  222. draw_slider( s );
  223. break;
  224. }
  225. /* Flush remaining motion events in event queue */
  226. while (QLength(LUI_Display) > 0) {
  227. XEvent ne;
  228. XPeekEvent(LUI_Display, &ne);
  229. /* Don't flush if its a button press or release */
  230. if (ne.type != MotionNotify)
  231. break;
  232. /* Get the next event */
  233. XNextEvent(LUI_Display, &ne);
  234. }
  235. return 0;
  236. }
  237. void LUI_NewSliderDestroy( LUI_NEWSLIDER *s )
  238. {
  239. XDestroyWindow( LUI_Display, s->window );
  240. if (s->label) {
  241. free( s->label );
  242. }
  243. /* MJK 12.04.98 */
  244. /* 24Nov97 Phil McDonald */
  245. if (s->units) free (s->units);
  246. free( s );
  247. }
  248. LUI_NEWSLIDER *LUI_NewSliderCreate( Window parent, int x, int y, int width )
  249. {
  250. LUI_NEWSLIDER *s;
  251. int height;
  252. height = 36;
  253. LUI_LayoutCheck( &x, &y, &width, &height );
  254. s = (LUI_NEWSLIDER *) malloc( sizeof(LUI_NEWSLIDER) );
  255. if (!s) {
  256. return NULL;
  257. }
  258. /* Create the slider window */
  259. s->window = XCreateSimpleWindow( LUI_Display, parent,
  260. x, y, width-2, height-2,
  261. 1, LUI_Color_black, LUI_Color_gray );
  262. LUI_EventAdd2( s->window,
  263. ExposureMask | ButtonPressMask | ButtonReleaseMask
  264. | ButtonMotionMask | EnterWindowMask | LeaveWindowMask,
  265. (LUI_FNCP) slider_process, s );
  266. XMapWindow(LUI_Display, s->window);
  267. /* Initialize slider */
  268. s->label = strdup("");
  269. s->x = x;
  270. s->y = y;
  271. s->width = width - 2;
  272. s->height = height - 2;
  273. s->state = LUI_SLIDER_INACTIVE;
  274. s->type = LUI_SLIDER_FLOAT;
  275. s->low = 0.0;
  276. s->high = 1.0;
  277. s->value = 0.5;
  278. s->old_value = 0.5;
  279. s->index = 0;
  280. s->callback = NULL;
  281. s->context_index = context_index;
  282. s->hilite = 0;
  283. /* MJK 12.04.98 */
  284. /* 22Sep97 Phil McDonald */
  285. s->units = strdup("");
  286. LUI_AddWidgetToWindow( parent, s, (LUI_FNCP) LUI_NewSliderDestroy );
  287. return s;
  288. }
  289. void LUI_NewSliderCallback( LUI_NEWSLIDER *s,
  290. int (*callback)( LUI_NEWSLIDER *, float ) )
  291. {
  292. s->callback = callback;
  293. }
  294. void LUI_NewSliderSetLabel( LUI_NEWSLIDER *s, char *label )
  295. {
  296. if (s->label) {
  297. free(s->label);
  298. }
  299. s->label = strdup( label );
  300. }
  301. void LUI_NewSliderSetRange( LUI_NEWSLIDER *s, float min, float max )
  302. {
  303. s->low = min;
  304. s->high = max;
  305. draw_slider( s );
  306. }
  307. void LUI_NewSliderSetValue( LUI_NEWSLIDER *s, float value )
  308. {
  309. s->value = value;
  310. draw_slider( s );
  311. }
  312. /* MJK 12.04.98 */
  313. /* 22Sep97 Phil McDonald */
  314. void LUI_NewSliderSetUnits( LUI_NEWSLIDER *s, char *units )
  315. {
  316. if (s->units) {
  317. free(s->units);
  318. }
  319. if (units != NULL){
  320. s->units = strdup( units );
  321. }
  322. else{
  323. s->units = NULL;
  324. }
  325. }
  326. void LUI_NewSliderChange( LUI_NEWSLIDER *s, char *label, char *units,
  327. float min, float max, float value)
  328. {
  329. LUI_NewSliderSetLabel( s, label );
  330. LUI_NewSliderSetUnits( s, units );
  331. LUI_NewSliderSetRange( s, min, max );
  332. /* 18Feb98 Phil McDonald */
  333. if (value < min) value = min;
  334. if (value > max) value = max;
  335. LUI_NewSliderSetValue( s, value );
  336. }
  337. #ifdef JOHAN
  338. void LUI_NewSliderChange( LUI_NEWSLIDER *s, char *label,
  339. float min, float max, float value )
  340. {
  341. LUI_NewSliderSetLabel( s, label );
  342. LUI_NewSliderSetRange( s, min, max );
  343. LUI_NewSliderSetValue( s, value );
  344. }
  345. #endif