list_box.cc 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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/list_box.hh"
  9. #include "gui/button.hh"
  10. #include "gui/deco_win.hh"
  11. #include "gui/image_win.hh"
  12. void i4_list_box_class:: set_top(i4_menu_item_class *item)
  13. {
  14. if (top)
  15. delete top;
  16. top=item->copy();
  17. int h=top->height() >= height()-(t+b) ? top->height() : height()-(t+b);
  18. top->set_menu_parent(this);
  19. top->resize(width()-(l+r)-down->width(), h);
  20. top->do_deactivate();
  21. i4_parent_window_class::add_child(l,t, top);
  22. }
  23. i4_list_box_class::~i4_list_box_class()
  24. {
  25. hide();
  26. for (int i=0; i<entries.size(); i++)
  27. delete entries[i];
  28. if (top)
  29. delete top;
  30. }
  31. i4_list_box_class::i4_list_box_class(w16 w,
  32. i4_graphical_style_class *style,
  33. i4_parent_window_class *root_window)
  34. : i4_menu_class(i4_F), entries(0,8), style(style), root_window(root_window)
  35. {
  36. i4_image_class *down_im=style->icon_hint->down_icon;
  37. down=new i4_button_class(0, new i4_image_window_class(down_im), style,
  38. 0,
  39. new i4_event_reaction_class(this, 1));
  40. down->set_popup(i4_T);
  41. l=1; r=1; t=1; b=1;
  42. resize(w, down->height()+(t+b));
  43. i4_parent_window_class::add_child(w-down->width()-r, t, down);
  44. top=0;
  45. pull_down=0;
  46. current=0;
  47. }
  48. void i4_list_box_class::parent_draw(i4_draw_context_class &context)
  49. {
  50. local_image->clear(0, context);
  51. // style->draw_in_deco(local_image, 0,0,width()-1, height()-1, i4_F, context);
  52. }
  53. void i4_list_box_class::add_item(i4_menu_item_class *item)
  54. {
  55. if (item->height()+t+b>height())
  56. resize(width(), item->height()+t+b);
  57. if (entries.size()==0)
  58. set_top(item);
  59. entries.add(item);
  60. item->set_menu_parent(this);
  61. }
  62. void i4_list_box_class::set_current_item(int entry_num)
  63. {
  64. if (entry_num>=0 && entry_num<entries.size())
  65. {
  66. set_top(entries[entry_num]);
  67. current=entry_num;
  68. }
  69. }
  70. class i4_list_pull_down_class : public i4_deco_window_class
  71. {
  72. i4_window_class *buddy;
  73. public:
  74. i4_list_pull_down_class(w16 w, w16 h, i4_window_class *buddy, i4_graphical_style_class *style)
  75. : i4_deco_window_class(w,h, i4_T, style), buddy(buddy)
  76. {
  77. }
  78. void grab()
  79. {
  80. i4_window_request_mouse_grab_class grab(this);
  81. i4_kernel.send_event(parent, &grab);
  82. }
  83. void receive_event(i4_event *ev)
  84. {
  85. if (ev->type()==i4_event::MOUSE_BUTTON_DOWN)
  86. {
  87. CAST_PTR(mev, i4_mouse_move_event_class, ev);
  88. if (mev->x<0 || mev->y<0 || mev->x>=width() || mev->y>=height())
  89. {
  90. i4_window_request_mouse_ungrab_class ungrab(this);
  91. i4_kernel.send_event(parent, &ungrab);
  92. i4_user_message_event_class uev(1);
  93. i4_kernel.send_event(buddy, &uev);
  94. }
  95. }
  96. i4_deco_window_class::receive_event(ev);
  97. }
  98. char *name() { return "list_box_pull_down"; }
  99. };
  100. void i4_list_box_class::show(i4_parent_window_class *show_on, i4_coord px, i4_coord py)
  101. {
  102. if (!pull_down)
  103. {
  104. int i, y=0, x;
  105. for (i=0; i<entries.size(); i++)
  106. y+=entries[i]->height();
  107. pull_down=new i4_list_pull_down_class(width()-(l+r), y, this, style);
  108. y=pull_down->get_y1();
  109. x=pull_down->get_x1();
  110. for (i=0; i<entries.size(); i++)
  111. {
  112. entries[i]->resize(width(), entries[i]->height());
  113. pull_down->add_child(x,y, entries[i]);
  114. y+=entries[i]->height();
  115. }
  116. show_on->add_child(px,py, pull_down);
  117. pull_down->grab();
  118. }
  119. }
  120. void i4_list_box_class::hide()
  121. {
  122. if (pull_down)
  123. {
  124. for (int i=0; i<entries.size(); i++)
  125. pull_down->remove_child(entries[i]);
  126. root_window->remove_child(pull_down);
  127. delete pull_down;
  128. pull_down=0;
  129. }
  130. }
  131. void i4_list_box_class::receive_event(i4_event *ev)
  132. {
  133. if (ev->type()==i4_event::USER_MESSAGE)
  134. {
  135. if (!pull_down)
  136. show(root_window, x(), y()+height());
  137. else hide();
  138. }
  139. else
  140. i4_menu_class::receive_event(ev);
  141. }
  142. void i4_list_box_class::note_reaction_sent(i4_menu_item_class *who, // this is who sent it
  143. i4_event_reaction_class *ev, // who it was to
  144. i4_menu_item_class::reaction_type type)
  145. {
  146. if (type==i4_menu_item_class::PRESSED)
  147. {
  148. if (who==top)
  149. show(root_window, x(), y()+height());
  150. else
  151. {
  152. for (int i=0; i<entries.size(); i++)
  153. if (entries[i]==who)
  154. set_current_item(i);
  155. hide();
  156. }
  157. }
  158. }