Adonthell  0.4
win_select.cc
1 /*
2  (C) Copyright 2000 Joel Vennin
3  Part of the Adonthell Project <http://adonthell.nongnu.org>
4 
5  Adonthell is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  Adonthell is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with Adonthell. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include "win_select.h"
20 
21 #include "audio.h"
22 
23 win_select::win_select()
24 {
25  cur_select_ = list_wb_.begin();
26 
27  set_mode(MODE_BRIGHTNESS);
28 
29  border_select_ = NULL;
30 
31  set_circle(false);
32 
33  finish_scroll_ = true;
34  //set_visible_scrollbar(false);
35 }
36 
37 
38 void win_select::add(win_base * w)
39 {
40  win_scroll::add(w);
41  cur_select_ = list_wb_.begin ();
42  //if select has a border for the selection, just set border to the win_base added
43  if(border_select_ != NULL) w->set_border(*border_select_);
44 
45  //set the object to unselect
46  rules(false, w);
47 
48  set_default();
49 
50  //update_cur_select_position();
51 }
52 
53 
54 void win_select::remove(win_base * w)
55 {
56  rules(false, w);
57 
58  win_scroll::remove(w);
59 
60  set_default();
61 }
62 
63 
64 void win_select::remove_all()
65 {
66  win_scroll::remove_all();
67  cur_select_ = list_wb_.begin();
68 }
69 
70 
71 void win_select::next()
72 {
73  //test if next possible
74  if(cur_select_ == list_wb_.end() || list_wb_.size() == 0) return;
75 
76  audio::play_wave (-1, 1);
77  (*cur_select_)->on_unselect();
78 
79  //unselect cur element
80  rules(false,*cur_select_);
81  (*cur_select_)->set_activate (false);
82 
83  //create a temporary index
84  lwb :: iterator i = cur_select_;
85 
86  //go next
87  i++;
88 
89  //while not a the end, not be selected and different at old object go to the next
90  while( i != list_wb_.end() && !(*i)->is_can_be_selected() && i != cur_select_) i++;
91 
92  //if at end of list and select circle is activate
93  if(i == list_wb_.end())
94  {
95  //cur is the begin of list
96  if( circle_ )
97  {
98  i = list_wb_.begin();
99  while(i != list_wb_.end() && !(*i)->is_can_be_selected() && i != cur_select_) i++;
100  if(i != list_wb_.end()) cur_select_ = i;
101  }
102  }else cur_select_ = i;
103 
104  rules(true,*cur_select_);
105 
106  (*cur_select_)->on_select();
107 
108  on_next();
109 
110  finish_scroll_ =false;
111 
112  //update_cur_select_position();
113 }
114 
115 
116 void win_select::previous()
117 {
118  if(cur_select_==list_wb_.end() || list_wb_.size() == 0) return;
119 
120  audio::play_wave (-1, 1);
121  (*cur_select_)->on_unselect();
122 
123  //set to unselect object
124  rules(false,*cur_select_);
125 
126  (*cur_select_)->set_activate (false);
127 
128  lwb::iterator i=cur_select_;
129 
130  if(circle_)
131  {
132  if(i==list_wb_.begin()) i=list_wb_.end();
133  i--;
134  }
135  else if(i!=list_wb_.begin()) i--;
136 
137  while(i != list_wb_.begin() && !(*i)->is_can_be_selected() && i != cur_select_) i--;
138 
139  if( i== list_wb_.begin() && !(*i)->is_can_be_selected())
140  {
141  if(circle_)
142  {
143  i = list_wb_.end();
144  i--;
145  while(i!=list_wb_.begin() && !(*i)->is_can_be_selected() && i!=cur_select_) i--;
146  if((*i)->is_can_be_selected()) cur_select_=i;
147  }
148  } else cur_select_=i;
149 
150  (*cur_select_)->on_select();
151 
152  //set to select object
153  rules(true,*cur_select_);
154 
155  //update_position();
156  on_previous();
157 
158  finish_scroll_ =false;
159  //update_cur_select_position();
160 }
161 
162 
163 void win_select::activate()
164 {
165  if(cur_select_ == list_wb_.end()) return;
166 
167  audio::play_wave (-1, 0);
168 
169  //set_activate(false);
170 
171  (*cur_select_)->set_activate(true);
172 
173  on_activate_key();
174 }
175 
176 
178 {
179 
181  {
182  if(focus_object_) return true;
183 
184  if(input::has_been_pushed(win_keys::KEY_NEXT)) next();
185  if(input::has_been_pushed(win_keys::KEY_PREVIOUS)) previous();
186  if(input::has_been_pushed(win_keys::KEY_ACTIVATE) ||
187  input::has_been_pushed(win_keys::KEY_ACTIVATE_ENTRY)) activate();
188 
189  return true;
190  }
191  return false;
192 }
193 
194 void win_select::rules(const bool b, win_base * wb)
195 {
196  if(!wb->is_can_be_selected()) return;
197 
198  switch(mode_)
199  {
200  case MODE_BORDER:
201  wb->set_visible_border(b);
202  break;
203 
204  case MODE_BRIGHTNESS:
205  wb->set_brightness(!b);
206  break;
207  }
208 }
209 
210 
211 void win_select::set_default()
212 {
213  if(list_wb_.size() == 0) return;
214 
215  if(cur_select_ != list_wb_.end())
216  {
217  rules(false,*cur_select_);
218  }
219 
220  cur_select_ = list_wb_.begin();
221 
222  while(cur_select_ != list_wb_.end() && !(*cur_select_)->is_can_be_selected()) cur_select_++;
223 
224  if(cur_select_ != list_wb_.end()) rules(true,*cur_select_);
225 
226  finish_scroll_ =false;
227 }
228 
229 void win_select::set_default_object(const win_base * wb)
230 {
231  if(list_wb_.size() == 0) return;
232 
233  if(cur_select_ != list_wb_.end()) rules(false,*cur_select_);
234 
235  cur_select_ = list_wb_.begin();
236 
237  while(cur_select_ != list_wb_.end() && *cur_select_ != wb) cur_select_++;
238 
239  if(cur_select_ != list_wb_.end()) rules(true,*cur_select_);
240 
241  finish_scroll_ =false;
242  //update_cur_select_position();
243 }
244 
245 
246 void win_select::set_default_position(const u_int16 pos)
247 {
248  if(list_wb_.size() == 0 || pos > list_wb_.size()) return;
249 
250  if(cur_select_ != list_wb_.end()) rules(false,*cur_select_);
251 
252  cur_select_ = list_wb_.begin();
253 
254  u_int16 i = 0;
255 
256  while(cur_select_ != list_wb_.end() && i++ < pos) cur_select_++;
257 
258  if(cur_select_ != list_wb_.end()) rules(true,*cur_select_);
259 
260  finish_scroll_ =false;
261  //update_cur_select_position();
262 }
263 
264 
265 win_base * win_select::get_selected_object()
266 {
267  if(cur_select_ != list_wb_.end() || list_wb_.size() == 0) return *cur_select_;
268  else return NULL;
269 }
270 
271 u_int16 win_select::get_selected_position()
272 {
273  u_int16 pos_=0;
274 
275  lwb::iterator i = list_wb_.begin();
276 
277  if(i==list_wb_.end()) return 0;
278 
279  while( (*i++) != (*cur_select_)) pos_++;
280 
281  return pos_+1;
282 }
283 
284 
285 
286 void win_select::update_cur_select_position()
287 {
288  if(!max_amplitude_) return;
289 
290  while( 1 )
291  {
292  // if((*cur_select_)->height() > height() + (space_with_border_ << 1) ) break;
293  // Workaround if the object is bigger than the select (Alex).
294  if((*cur_select_)->height() + (space_with_border_ << 1) > height()) break;
295  else if((*cur_select_)->y() + (*cur_select_)->pad_y() < space_with_border_ ) up();
296  else if((*cur_select_)->y() + (*cur_select_)->pad_y() + (*cur_select_)->height() > height() - space_with_border_) down();
297  else break;
298  }
299 }
300 
301 
303 {
304  if(win_scroll::update())
305  {
306  if(!finish_scroll_)
307  {
308  if(!max_amplitude_) {finish_scroll_=true;return true;}
309  if((*cur_select_)->height() + (space_with_border_ << 1) > height()) {finish_scroll_ = true; return true;}
310  else if((*cur_select_)->y() + (*cur_select_)->pad_y() < space_with_border_ ) up();
311  else if((*cur_select_)->y() + (*cur_select_)->pad_y() + (*cur_select_)->height() > height() - space_with_border_) down();
312  else finish_scroll_ = true;
313  }
314  return true;
315  }
316  return false;
317 }
318 
319 
320 
321 /*
322 #include <list>
323 #include "types.h"
324 #include "input.h"
325 #include "image.h"
326 #include "win_types.h"
327 #include "win_base.h"
328 #include "win_border.h"
329 #include "win_scrollbar.h"
330 #include "win_theme.h"
331 #include "win_container.h"
332 #include "win_scrolled.h"
333 #include "win_select.h"
334 
335 //STATIC INIT
336 win_select * win_select::curselect_=NULL;
337 bool win_select::activate_keyboard_=true;
338 
339 s_int32 win_select::next_key=WIN_SELECT_DEFAULT_KEY_NEXT;
340 s_int32 win_select::previous_key=WIN_SELECT_DEFAULT_KEY_PREVIOUS;
341 s_int32 win_select::activate_key=WIN_SELECT_DEFAULT_KEY_ACTIVATE;
342 s_int32 win_select::back_key=WIN_SELECT_DEFAULT_KEY_BACK;
343 
344 
345 win_select::win_select(s_int16 tx,s_int16 ty,u_int16 tl,u_int16 th,win_theme * wth):win_scrolled(tx,ty,tl,th,wth)
346 {
347  //father select is the father of this object
348  fatherselect_=NULL;
349  //if there are no select object attached to the static curselet, this object become the curselect
350  if(!curselect_) curselect_=this;
351 
352  index_list=list_obj.begin();
353  //the default mode select for this object is the border
354  mode_selected_=WIN_SELECT_MODE_BORDER;
355  //by default, the scroll bar is not visible
356  visible_scrollbar_=false;
357  //if when you select you change the first to the last
358  select_circle_=false;
359 
360  //type of the select
361  type_selected_=WIN_SELECT_TYPE_NORMAL;
362 
363 }
364 
365 
366 win_select::~win_select()
367 {
368  //WARNING CHECK BACK
369  if(curselect_==this)
370  {
371  back();
372  curselect_=NULL;
373  }
374  //WARNING DESTROY()
375 }
376 
377 
378 void win_select::add(win_base * wb)
379 {
380  //call the add of win_scrolled
381  win_scrolled::add(wb);
382 
383  //prevent the new object is in select
384  wb->set_in_select(true);
385 
386  //set the parameters for this object
387  set_select_object(wb,false);
388 
389  //when you add an object, automatically the index become the first element of the list
390  set_default();
391 
392  //a select can have just one mode to select each object in the list
393  wb->set_select_mode_(mode_selected_);
394 }
395 
396 void win_select::add(win_select * ws)
397 {
398  //add a select object
399  win_select::add((win_base*)ws);
400  //add the object but prevent the new object that this objetc is the father
401  ws->fatherselect_=this;
402 }
403 
404 void win_select::remove(win_base * wb)
405 {
406  //remove an objetc prevent that the object is not in_select
407  win_scrolled::remove(wb);
408  wb->set_in_select(false);
409  wb->set_draw_brightness(false);
410  index_list=list_obj.begin();
411 }
412 
413 void win_select::remove_all()
414 {
415  for(list<win_base *>::iterator i=list_obj.begin();i!=list_obj.end();i++)
416  {
417  (*i)->set_in_select(false);
418  (*i)->wb_father_=NULL;//part of win_container
419  }
420  list_obj.clear();
421  index_list=list_obj.begin();
422 
423  //win scrolled part
424  max_amplitude_=0;
425  cur_amplitude_=0;
426  theme_->scrollbar->update_scroll_bar(this);
427 }
428 
429 void win_select::destroy()
430 {
431  win_scrolled::destroy();
432  index_list=list_obj.begin();
433 }
434 
435 
436 void win_select::on_next()
437 {
438  if(callback_[WIN_SIG_NEXT_KEY]) (callback_[WIN_SIG_NEXT_KEY])();
439 }
440 
441 void win_select::on_previous()
442 {
443  if(callback_[WIN_SIG_PREVIOUS_KEY]) (callback_[WIN_SIG_PREVIOUS_KEY])();
444 }
445 
446 bool win_select::update()
447 {
448  if(win_scrolled::update())
449  {
450  if(focus_ && activate_keyboard_ && activated_)
451  {
452  if(input::has_been_pushed (SDL_Keycode (next_key))) next_();
453  if(input::has_been_pushed (SDL_Keycode (previous_key))) previous_();
454  if(input::has_been_pushed (SDL_Keycode (back_key))) back();
455  if(input::has_been_pushed (SDL_Keycode (activate_key))) activate___();
456  }
457  return true;
458  }
459  return false;
460 }
461 
462 //if b is true, cur object take parameters to an selected object
463 void win_select::set_select_object(win_base * wb,bool b)
464 {
465  switch(mode_selected_)
466  {
467  case WIN_SELECT_MODE_BRIGHTNESS:
468  wb->set_draw_brightness(!b);
469  break;
470  case WIN_SELECT_MODE_BORDER:
471  wb->set_border_visible(b);
472  }
473 
474  switch(type_selected_)
475  {
476  case WIN_SELECT_TYPE_NORMAL:
477  wb->set_visible(true);
478  break;
479  case WIN_SELECT_TYPE_SCROLL:
480  wb->set_visible(b);
481  break;
482  }
483 }
484 
485 
486 //WARNING: lots of confuse in next_ and previous maybe rewrite them
487 void win_select::next_()
488 {
489  //test if next is possible
490  if(index_list==list_obj.end() || !activated_) return;
491 
492  //unselect cur element
493  (*index_list)->on_unselect();
494 
495  set_select_object(*index_list,false);
496 
497  //create a temporary index
498  list<win_base*>::iterator cur_i=index_list;
499 
500  //to next elements
501  cur_i++;
502 
503  //while not a the end, not be selected and different at old object go to the next
504  while(cur_i!=list_obj.end() && !(*cur_i)->is_can_be_selected() && cur_i!=index_list) cur_i++;
505 
506  //if at end of list and select circle is activate
507  if(cur_i==list_obj.end())
508  {
509  //cur is the begin of list
510  if(select_circle_)
511  {
512  cur_i=list_obj.begin();
513  while(cur_i!=list_obj.end() && !(*cur_i)->is_can_be_selected() && cur_i!=index_list) cur_i++;
514  if(cur_i!=list_obj.end()) index_list=cur_i;
515  }
516  }else index_list=cur_i;
517 
518  set_select_object(*index_list,true);
519 
520  (*index_list)->on_select();
521 
522  update_position();
523 
524  on_next();
525 }
526 
527 void win_select::previous_()
528 {
529  if(index_list==list_obj.end() || !activated_) return;
530 
531  (*index_list)->on_unselect();
532 
533  //set to unselect object
534  set_select_object(*index_list,false);
535 
536  list<win_base*>::iterator cur_i=index_list;
537 
538 
539 
540  if(select_circle_)
541  {
542 
543  if(cur_i==list_obj.begin()) cur_i=list_obj.end();
544  cur_i--;
545  }
546  else if(cur_i!=list_obj.begin()) cur_i--;
547 
548 
549 
550 
551 
552 
553 
554  while(cur_i!=list_obj.begin() && !(*cur_i)->is_can_be_selected() && cur_i!=index_list) cur_i--;
555 
556  if(cur_i==list_obj.begin() && !(*cur_i)->is_can_be_selected())
557  {
558  if(select_circle_)
559  {
560 
561  cur_i=list_obj.end();
562  cur_i--;
563 
564  while(cur_i!=list_obj.begin() && !(*cur_i)->is_can_be_selected() && cur_i!=index_list) cur_i--;
565  if((*cur_i)->is_can_be_selected()) index_list=cur_i;
566  }
567  } else index_list=cur_i;
568 
569  (*index_list)->on_select();
570 
571 
572  //set to select object
573  set_select_object(*index_list,true);
574 
575  update_position();
576  on_previous();
577 
578 }
579 
580 
581 void win_select::set_can_be_selected_all(bool b)
582 {
583  for(list<win_base*>::iterator i=list_obj.begin();i!=list_obj.end();i++)
584  (*i)->set_can_be_selected(b);
585 }
586 
587 void win_select::set_default()
588 {
589  if(list_obj.size()==0) return;
590 
591  if(index_list!=list_obj.end()) set_select_object(*index_list,false);
592 
593  index_list=list_obj.begin();
594 
595  while(index_list!=list_obj.end() && !(*index_list)->is_can_be_selected()) index_list++;
596 
597  if(index_list!=list_obj.end()) set_select_object(*index_list,true);
598 }
599 
600 
601 void win_select::update_position()
602 {
603 
604  //this function is used to see the cur object which is selected
605  static bool tmp_is_visible_;
606 
607  //if(index_list==list_obj.end()){cout << "tets\n"; return;}
608 
609  switch(type_selected_)
610  {
611  case WIN_SELECT_TYPE_NORMAL:
612  tmp_is_visible_=false;
613  //if not amplitude --> all object in the list is visible
614  if(!max_amplitude_) {tmp_is_visible_=true;return;}
615  while(!tmp_is_visible_)
616  {
617 
618  // if(((*index_list)->y()+(*index_list)->pady()>space_between_border_) &&
619  // ((*index_list)->y()+(*index_list)->height()>height_-space_between_border_)) {tmp_is_visible_=true;cout << "16\n";}
620  if((*index_list)->height()>height_+(space_between_border_<<1)) tmp_is_visible_=true;
621 
622  else if((*index_list)->y()+(*index_list)->pady()<space_between_border_) up();
623  else if((*index_list)->y()+(*index_list)->pady()+(*index_list)->height()>height_-space_between_border_) down();
624  else tmp_is_visible_=true;
625  }
626  break;
627 
628  case WIN_SELECT_TYPE_SCROLL:
629  //set position of the cur select object
630 
631  (*index_list)->move(space_between_border_,space_between_border_);
632 
633  break;
634  default:
635  break;
636  }
637 }
638 
639 
640 void win_select::set_type(u_int8 t)
641 {
642  type_selected_=t;
643  //set all object to the new type set
644  for(list<win_base*>::iterator i=list_obj.begin();i!=list_obj.end();i++)
645  set_select_object(*i,false);
646 
647  //select the first object
648  set_default();
649 }
650 
651 
652 
653 //return the cur object which is selected
654 win_base * win_select::get()
655 {
656  if(index_list==list_obj.end()) return NULL;
657  else return (*index_list);
658 }
659 
660 //if error return 0
661 u_int16 win_select::get_pos()
662 {
663  u_int16 pos_=0;
664  list<win_base *>::iterator i=list_obj.begin();
665  if(i==list_obj.end()) return 0;
666  while((*i++)!=(*index_list)) pos_++;
667  return pos_+1;
668 }
669 
670 void win_select::set_default(u_int16 nb)
671 {
672  if(index_list==list_obj.end()) return;
673  u_int16 j=1;
674  (*index_list)->set_select(false);
675  if(mode_selected_==WIN_SELECT_MODE_BRIGHTNESS)
676  (*index_list)->set_draw_brightness(true);
677  else if(mode_selected_==WIN_SELECT_MODE_BORDER)
678  (*index_list)->set_border_visible(false);
679 
680  index_list=list_obj.begin();
681  while(index_list!=list_obj.end() && j++<nb) index_list++;
682  if(index_list!=list_obj.end())
683  {
684  (*index_list)->set_select(true);
685  if(mode_selected_==WIN_SELECT_MODE_BRIGHTNESS)
686  (*index_list)->set_draw_brightness(false);
687  else if(mode_selected_==WIN_SELECT_MODE_BORDER)
688  (*index_list)->set_border_visible(true);
689  }
690 }
691 
692 void win_select::set_default(win_base * wb)
693 {
694  if(index_list==list_obj.end()) return;
695  (*index_list)->set_select(false);
696 
697  if(mode_selected_==WIN_SELECT_MODE_BRIGHTNESS)
698  (*index_list)->set_draw_brightness(true);
699  else if(mode_selected_==WIN_SELECT_MODE_BORDER)
700  (*index_list)->set_border_visible(false);
701 
702  index_list=list_obj.begin();
703  while(index_list != list_obj.end() && (*index_list)!=wb) index_list++;
704  if(index_list!=list_obj.end())
705  {
706  (*index_list)->set_select(true);
707  if(mode_selected_==WIN_SELECT_MODE_BRIGHTNESS)
708  (*index_list)->set_draw_brightness(false);
709  else if(mode_selected_==WIN_SELECT_MODE_BORDER)
710  (*index_list)->set_border_visible(true);
711  }
712 }
713 
714 void win_select::set_select_mode(u_int8 mode)
715 {
716  mode_selected_=mode;
717  if(mode_selected_==WIN_SELECT_MODE_BRIGHTNESS)
718  for(list<win_base*>::iterator i=list_obj.begin();i!=list_obj.end();i++)
719  (*i)->set_draw_brightness(true);
720  if(index_list!=list_obj.end()) (*index_list)->set_draw_brightness(false);
721  for(list<win_base*>::iterator i=list_obj.begin();i!=list_obj.end();i++)
722  (*i)->set_select_mode_(mode);
723 }
724 
725 void win_select::activate()
726 {
727  if(curselect_) curselect_->activate___();
728 }
729 
730 void win_select::next()
731 {
732  if(curselect_) curselect_->next_();
733 }
734 
735 void win_select::previous()
736 {
737  if(curselect_) curselect_->previous_();
738 }
739 
740 bool win_select::activate___()
741 {
742  if(index_list!=list_obj.end())
743  {
744  (*index_list)->set_activated(true);
745  on_activate_key();
746  return true;
747  }
748  return false;
749 }
750 
751 void win_select::on_activate()
752 {
753  win_scrolled::on_activate();
754  if(!curselect_) {curselect_=this;return;}
755  if(curselect_==this) return;
756  //if curselect
757  curselect_->on_unactivate();
758  curselect_=this;
759 }
760 
761 bool win_select::back()
762 {
763  //if true we can go to the father
764  if(curselect_)
765  {
766  if(curselect_->fatherselect_)
767  {
768  if(curselect_->index_list!=curselect_->list_obj.end())
769  {
770  curselect_->on_unactivate();
771  curselect_=curselect_->fatherselect_;
772  curselect_->on_activate();
773  return true;
774  }
775  }
776  }
777  return false;
778 }
779 
780 void win_select::set_cur_select(win_select * ws)
781 {
782  if(curselect_ && curselect_!=ws) curselect_->set_activated(false);
783  curselect_=ws;
784 }
785 
786 void win_select::init()
787 {
788  if(curselect_) curselect_->set_activated(false);
789  curselect_=NULL;
790 }
791 
792 
793 
794 
795 
796 
797 
798 
799 
800 
801 
802 */
803 
804 
805 
806 
807 
808 
809 
static bool has_been_pushed(SDL_Keycode key)
Returns whether a key has been pushed since last function call, false otherwise.
Definition: input.cc:119
#define u_int16
16 bits long unsigned integer
Definition: types.h:38
bool input_update()
Input Update process .
Definition: win_scroll.cc:216
bool update()
Update process.
Definition: win_scroll.cc:190
bool input_update()
Input Update process .
Definition: win_select.cc:177
virtual void set_brightness(const bool b)
Set the transluency parameter.
Definition: win_base.h:198
bool is_can_be_selected() const
Test if win_* can be selected.
Definition: win_base.h:218
Common properties for each win_base&#39;s object.
Definition: win_base.h:51
u_int16 height() const
Returns the height of the drawing_area.
Definition: drawing_area.h:101
bool update()
Update process.
Definition: win_select.cc:302