input.c 5.0 KB

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