button.cc 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /********************************************************************** <BR>
  2. This file is part of Crack dot Com's free source code release of
  3. Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
  4. information about compiling & licensing issues visit this URL</a>
  5. <PRE> If that doesn't help, contact Jonathan Clark at
  6. golgotha_source@usa.net (Subject should have "GOLG" in it)
  7. ***********************************************************************/
  8. #include "gui/button.hh"
  9. #include "device/kernel.hh"
  10. #include "device/keys.hh"
  11. #include "window/win_evt.hh"
  12. i4_button_class::i4_button_class(const i4_const_str *idle_context_help, // can be null
  13. i4_window_class *child,
  14. i4_graphical_style_class *hint,
  15. i4_event_reaction_class *press,
  16. i4_event_reaction_class *depress,
  17. i4_event_reaction_class *activate,
  18. i4_event_reaction_class *deactivate) :
  19. i4_menu_item_class(idle_context_help,
  20. hint,
  21. child ? child->width()+4 : 0,
  22. child ? child->height()+4 : 0,
  23. press,depress,
  24. activate,
  25. deactivate),
  26. decore(child)
  27. {
  28. popup=i4_F;
  29. state=WAIT_CLICK;
  30. repeat_down=i4_F;
  31. repeat_event=0;
  32. grabbing=i4_F;
  33. if (child)
  34. add_child(2,2,child);
  35. }
  36. i4_button_class::~i4_button_class()
  37. {
  38. if (decore)
  39. {
  40. remove_child(decore);
  41. delete decore;
  42. if (grabbing)
  43. {
  44. I4_ASSERT(parent, "~button/grab/and no parent");
  45. i4_window_request_mouse_ungrab_class ungrab(this);
  46. i4_kernel.send_event(parent,&ungrab);
  47. }
  48. }
  49. }
  50. void i4_button_class::reparent(i4_image_class *draw_area, i4_parent_window_class *par)
  51. {
  52. if (grabbing && !draw_area)
  53. {
  54. grabbing=i4_F;
  55. i4_window_request_mouse_ungrab_class ungrab(this);
  56. i4_kernel.send_event(parent,&ungrab);
  57. }
  58. i4_menu_item_class::reparent(draw_area, par);
  59. }
  60. void i4_button_class::receive_event(i4_event *ev)
  61. {
  62. if (!disabled)
  63. {
  64. if (ev->type()==i4_event::OBJECT_MESSAGE)
  65. {
  66. CAST_PTR(oev,i4_object_message_event_class,ev);
  67. if (oev->object==this)
  68. {
  69. i4_kernel.not_idle();
  70. if (repeat_event)
  71. send_event(repeat_event, PRESSED);
  72. else
  73. send_event(send.press, PRESSED);
  74. time_id=i4_time_dev.request_event(this,
  75. new i4_object_message_event_class(this),
  76. hint->time_hint->button_repeat);
  77. state=WAIT_REPEAT;
  78. } else i4_menu_item_class::receive_event(ev);
  79. }
  80. else if (ev->type()==i4_event::MOUSE_BUTTON_DOWN)
  81. {
  82. CAST_PTR(b,i4_mouse_button_down_event_class,ev);
  83. if (b->but==i4_mouse_button_down_event_class::LEFT)
  84. {
  85. if (pressed)
  86. {
  87. do_depress();
  88. send_event(send.depress, DEPRESSED);
  89. }
  90. else
  91. {
  92. do_press();
  93. send_event(send.press, PRESSED);
  94. if (!grabbing)
  95. {
  96. i4_window_request_mouse_grab_class grab(this);
  97. i4_kernel.send_event(parent,&grab);
  98. grabbing=i4_T;
  99. }
  100. if (repeat_down)
  101. {
  102. i4_kernel.not_idle();
  103. time_id=i4_time_dev.request_event(this,
  104. new i4_object_message_event_class(this),
  105. hint->time_hint->button_delay);
  106. state=WAIT_DELAY;
  107. }
  108. }
  109. }
  110. } else if (ev->type()==i4_event::MOUSE_BUTTON_UP)
  111. {
  112. CAST_PTR(b,i4_mouse_button_down_event_class,ev);
  113. if (b->but==i4_mouse_button_down_event_class::LEFT)
  114. {
  115. if (grabbing)
  116. {
  117. grabbing=i4_F;
  118. i4_window_request_mouse_ungrab_class ungrab(this);
  119. i4_kernel.send_event(parent,&ungrab);
  120. }
  121. if (state==WAIT_DELAY || state==WAIT_REPEAT)
  122. {
  123. i4_time_dev.cancel_event(time_id);
  124. state=WAIT_CLICK;
  125. }
  126. if (pressed && popup)
  127. {
  128. do_depress();
  129. send_event(send.depress, DEPRESSED);
  130. }
  131. }
  132. }
  133. else if (ev->type()==i4_event::KEY_PRESS)
  134. {
  135. CAST_PTR(k,i4_key_press_event_class,ev);
  136. if (k->key==I4_ENTER)
  137. {
  138. if (pressed)
  139. {
  140. do_depress();
  141. send_event(send.depress, DEPRESSED);
  142. }
  143. else
  144. {
  145. do_press();
  146. send_event(send.press, PRESSED);
  147. }
  148. } else if (k->key==I4_TAB)
  149. {
  150. i4_window_message_class t(i4_window_message_class::REQUEST_NEXT_KEY_FOCUS,this);
  151. i4_kernel.send_event(parent, &t);
  152. }
  153. else if (k->key==I4_LEFT)
  154. {
  155. i4_window_message_class l(i4_window_message_class::REQUEST_LEFT_KEY_FOCUS,this);
  156. i4_kernel.send_event(parent, &l);
  157. }
  158. else if (k->key==I4_RIGHT)
  159. {
  160. i4_window_message_class r(i4_window_message_class::REQUEST_RIGHT_KEY_FOCUS,this);
  161. i4_kernel.send_event(parent, &r);
  162. }
  163. else if (k->key==I4_UP)
  164. {
  165. i4_window_message_class u(i4_window_message_class::REQUEST_UP_KEY_FOCUS,this);
  166. i4_kernel.send_event(parent, &u);
  167. }
  168. else if (k->key==I4_DOWN)
  169. {
  170. i4_window_message_class d(i4_window_message_class::REQUEST_DOWN_KEY_FOCUS,this);
  171. i4_kernel.send_event(parent, &d);
  172. }
  173. } else
  174. i4_menu_item_class::receive_event(ev);
  175. } else i4_menu_item_class::receive_event(ev);
  176. }
  177. void i4_button_class::parent_draw(i4_draw_context_class &context)
  178. {
  179. local_image->add_dirty(0,0,width()-1,height()-1,context);
  180. i4_color_hint_class::bevel *color;
  181. if (active)
  182. color=&hint->color_hint->button.active;
  183. else
  184. color=&hint->color_hint->button.passive;
  185. i4_color b,d,m=color->medium;
  186. if (!pressed)
  187. {
  188. b=color->bright;
  189. d=color->dark;
  190. } else
  191. {
  192. b=color->dark;
  193. d=color->bright;
  194. }
  195. local_image->bar(0,0,width()-1,0,b,context);
  196. local_image->bar(0,0,0,height()-1,b,context);
  197. local_image->bar(1,1,width()-2,1,m,context);
  198. local_image->bar(1,1,1,height()-2,m,context);
  199. local_image->bar(2,height()-2,width()-2,height()-2,d,context);
  200. local_image->bar(width()-2,2,width()-2,height()-2,d,context);
  201. local_image->bar(0,height()-1,width()-1,height()-1,hint->color_hint->black,context);
  202. local_image->bar(width()-1,0,width()-1,height()-1,hint->color_hint->black,context);
  203. local_image->bar(2,2,width()-3,height()-3,color->medium,context);
  204. }
  205. void i4_button_class::set_popup(i4_bool value)
  206. {
  207. popup=value;
  208. }
  209. void i4_button_class::set_repeat_down(i4_bool value, i4_event_reaction_class *_repeat_event)
  210. {
  211. if (!value && (state==WAIT_DELAY || state==WAIT_REPEAT))
  212. i4_time_dev.cancel_event(time_id);
  213. state=WAIT_CLICK;
  214. repeat_down=value;
  215. if (repeat_event) delete repeat_event;
  216. repeat_event=_repeat_event;
  217. }