source: golgotha/src/i4/gui/list_pick.cc @ 608

Last change on this file since 608 was 80, checked in by Sam Hocevar, 15 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 5.1 KB
Line 
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
9
10#ifdef _MANGLE_INC
11#include "LIST_~LE.HH"
12#else
13#include "list_pick.hh"
14#endif
15#include "menu/menuitem.hh"
16#include "image/image.hh"
17#ifdef _MANGLE_INC
18#include "gui/SCROL~OK.HH"
19#else
20#include "gui/scroll_bar.hh"
21#endif
22
23i4_list_pick::i4_list_pick(w16 width, w16 height,
24                           w32 total_items,
25                           i4_menu_item_class **items,
26                           w32 scroll_event_id,
27                           i4_color background,
28                           i4_bool free_items)
29
30  : i4_parent_window_class(width, height),
31    total_items(total_items),
32    items(items),
33    background(background),
34    scroll_event_id(scroll_event_id),
35    free_items(free_items)
36{
37  need_draw_all=i4_T;
38  start=0;
39  end=-1;
40  for (w32 i=0; i<total_items; i++)
41  {
42    if (items[i]->width()>length)
43      length=items[i]->width();
44  }
45  length+=8;
46  reposition_start(0);
47}
48
49
50
51
52i4_list_pick::~i4_list_pick()
53{
54  if (free_items)
55  {
56    for (w32 i=0; i<total_items; i++)
57      delete items[i];
58    i4_free(items);
59  }
60
61}
62
63void i4_list_pick::reposition_start(w32 new_start)
64{
65  sw32 old_end=end,old_start=start,i;
66  i4_coord x1=x(),y1=y(),x2=x()+width(),y2=y()+height();
67
68  if (new_start!=start)
69    need_draw_all=i4_T;
70
71  i4_window_class *c;
72
73  for (i=new_start; x1<x2 && i<total_items;)
74  {
75    c=items[i];
76
77
78    if (c->height()+y1>=y2)
79    {
80      x1+=length;
81      y1=y();
82    }
83
84    if (i>=end || i<start)
85    {
86      //      i4_warning("add    %d",i);
87      add_child(x1,y1,c);
88    }
89    else
90    {
91      //      i4_warning("move   %d",i);
92      c->move(x1-c->x(),y1-c->y());
93    }
94
95    y1+=c->height();
96    i++;
97  }
98
99  start=new_start;
100  end=i;
101
102  if (old_start<start && old_end>=start)
103  {
104    for (i=old_start; i<start; i++)
105    {
106      //      i4_warning("remove %d",i);
107      remove_child(items[i]);
108    }
109  }
110
111  if (old_start<=end && old_end>end)
112  {
113    for (i=end; i<old_end; i++)
114    {
115      //      i4_warning("remove %d",i);
116      remove_child(items[i]);
117    }
118  }
119
120
121  if (old_end<start || old_start>end)
122  {
123    for (i=old_start; i<old_end; i++)
124    {
125      //      i4_warning("remove %d",i);
126      remove_child(items[i]);
127    }
128  }
129}
130 
131void i4_list_pick::parent_draw(i4_draw_context_class &context)
132{
133  if (need_draw_all)
134  {
135    local_image->add_dirty(0,0, width()-1, height()-1, context);
136    local_image->clear(background,context);   
137    need_draw_all=i4_F;
138  }
139  else
140  {
141    i4_rect_list_class child_clip(&context.clip,0,0);
142    child_clip.intersect_list(&undrawn_area);
143
144    child_clip.swap(&context.clip);
145
146    local_image->clear(background,context);
147
148    child_clip.swap(&context.clip);
149  }
150}
151
152
153void i4_list_pick::receive_event(i4_event *ev)
154{
155  if (ev->type()==i4_event::USER_MESSAGE)
156  {
157    CAST_PTR(uev, i4_user_message_event_class, ev);
158    if (uev->sub_type==scroll_event_id)
159    {
160      CAST_PTR(sc_msg, i4_scroll_message, ev);
161      reposition_start(sc_msg->amount*total_items/sc_msg->scroll_total);
162    }
163    else i4_parent_window_class::receive_event(ev);   
164  }
165  else i4_parent_window_class::receive_event(ev);
166}
167
168
169
170// draw should redraw supplied area of self
171void i4_list_pick::draw(i4_draw_context_class &context)
172
173  if (!undrawn_area.empty() || redraw_flag)
174  {   
175    redraw_flag=i4_F;
176    parent_draw(context);
177    undrawn_area.delete_list();
178  }
179
180
181  if (child_need_redraw)
182  {
183    child_need_redraw=i4_F;
184    win_iter c=children.begin();
185    for (;c!=children.end();++c)   
186    {
187      if (c->need_redraw())
188      {         
189        // copy the clip list, and move it to local coordinates
190        i4_rect_list_class child_clip(&context.clip,
191                                      -(c->x()-x()),
192                                      -(c->y()-y()));         
193
194        // intersect the clip with what our area is supposed to be
195        child_clip.intersect_area(0,0,
196                                  c->width()-1,
197                                  c->height()-1);   
198
199        sw16 old_xoff=context.xoff,old_yoff=context.yoff;   // save the old context xoff and yoff
200        context.xoff+=(c->x()-x());                // move the context offset to the child's x,y
201        context.yoff+=(c->y()-y());
202
203        child_clip.swap(&context.clip);
204
205        c->draw(context);         // the child is ready to draw                   
206
207        context.xoff=old_xoff;    // restore the context's x & y offsets
208        context.yoff=old_yoff;
209
210
211        child_clip.swap(&context.clip);   // restore the old clip list
212      }     
213    }
214  }
215}
Note: See TracBrowser for help on using the repository browser.