list_pick.cc 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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. #ifdef _MANGLE_INC
  9. #include "LIST_~LE.HH"
  10. #else
  11. #include "list_pick.hh"
  12. #endif
  13. #include "menu/menuitem.hh"
  14. #include "image/image.hh"
  15. #ifdef _MANGLE_INC
  16. #include "gui/SCROL~OK.HH"
  17. #else
  18. #include "gui/scroll_bar.hh"
  19. #endif
  20. i4_list_pick::i4_list_pick(w16 width, w16 height,
  21. w32 total_items,
  22. i4_menu_item_class **items,
  23. w32 scroll_event_id,
  24. i4_color background,
  25. i4_bool free_items)
  26. : i4_parent_window_class(width, height),
  27. total_items(total_items),
  28. items(items),
  29. background(background),
  30. scroll_event_id(scroll_event_id),
  31. free_items(free_items)
  32. {
  33. need_draw_all=i4_T;
  34. start=0;
  35. end=-1;
  36. for (w32 i=0; i<total_items; i++)
  37. {
  38. if (items[i]->width()>length)
  39. length=items[i]->width();
  40. }
  41. length+=8;
  42. reposition_start(0);
  43. }
  44. i4_list_pick::~i4_list_pick()
  45. {
  46. if (free_items)
  47. {
  48. for (w32 i=0; i<total_items; i++)
  49. delete items[i];
  50. i4_free(items);
  51. }
  52. }
  53. void i4_list_pick::reposition_start(w32 new_start)
  54. {
  55. sw32 old_end=end,old_start=start,i;
  56. i4_coord x1=x(),y1=y(),x2=x()+width(),y2=y()+height();
  57. if (new_start!=start)
  58. need_draw_all=i4_T;
  59. i4_window_class *c;
  60. for (i=new_start; x1<x2 && i<total_items;)
  61. {
  62. c=items[i];
  63. if (c->height()+y1>=y2)
  64. {
  65. x1+=length;
  66. y1=y();
  67. }
  68. if (i>=end || i<start)
  69. {
  70. // i4_warning("add %d",i);
  71. add_child(x1,y1,c);
  72. }
  73. else
  74. {
  75. // i4_warning("move %d",i);
  76. c->move(x1-c->x(),y1-c->y());
  77. }
  78. y1+=c->height();
  79. i++;
  80. }
  81. start=new_start;
  82. end=i;
  83. if (old_start<start && old_end>=start)
  84. {
  85. for (i=old_start; i<start; i++)
  86. {
  87. // i4_warning("remove %d",i);
  88. remove_child(items[i]);
  89. }
  90. }
  91. if (old_start<=end && old_end>end)
  92. {
  93. for (i=end; i<old_end; i++)
  94. {
  95. // i4_warning("remove %d",i);
  96. remove_child(items[i]);
  97. }
  98. }
  99. if (old_end<start || old_start>end)
  100. {
  101. for (i=old_start; i<old_end; i++)
  102. {
  103. // i4_warning("remove %d",i);
  104. remove_child(items[i]);
  105. }
  106. }
  107. }
  108. void i4_list_pick::parent_draw(i4_draw_context_class &context)
  109. {
  110. if (need_draw_all)
  111. {
  112. local_image->add_dirty(0,0, width()-1, height()-1, context);
  113. local_image->clear(background,context);
  114. need_draw_all=i4_F;
  115. }
  116. else
  117. {
  118. i4_rect_list_class child_clip(&context.clip,0,0);
  119. child_clip.intersect_list(&undrawn_area);
  120. child_clip.swap(&context.clip);
  121. local_image->clear(background,context);
  122. child_clip.swap(&context.clip);
  123. }
  124. }
  125. void i4_list_pick::receive_event(i4_event *ev)
  126. {
  127. if (ev->type()==i4_event::USER_MESSAGE)
  128. {
  129. CAST_PTR(uev, i4_user_message_event_class, ev);
  130. if (uev->sub_type==scroll_event_id)
  131. {
  132. CAST_PTR(sc_msg, i4_scroll_message, ev);
  133. reposition_start(sc_msg->amount*total_items/sc_msg->scroll_total);
  134. }
  135. else i4_parent_window_class::receive_event(ev);
  136. }
  137. else i4_parent_window_class::receive_event(ev);
  138. }
  139. // draw should redraw supplied area of self
  140. void i4_list_pick::draw(i4_draw_context_class &context)
  141. {
  142. if (!undrawn_area.empty() || redraw_flag)
  143. {
  144. redraw_flag=i4_F;
  145. parent_draw(context);
  146. undrawn_area.delete_list();
  147. }
  148. if (child_need_redraw)
  149. {
  150. child_need_redraw=i4_F;
  151. win_iter c=children.begin();
  152. for (;c!=children.end();++c)
  153. {
  154. if (c->need_redraw())
  155. {
  156. // copy the clip list, and move it to local coordinates
  157. i4_rect_list_class child_clip(&context.clip,
  158. -(c->x()-x()),
  159. -(c->y()-y()));
  160. // intersect the clip with what our area is supposed to be
  161. child_clip.intersect_area(0,0,
  162. c->width()-1,
  163. c->height()-1);
  164. sw16 old_xoff=context.xoff,old_yoff=context.yoff; // save the old context xoff and yoff
  165. context.xoff+=(c->x()-x()); // move the context offset to the child's x,y
  166. context.yoff+=(c->y()-y());
  167. child_clip.swap(&context.clip);
  168. c->draw(context); // the child is ready to draw
  169. context.xoff=old_xoff; // restore the context's x & y offsets
  170. context.yoff=old_yoff;
  171. child_clip.swap(&context.clip); // restore the old clip list
  172. }
  173. }
  174. }
  175. }