input.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. #include "globals.h"
  2. #include "local_proto.h"
  3. #include <grass/display.h>
  4. static int active = 0;
  5. static int replot;
  6. static int mouse(Objects *, int, int, int);
  7. static int use_mouse_msg(void);
  8. static int draw_objects(Objects *);
  9. static Objects *find(Objects *, int, int);
  10. static int select_option(Objects *, Objects *);
  11. static int draw_option_boxes(Objects *);
  12. static int visible(Objects *);
  13. #define TEXT_COLOR BLACK
  14. #define FILL_COLOR GREY
  15. #define OUTLINE_COLOR WHITE
  16. /* Input: drive mouse. returns status of handler that returns != 0 */
  17. int Input_pointer(Objects * objects)
  18. {
  19. return mouse(objects, 0, 0, 0);
  20. }
  21. int Input_box(Objects * objects, int ax, int ay)
  22. {
  23. return mouse(objects, ax, ay, 1);
  24. }
  25. int Input_other(int (*function) (), char *type)
  26. {
  27. int stat;
  28. char msg[1024];
  29. sprintf(msg, "%s input required", type);
  30. Menu_msg(msg);
  31. stat = (*function) ();
  32. if (active) {
  33. use_mouse_msg();
  34. }
  35. Menu_msg("");
  36. return stat;
  37. }
  38. static int mouse(Objects * objects, int ax, int ay, int box)
  39. {
  40. int first;
  41. int stat;
  42. int x, y, button;
  43. Objects *obj;
  44. first = !active;
  45. active = 1;
  46. if (first)
  47. use_mouse_msg();
  48. if (box) {
  49. x = ax + 20;
  50. y = ay + 20;
  51. }
  52. stat = 0;
  53. replot = 1;
  54. while (stat == 0) {
  55. if (replot) {
  56. replot = 0;
  57. draw_objects(objects);
  58. }
  59. if (box)
  60. Mouse_box_anchored(ax, ay, &x, &y, &button);
  61. else
  62. Mouse_pointer(&x, &y, &button);
  63. if (!(obj = find(objects, x, y)))
  64. continue;
  65. switch (obj->type) {
  66. case MENU_OBJECT:
  67. case OTHER_OBJECT:
  68. stat = (*obj->handler) (x, y, button);
  69. break;
  70. case OPTION_OBJECT:
  71. select_option(objects, obj);
  72. draw_option_boxes(objects);
  73. break;
  74. }
  75. }
  76. /* if we are first call, mark not active
  77. * indicate that objects above use must be replotted.
  78. */
  79. if (first)
  80. active = 0;
  81. Menu_msg("");
  82. return stat;
  83. }
  84. static int use_mouse_msg(void)
  85. {
  86. Curses_write_window(PROMPT_WINDOW, 1, 1, "Use mouse now ...\n");
  87. return 0;
  88. }
  89. static int draw_objects(Objects * objects)
  90. {
  91. Objects *obj;
  92. int top, bottom, left, right;
  93. int size, edge;
  94. /* erase the menu window */
  95. Erase_view(VIEW_MENU);
  96. R_flush();
  97. /* determine sizes and text indentation */
  98. size = VIEW_MENU->nrows - 4;
  99. edge = 2;
  100. R_text_size(size, size);
  101. left = VIEW_MENU->left;
  102. top = VIEW_MENU->top;
  103. bottom = VIEW_MENU->bottom;
  104. /* put the (boxed) text on the menu view */
  105. for (obj = objects; obj->type; obj++) {
  106. if (!visible(obj))
  107. continue;
  108. switch (obj->type) {
  109. case OPTION_OBJECT:
  110. case MENU_OBJECT:
  111. right = left + 2 * edge + Text_width(obj->label);
  112. obj->left = left;
  113. obj->right = right;
  114. obj->top = top;
  115. obj->bottom = bottom;
  116. R_standard_color(FILL_COLOR);
  117. R_box_abs(left, top, right, bottom);
  118. R_standard_color(TEXT_COLOR);
  119. Text(obj->label, top, bottom, left, right, edge);
  120. R_standard_color(OUTLINE_COLOR);
  121. Outline_box(top, bottom, left, right);
  122. left = right;
  123. break;
  124. case INFO_OBJECT:
  125. if (*obj->label == 0)
  126. break;
  127. if (*obj->status < 0)
  128. break;
  129. right = left + 2 * edge + Text_width(obj->label);
  130. R_standard_color(WHITE);
  131. Text(obj->label, top, bottom, left, right, edge);
  132. left = right;
  133. break;
  134. }
  135. }
  136. draw_option_boxes(objects);
  137. R_flush();
  138. return 0;
  139. }
  140. static Objects *find(Objects * objects, int x, int y)
  141. {
  142. Objects *other;
  143. other = NULL;
  144. for (; objects->type; objects++) {
  145. if (!visible(objects))
  146. continue;
  147. switch (objects->type) {
  148. case MENU_OBJECT:
  149. case OPTION_OBJECT:
  150. if (x >= objects->left && x <= objects->right
  151. && y >= objects->top && y <= objects->bottom)
  152. return objects;
  153. break;
  154. case OTHER_OBJECT:
  155. other = objects;
  156. break;
  157. }
  158. }
  159. return other;
  160. }
  161. static int select_option(Objects * objects, Objects * obj)
  162. {
  163. while (objects->type) {
  164. if (objects->type == OPTION_OBJECT && *objects->status >= 0 &&
  165. objects->binding == obj->binding)
  166. *objects->status = 0;
  167. objects++;
  168. }
  169. *obj->status = 1;
  170. return 0;
  171. }
  172. static int draw_option_boxes(Objects * objects)
  173. {
  174. Objects *x;
  175. R_standard_color(OUTLINE_COLOR);
  176. for (x = objects; x->type; x++) {
  177. if (x->type == OPTION_OBJECT && *x->status == 0)
  178. Outline_box(x->top + 1, x->bottom, x->left, x->right - 1);
  179. }
  180. R_standard_color(GREEN);
  181. for (x = objects; x->type; x++) {
  182. if (x->type == OPTION_OBJECT && *x->status > 0)
  183. Outline_box(x->top + 1, x->bottom, x->left, x->right - 1);
  184. }
  185. R_flush();
  186. return 0;
  187. }
  188. static int visible(Objects * object)
  189. {
  190. if (object->type == OPTION_OBJECT)
  191. return (*object->status >= 0);
  192. return (*object->status > 0);
  193. }
  194. int Menu_msg(char *msg)
  195. {
  196. int size, edge;
  197. size = VIEW_MENU->nrows - 4;
  198. edge = 2;
  199. Erase_view(VIEW_MENU);
  200. if (*msg) {
  201. R_text_size(size, size);
  202. R_standard_color(WHITE);
  203. Text(msg, VIEW_MENU->top, VIEW_MENU->bottom,
  204. VIEW_MENU->left, VIEW_MENU->right, edge);
  205. }
  206. R_flush();
  207. replot = 1;
  208. return 0;
  209. }
  210. int Start_mouse_in_menu(void)
  211. {
  212. Set_mouse_xy((VIEW_MENU->left + 2 * VIEW_MENU->right) / 3,
  213. (VIEW_MENU->top + VIEW_MENU->bottom) / 2);
  214. return 0;
  215. }