source: golgotha/src/i4/gui/scroll_bar.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 12 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: 9.2 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#include "gui/scroll_bar.hh"
10#include "window/colorwin.hh"
11#include "image/image.hh"
12#include "gui/button.hh"
13#include "gui/image_win.hh"
14#include "window/win_evt.hh"
15
16
17
18inline void draw_out_deco(i4_image_class *screen,
19                          i4_draw_context_class &context,
20                          i4_coord x1, i4_coord y1, i4_coord x2, i4_coord y2,
21                          i4_color bright, i4_color medium, i4_color dark, i4_color black)
22{
23  screen->add_dirty(x1,y1,x2,y2,context);
24
25  screen->bar(x1,y1,x2-1,y1, bright, context);
26  screen->bar(x1,y1,x1,y2-1, bright, context);
27  screen->bar(x1,y2-1,x2-1,y2-1, dark, context);
28  screen->bar(x2-1,y1+1,x2-1,y2-1, dark, context);
29
30  screen->bar(x1,y2,x2,y2, black, context);
31  screen->bar(x2,y1,x2,y2, black, context);
32  screen->bar(x1+1, y1+1, x2-2, y2-2, medium, context);
33 
34}
35
36
37class i4_scroll_button : public i4_window_class
38{
39  i4_bool active,dragging;
40  i4_scroll_bar *buddy;
41
42  void reparent(i4_image_class *draw_area, i4_parent_window_class *parent)
43  {
44    i4_window_class::reparent(draw_area, parent);
45    if (parent)
46      fit_parent();
47  }
48
49  i4_bool vertical() { return buddy->vertical; }
50  i4_graphical_style_class *style() { return buddy->style; }
51
52
53
54public:
55  void fit_parent()
56  {   
57    if (vertical())
58      resize(parent->width(),
59             parent->height() * buddy->total_visible_objects / buddy->total_scroll_objects);
60    else
61      resize(parent->width() * buddy->total_visible_objects / buddy->total_scroll_objects,
62             parent->height());
63  }
64
65  char *name() { return "scroll_button"; }
66
67
68  i4_scroll_button(i4_scroll_bar *buddy)
69    : i4_window_class(0,0),
70      buddy(buddy)
71  {
72    active=i4_F;
73    dragging=i4_F;
74  }
75
76  void draw(i4_draw_context_class &context)
77  {
78    i4_color_hint_class::bevel *color;
79    if (active)
80      color=&style()->color_hint->window.active;
81    else
82      color=&style()->color_hint->window.passive;
83
84    draw_out_deco(local_image,context,
85                  0,0,width()-1,height()-1,
86                  color->bright,
87                  color->medium,
88                  color->dark,
89                  style()->color_hint->black);
90  }
91
92  void receive_event(i4_event *ev)
93  {
94    switch (ev->type())
95    {
96      case i4_event::WINDOW_MESSAGE :
97      {
98        CAST_PTR(wev,i4_window_message_class,ev);
99        if (wev->sub_type==i4_window_message_class::GOT_MOUSE_FOCUS)
100        {
101          active=i4_T;
102          request_redraw();
103        }
104        else if (wev->sub_type==i4_window_message_class::LOST_MOUSE_FOCUS)
105        {
106          active=i4_F;
107          request_redraw();
108        }
109      } break;
110      case i4_event::MOUSE_MOVE :
111      {
112        CAST_PTR(mev,i4_mouse_move_event_class,ev);
113        if (dragging)
114        {
115          if (vertical())
116          {
117            i4_coord new_y=mev->y+y()-parent->y()-height()/2;  // convert to parent coords
118            if (new_y<0)
119              new_y=0;
120            else if (new_y+height()>=parent->height())
121              new_y=parent->height()-height();
122
123            new_y=new_y+parent->y()-y();  // convert back to our coord system
124            if (new_y!=y())
125            {
126              move(0,new_y);
127              buddy->calc_pos();
128              buddy->send_position();
129            }
130          }
131          else
132          {
133            i4_coord new_x=mev->x+x()-parent->x()-width()/2;  // convert to parent coords
134            if (new_x<0)
135              new_x=0;
136            else if (new_x+width()>=parent->width())
137              new_x=parent->width()-width();
138
139            new_x=new_x+parent->x()-x();  // convert back to our coord system
140            if (new_x!=x())
141            {
142              move(new_x, 0);
143              buddy->calc_pos();
144              buddy->send_position();
145            }
146          }
147        }
148      } break;
149
150      case i4_event::MOUSE_BUTTON_DOWN :
151      {
152        CAST_PTR(bev,i4_mouse_button_down_event_class,ev);
153        if (bev->but==i4_mouse_button_down_event_class::LEFT)
154        {
155          dragging=i4_T;
156          i4_window_request_mouse_grab_class grab(this);
157          i4_kernel.send_event(parent,&grab);
158        }
159      } break;
160
161      case i4_event::MOUSE_BUTTON_UP :
162      {
163        CAST_PTR(bev,i4_mouse_button_up_event_class,ev);
164        if (bev->but==i4_mouse_button_up_event_class::LEFT)
165        {
166          dragging=i4_F;
167          i4_window_request_mouse_ungrab_class ungrab(this);
168          i4_kernel.send_event(parent,&ungrab);
169        }
170      } break;
171
172
173    }
174  }
175
176} ;
177
178
179// if total items under control changes
180void i4_scroll_bar::set_new_total(int total)
181{
182  total_scroll_objects=total;
183  if (total_scroll_objects<=0)
184    total_scroll_objects=1;
185
186  scroll_but->fit_parent();
187}
188
189i4_button_class *i4_scroll_bar::create_button(i4_button_class *&b, i4_image_class *im)
190{
191  b=new i4_button_class(0, new i4_image_window_class(im), style);
192
193  b->send.press=new i4_event_reaction_class(this, new i4_object_message_event_class(b));
194  b->set_repeat_down(i4_T);
195  b->set_popup(i4_T);
196 
197  return b;
198}
199
200i4_scroll_bar::i4_scroll_bar(i4_bool vertical,
201                             int max_dimention_size,
202                             int total_visible_objects,
203                             int total_scroll_objects,    // total number of objects
204                             w32 message_id,
205                             i4_event_handler_class *send_to,
206                             i4_graphical_style_class *style)
207
208  : i4_parent_window_class(0,0),
209    vertical(vertical),
210    total_scroll_objects(total_scroll_objects),
211    total_visible_objects(total_visible_objects),
212    id(message_id),
213    send_to(send_to),
214    style(style)
215{
216  pos=0;
217  if (vertical)
218  {
219    add_child(0,0, create_button(up_but, style->icon_hint->up_icon));
220
221    create_button(down_but, style->icon_hint->down_icon);
222    add_child(0, max_dimention_size-down_but->height(), down_but);
223
224    left_but=right_but=0;
225
226    resize(up_but->width(), max_dimention_size);
227  }
228  else
229  {
230    add_child(0,0, create_button(left_but, style->icon_hint->left_icon));
231
232    create_button(right_but, style->icon_hint->right_icon);
233    add_child(max_dimention_size-right_but->width(),0, right_but);
234    up_but=down_but=0;   
235
236    resize(max_dimention_size,  left_but->height());
237  }
238
239
240  int x=vertical ? 0 : left_but->width(),
241    y=vertical ? up_but->height() : 0;
242  int sa_w=vertical ? width() : width() - left_but->width() - right_but->height(),
243    sa_h=vertical ? height() - up_but->width() - down_but->height() : height();
244
245  // area where scroll grab button resides
246  scroll_area=i4_add_color_window(this,
247                                  style->color_hint->window.passive.dark,
248                                  style, x,y, sa_w, sa_h);
249
250
251  scroll_but=new i4_scroll_button(this);
252  scroll_area->add_child(0,0,scroll_but);
253
254}
255 
256void i4_scroll_bar::receive_event(i4_event *ev)
257{
258  if (ev->type()==i4_event::OBJECT_MESSAGE)
259  {
260    CAST_PTR(oev,i4_object_message_event_class,ev);
261    if (oev->object==down_but || oev->object==right_but)
262    {   
263      if (pos<total_scroll_objects-1)
264      {
265        pos+=1;
266        set_bar_pos(pos);
267        send_position();
268      }           
269    } else if (oev->object==up_but || oev->object==left_but)
270    {
271      if (pos>0)
272      {
273        pos-=1;
274        set_bar_pos(pos);
275        send_position();
276      }           
277    }
278
279  } else i4_parent_window_class::receive_event(ev);
280}
281
282void i4_scroll_bar::set_bar_pos(sw32 pos)
283{
284  sw32 reverse_pos;
285
286  if (vertical)
287  {
288    if (total_scroll_objects<=1)
289      reverse_pos=0;
290    else
291      reverse_pos=pos*(scroll_area->height()-scroll_but->height())/(total_scroll_objects-1);
292
293    scroll_but->move(0,reverse_pos- (scroll_but->y()-scroll_area->y()));
294  }
295  else
296  {
297    if (total_scroll_objects<=1)
298      reverse_pos=0;
299    else
300      reverse_pos=pos*(scroll_area->width()-scroll_but->width())/(total_scroll_objects-1);
301
302    scroll_but->move(reverse_pos- (scroll_but->x()-scroll_area->x()),0);
303  }
304                   
305}
306
307void i4_scroll_bar::calc_pos()
308{
309  if (total_visible_objects>=total_scroll_objects || total_scroll_objects<=1)
310    pos=0;
311  else if (vertical)
312    pos=(scroll_but->y()-scroll_area->y()) * (total_scroll_objects-1) /
313      (scroll_area->height()-scroll_but->height());
314  else
315    pos=(scroll_but->x()-scroll_area->x()) * (total_scroll_objects-1) /
316      (scroll_area->width()-scroll_but->width());
317
318}
319
320void i4_scroll_bar::send_position()
321{
322  if (send_to)
323  {
324    //    i4_vscroll_button *b=(i4_vscroll_button *)scroll_but;
325    i4_scroll_message message(pos, total_scroll_objects, id);
326    i4_kernel.send_event(send_to,&message);
327  } 
328}
329
Note: See TracBrowser for help on using the repository browser.