Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ListBox.cpp
Go to the documentation of this file.
1 /* Project nGenEx
2  Destroyer Studios LLC
3  Copyright � 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: nGenEx.lib
6  FILE: ListBox.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  ListBox ActiveWindow class
13 */
14 
15 #include "MemDebug.h"
16 #include "ListBox.h"
17 #include "Button.h"
18 #include "Bitmap.h"
19 #include "FormWindow.h"
20 #include "Video.h"
21 #include "Font.h"
22 #include "Keyboard.h"
23 #include "Mouse.h"
24 
25 // +--------------------------------------------------------------------+
26 
28 {
29 public:
30  static const char* TYPENAME() { return "ListBoxCell"; }
31 
32  ListBoxCell() : data(0), image(0) { }
33 
35  DWORD data;
37 };
38 
39 // +--------------------------------------------------------------------+
40 
42 {
43 public:
44  static const char* TYPENAME() { return "ListBoxItem"; }
45 
46  ListBoxItem() : data(0), image(0), selected(false), listbox(0), color(Color::White) { }
48 
49  int operator < (const ListBoxItem& item) const;
50  int operator <=(const ListBoxItem& item) const;
51  int operator ==(const ListBoxItem& item) const;
52 
54  DWORD data;
56  bool selected;
59 
61 };
62 
63 // +--------------------------------------------------------------------+
64 
66 {
67 public:
68  static const char* TYPENAME() { return "ListBoxColumn"; }
69 
70  ListBoxColumn() : width(0), align(0), sort(0), color(Color::White), use_color(0), percent(0) { }
71 
73  int width;
74  int align;
75  int sort;
77  int use_color;
78 
79  double percent;
80 };
81 
82 // +--------------------------------------------------------------------+
83 
84 int ListBoxItem::operator < (const ListBoxItem& item) const
85 {
86  if (listbox && listbox == item.listbox) {
87  int sort_column = listbox->GetSortColumn() - 1;
88  int sort_criteria = listbox->GetSortCriteria();
89 
90  if (sort_column == -1) {
91  switch (sort_criteria) {
93  return data > item.data;
94 
96  return text > item.text;
97 
99  return text < item.text;
100 
102  return data < item.data;
103  }
104  }
105 
106  else if (sort_column >= 0 &&
107  sort_column <= subitems.size() &&
108  sort_column <= item.subitems.size()) {
109 
110  switch (sort_criteria) {
112  return subitems[sort_column]->data > item.subitems[sort_column]->data;
113 
115  return subitems[sort_column]->text > item.subitems[sort_column]->text;
116 
118  return subitems[sort_column]->text < item.subitems[sort_column]->text;
119 
121  return subitems[sort_column]->data < item.subitems[sort_column]->data;
122  }
123  }
124  }
125 
126  return 0;
127 }
128 
129 // +--------------------------------------------------------------------+
130 
131 int ListBoxItem::operator <=(const ListBoxItem& item) const
132 {
133  if (listbox && listbox == item.listbox) {
134  int sort_column = listbox->GetSortColumn() - 1;
135  int sort_criteria = listbox->GetSortCriteria();
136 
137  if (sort_column == -1) {
138  switch (sort_criteria) {
140  return data >= item.data;
141 
143  return text >= item.text;
144 
146  return text <= item.text;
147 
149  return data <= item.data;
150  }
151  }
152 
153  else if (sort_column >= 0 &&
154  sort_column <= subitems.size() &&
155  sort_column <= item.subitems.size()) {
156 
157  switch (sort_criteria) {
159  return subitems[sort_column]->data >= item.subitems[sort_column]->data;
160 
162  return subitems[sort_column]->text >= item.subitems[sort_column]->text;
163 
165  return subitems[sort_column]->text <= item.subitems[sort_column]->text;
166 
168  return subitems[sort_column]->data <= item.subitems[sort_column]->data;
169  }
170  }
171  }
172 
173  return 0;
174 }
175 
176 // +--------------------------------------------------------------------+
177 
179 {
180  if (listbox && listbox == item.listbox) {
181  int sort_column = listbox->GetSortColumn() - 1;
182  int sort_criteria = listbox->GetSortCriteria();
183 
184  if (sort_column == -1) {
185  switch (sort_criteria) {
187  return data == item.data;
188 
190  return text == item.text;
191 
193  return text == item.text;
194 
196  return data == item.data;
197  }
198  }
199 
200  else if (sort_column >= 0 &&
201  sort_column <= subitems.size() &&
202  sort_column <= item.subitems.size()) {
203 
204  switch (sort_criteria) {
206  return subitems[sort_column]->data == item.subitems[sort_column]->data;
207 
209  return subitems[sort_column]->text == item.subitems[sort_column]->text;
210 
212  return subitems[sort_column]->text == item.subitems[sort_column]->text;
213 
215  return subitems[sort_column]->data == item.subitems[sort_column]->data;
216  }
217  }
218  }
219 
220  return 0;
221 }
222 
223 // +--------------------------------------------------------------------+
224 
225 static int old_cursor;
226 
227 // +--------------------------------------------------------------------+
228 
229 ListBox::ListBox(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD aid)
230 : ScrollWindow(p->GetScreen(), ax, ay, aw, ah, aid, 0, p)
231 {
232  show_headings = false;
233  multiselect = false;
234  list_index = 0;
235  selcount = 0;
236 
237  selected_color = Color(255, 255, 128);
238 
239  sort_column = 0;
242 
243  char buf[32];
244  sprintf_s(buf, "ListBox %d", id);
245  desc = buf;
246 }
247 
248 ListBox::ListBox(Screen* s, int ax, int ay, int aw, int ah, DWORD aid)
249 : ScrollWindow(s, ax, ay, aw, ah, aid)
250 {
251  show_headings = false;
252  multiselect = false;
253  list_index = 0;
254  selcount = 0;
255 
256  selected_color = Color(255, 255, 128);
257 
258  sort_column = 0;
261 
262  char buf[32];
263  sprintf_s(buf, "ListBox %d", id);
264  desc = buf;
265 }
266 
268 {
269  items.destroy();
270  columns.destroy();
271 }
272 
273 // +--------------------------------------------------------------------+
274 
275 void
276 ListBox::DrawContent(const Rect& ctrl_rect)
277 {
278  SizeColumns();
279 
280  Rect item_rect = ctrl_rect;
281  item_rect.h = line_height;
282 
283  int h = rect.h;
284 
285  // draw headings at top, if needed:
286  if (show_headings) {
287  Color save_color = back_color;
290 
291  int max_column = columns.size()-1;
292  item_rect.h += HEADING_EXTRA;
293 
294  page_size = (h-item_rect.h) / (line_height + leading);
295 
296  for (int column = 0; column <= max_column; column++) {
297  item_rect.w = GetColumnWidth(column);
298 
299  // draw heading button
300  FillRect(item_rect, back_color);
301  DrawStyleRect(item_rect, WIN_RAISED_FRAME);
302 
303  Rect title_rect = item_rect;
304  title_rect.Deflate(3,3);
305 
306  DrawText(GetColumnTitle(column),
307  0,
308  title_rect,
309  DT_CENTER|DT_SINGLELINE);
310 
311  item_rect.x += item_rect.w;
312  }
313 
314  item_rect.y += item_rect.h;
315  back_color = save_color;
316  item_rect.h = line_height;
317  }
318 
319  int index = 0;
321 
322  while (++iter && item_rect.y < h) {
323  ListBoxItem* item = iter.value();
324 
325  if (index++ >= top_index) {
326  // draw main item:
327  int column = 0;
328  item_rect.x = ctrl_rect.x;
329  item_rect.w = GetColumnWidth(column) - 2;
330 
331  if (item_rect.y + item_rect.h > h) {
332  item_rect.h = h - item_rect.y - 1;
333  }
334 
335  Color item_color = GetItemColor(index-1, 0);
336 
337  if (item->selected) {
339 
341  FillRect(item_rect, selected_color * 0.25);
342 
344  DrawRect(item_rect, selected_color);
345  }
346  else {
347  font->SetColor(item_color);
348 
350  FillRect(item_rect, item_color * 0.25);
351 
353  DrawRect(item_rect, item_color);
354  }
355 
356  Rect text_rect = item_rect;
357 
358  if (item->image && item->image->Width() > 0 && item->image->Height() > 0) {
359  DrawBitmap(text_rect.x, text_rect.y, text_rect.x + text_rect.w, text_rect.y + line_height, item->image);
360  }
361  else {
362  text_rect.Deflate(2,0);
363  DrawText(item->text.data(),
364  item->text.length(),
365  text_rect,
366  GetColumnAlign(column)|DT_SINGLELINE);
367  }
368 
369  // draw subitems:
370  ListIter<ListBoxCell> sub_iter = item->subitems;
371  while (++sub_iter) {
372  ListBoxCell* sub = sub_iter.value();
373 
374  column++;
375  item_rect.x += item_rect.w + 2;
376  item_rect.w = GetColumnWidth(column) - 2;
377 
378  if (item->selected) {
380  FillRect(item_rect, selected_color * 0.25);
381 
383  DrawRect(item_rect, selected_color);
384  }
385  else {
387  FillRect(item_rect, item_color * 0.25);
388 
390  DrawRect(item_rect, item_color);
391  }
392 
393  if (item->selected)
395  else
396  font->SetColor(GetItemColor(index-1, column));
397 
398  Rect text_rect = item_rect;
399  if (sub->image && sub->image->Width() > 0 && sub->image->Height() > 0) {
400  DrawBitmap(text_rect.x, text_rect.y, text_rect.x + text_rect.w, text_rect.y + line_height, sub->image);
401  }
402  else {
403  text_rect.Deflate(2,0);
404  DrawText(sub->text.data(),
405  sub->text.length(),
406  text_rect,
407  GetColumnAlign(column)|DT_SINGLELINE);
408  }
409  }
410 
411  item_rect.y += line_height + leading;
412  }
413  }
414 }
415 
416 // +--------------------------------------------------------------------+
417 
418 void
420 {
421  ListBoxColumn* c = columns.first();
422 
423  if (c->percent < 0.001) {
424  double total = 0;
425 
427  while (++iter) {
428  c = iter.value();
429  total += c->width;
430  }
431 
432  iter.reset();
433  while (++iter) {
434  c = iter.value();
435  c->percent = c->width / total;
436  }
437  }
438 
439  int usable_width = rect.w;
440  int used = 0;
441 
442  if (IsScrollVisible()) {
443  usable_width -= SCROLL_WIDTH + 2;
444  }
445  else {
446  usable_width -= 3;
447  }
448 
449  for (int i = 0; i < columns.size(); i++) {
450  c = columns[i];
451 
452  if (i < columns.size() - 1)
453  c->width = (int) (c->percent * usable_width);
454  else
455  c->width = usable_width - used;
456 
457  used += c->width;
458  }
459 }
460 
461 // +--------------------------------------------------------------------+
462 
464 {
465  return items.size();
466 }
467 
469 {
470  return columns.size();
471 }
472 
474 {
475  if (index >= 0 && index < items.size())
476  return items[index]->text;
477 
478  return Text();
479 }
480 
481 void ListBox::SetItemText(int index, const char* text)
482 {
483  if (index >= 0 && index < items.size()) {
484  items[index]->text = text;
485  }
486 }
487 
488 DWORD ListBox::GetItemData(int index)
489 {
490  if (index >= 0 && index < items.size())
491  return items[index]->data;
492 
493  return 0;
494 }
495 
496 void ListBox::SetItemData(int index, DWORD data)
497 {
498  if (index >= 0 && index < items.size()) {
499  items[index]->data = data;
500  }
501 }
502 
504 {
505  if (index >= 0 && index < items.size())
506  return items[index]->image;
507 
508  return 0;
509 }
510 
511 void ListBox::SetItemImage(int index, Bitmap* img)
512 {
513  if (index >= 0 && index < items.size()) {
514  items[index]->image = img;
515  }
516 }
517 
519 {
520  if (index >= 0 && index < items.size())
521  return items[index]->color;
522 
523  return Color::White;
524 }
525 
526 void ListBox::SetItemColor(int index, Color c)
527 {
528  if (index >= 0 && index < items.size()) {
529  items[index]->color = c;
530  }
531 }
532 
533 Text ListBox::GetItemText(int index, int column)
534 {
535  if (column == 0) {
536  return GetItemText(index);
537  }
538 
539  if (index >= 0 && index < items.size()) {
540  ListBoxItem* item = items[index];
541 
542  column--;
543  if (column >= 0 && column < item->subitems.size())
544  return item->subitems[column]->text;
545  }
546 
547  return Text();
548 }
549 
550 void ListBox::SetItemText(int index, int column, const char* text)
551 {
552  if (column == 0) {
553  SetItemText(index, text);
554  return;
555  }
556 
557  if (index >= 0 && index < items.size()) {
558  ListBoxItem* item = items[index];
559 
560  column--;
561  if (column >= 0 && column < columns.size()-1) {
562  while (column >= item->subitems.size()) {
563  ListBoxCell* cell = new(__FILE__,__LINE__) ListBoxCell;
564  if (cell)
565  item->subitems.append(cell);
566  }
567 
568  item->subitems[column]->text = text;
569  }
570  }
571 }
572 
573 DWORD ListBox::GetItemData(int index, int column)
574 {
575  if (column == 0) {
576  return GetItemData(index);
577  }
578 
579  if (index >= 0 && index < items.size()) {
580  ListBoxItem* item = items[index];
581 
582  column--;
583  if (column >= 0 && column < item->subitems.size())
584  return item->subitems[column]->data;
585  }
586 
587  return 0;
588 }
589 
590 void ListBox::SetItemData(int index, int column, DWORD data)
591 {
592  if (column == 0) {
593  SetItemData(index, data);
594  return;
595  }
596 
597  if (index >= 0 && index < items.size()) {
598  ListBoxItem* item = items[index];
599 
600  column--;
601  if (column >= 0 && column < columns.size()-1) {
602  while (column >= item->subitems.size()) {
603  ListBoxCell* cell = new(__FILE__,__LINE__) ListBoxCell;
604  if (cell)
605  item->subitems.append(cell);
606  }
607 
608  item->subitems[column]->data = data;
609  }
610  }
611 }
612 
613 Bitmap* ListBox::GetItemImage(int index, int column)
614 {
615  if (column == 0) {
616  return GetItemImage(index);
617  }
618 
619  if (index >= 0 && index < items.size()) {
620  ListBoxItem* item = items[index];
621 
622  column--;
623  if (column >= 0 && column < item->subitems.size())
624  return item->subitems[column]->image;
625  }
626 
627  return 0;
628 }
629 
630 void ListBox::SetItemImage(int index, int column, Bitmap* img)
631 {
632  if (column == 0) {
633  SetItemImage(index, img);
634  return;
635  }
636 
637  if (index >= 0 && index < items.size()) {
638  ListBoxItem* item = items[index];
639 
640  column--;
641  if (column >= 0 && column < columns.size()-1) {
642  while (column >= item->subitems.size()) {
643  ListBoxCell* cell = new(__FILE__,__LINE__) ListBoxCell;
644  if (cell)
645  item->subitems.append(cell);
646  }
647 
648  item->subitems[column]->image = img;
649  }
650  }
651 }
652 
653 int ListBox::AddItem(const char* text)
654 {
655  ListBoxItem* item = new(__FILE__,__LINE__) ListBoxItem;
656 
657  if (item) {
658  item->text = text;
659  item->color = fore_color;
660  item->listbox = this;
661 
662  items.append(item);
663 
664  line_count = items.size();
665  list_index = items.size()-1;
666  }
667 
668  return list_index+1;
669 }
670 
671 int ListBox::AddItemWithData(const char* text, int data)
672 {
673  ListBoxItem* item = new(__FILE__,__LINE__) ListBoxItem;
674 
675  if (item) {
676  item->text = text;
677  item->data = data;
678  item->color = fore_color;
679  item->listbox = this;
680 
681  items.append(item);
682 
683  line_count = items.size();
684  list_index = items.size()-1;
685  }
686 
687  return list_index+1;
688 }
689 
691 {
692  ListBoxItem* item = new(__FILE__,__LINE__) ListBoxItem;
693 
694  if (item) {
695  item->image = img;
696  item->color = fore_color;
697  item->listbox = this;
698 
699  items.append(item);
700 
701  line_count = items.size();
702  list_index = items.size()-1;
703  }
704 
705  return list_index+1;
706 }
707 
708 void ListBox::InsertItem(int index, const char* text)
709 {
710  if (index >=0 && index < items.size()) {
711  ListBoxItem* item = new(__FILE__,__LINE__) ListBoxItem;
712 
713  if (item) {
714  item->text = text;
715  item->color = fore_color;
716  item->listbox = this;
717 
718  list_index = index;
719  items.insert(item, list_index);
720  line_count = items.size();
721  }
722  }
723 }
724 
725 void ListBox::InsertItemWithData(int index, const char* text, int data)
726 {
727  if (index >=0 && index < items.size()) {
728  ListBoxItem* item = new(__FILE__,__LINE__) ListBoxItem;
729 
730  if (item) {
731  item->text = text;
732  item->data = data;
733  item->color = fore_color;
734  item->listbox = this;
735 
736  list_index = index;
737  items.insert(item, list_index);
738  line_count = items.size();
739  }
740  }
741 }
742 
744 {
745  items.destroy();
746  selcount = 0;
747  top_index = 0;
748  list_index = 0;
749  line_count = 0;
750 }
751 
752 void ListBox::RemoveItem(int index)
753 {
754  if (index >= 0 && index < items.size()) {
755  if (items[index]->selected)
756  selcount--;
757  items.removeIndex(index);
758  line_count = items.size();
759  }
760 }
761 
763 {
764  if (selcount) {
766  while (++item) {
767  if (item->selected) {
768  delete item.removeItem();
769  }
770  }
771 
772  line_count = items.size();
773  selcount = 0;
774  }
775 }
776 
777 void ListBox::AddColumn(const char* title, int width, int align, int sort)
778 {
779  ListBoxColumn* column = new(__FILE__,__LINE__) ListBoxColumn;
780 
781  if (column) {
782  column->title = title;
783  column->width = width;
784  column->align = align;
785  column->sort = sort;
786 
787  columns.append(column);
788  }
789 }
790 
792 {
793  if (index >= 0 && index < columns.size())
794  return columns[index]->title;
795 
796  return Text();
797 }
798 
799 void ListBox::SetColumnTitle(int index, const char* title)
800 {
801  if (index >= 0 && index < columns.size()) {
802  columns[index]->title = title;
803  }
804 }
805 
807 {
808  if (index >= 0 && index < columns.size())
809  return columns[index]->width;
810 
811  return 0;
812 }
813 
814 void ListBox::SetColumnWidth(int index, int width)
815 {
816  if (index >= 0 && index < columns.size()) {
817  columns[index]->width = width;
818  }
819 }
820 
822 {
823  if (index >= 0 && index < columns.size())
824  return columns[index]->align;
825 
826  return 0;
827 }
828 
829 void ListBox::SetColumnAlign(int index, int align)
830 {
831  if (index >= 0 && index < columns.size()) {
832  columns[index]->align = align;
833  }
834 }
835 
837 {
838  if (index >= 0 && index < columns.size())
839  return columns[index]->sort;
840 
841  return 0;
842 }
843 
844 void ListBox::SetColumnSort(int index, int sort)
845 {
846  if (index >= 0 && index < columns.size()) {
847  columns[index]->sort = sort;
848  }
849 }
850 
852 {
853  if (index >= 0 && index < columns.size())
854  return columns[index]->color;
855 
856  return Color::White;
857 }
858 
859 void ListBox::SetColumnColor(int index, Color c)
860 {
861  if (index >= 0 && index < columns.size()) {
862  columns[index]->color = c;
863  columns[index]->use_color = true;
864  }
865 }
866 
867 Color ListBox::GetItemColor(int index, int column)
868 {
869  Color c = Color::White;
870 
871  if (index >= 0 && index < items.size())
872  c = items[index]->color;
873 
874  if (column >= 0 && column < columns.size()) {
875  if (columns[column]->use_color)
876  c = columns[column]->color;
877  }
878 
879  return c;
880 }
881 
883 {
884  return multiselect;
885 }
886 
887 void ListBox::SetMultiSelect(int nNewValue)
888 {
889  if (multiselect != nNewValue && (nNewValue == 0 || nNewValue == 1)) {
890  multiselect = nNewValue;
891  ClearSelection();
892  }
893 }
894 
896 {
897  return show_headings;
898 }
899 
900 void ListBox::SetShowHeadings(bool nNewValue)
901 {
902  if (show_headings != nNewValue) {
903  show_headings = nNewValue;
904  }
905 }
906 
908 {
909  return selected_color;
910 }
911 
913 {
914  if (selected_color != c) {
915  selected_color = c;
916  }
917 }
918 
920 {
921  return item_style;
922 }
923 
924 void ListBox::SetItemStyle(int style)
925 {
926  if (style >= LIST_ITEM_STYLE_PLAIN && style <= LIST_ITEM_STYLE_FILLED_BOX) {
927  item_style = style;
928  }
929 }
930 
932 {
933  return seln_style;
934 }
935 
937 {
938  if (style >= LIST_ITEM_STYLE_PLAIN && style <= LIST_ITEM_STYLE_FILLED_BOX) {
939  seln_style = style;
940  }
941 }
942 
943 bool ListBox::IsSelected(int index)
944 {
945  if (index >= 0 && index < items.size())
946  return items[index]->selected;
947 
948  return false;
949 }
950 
951 void ListBox::SetSelected(int index, bool bNewValue)
952 {
953  if (index >= 0 && index < items.size()) {
954  if (!multiselect)
955  ClearSelection();
956 
957  if (items[index]->selected != bNewValue) {
958  items[index]->selected = bNewValue;
959 
960  if (bNewValue) {
961  list_index = index;
962  selcount++;
963  }
964  else {
965  selcount--;
966  }
967  }
968  }
969 }
970 
972 {
974  while (++item)
975  item->selected = false;
976 
977  selcount = 0;
978 }
979 
981 {
982  return list_index;
983 }
984 
986 {
987  line_count = items.size();
988  return line_count;
989 }
990 
992 {
993  return selcount;
994 }
995 
997 {
998  for (int i = 0; i < items.size(); i++)
999  if (items[i]->selected)
1000  return i;
1001 
1002  return -1;
1003 }
1004 
1006 {
1007  int n = GetSelection();
1008  return GetItemText(n);
1009 }
1010 
1011 // +--------------------------------------------------------------------+
1012 
1014 {
1015  return sort_column;
1016 }
1017 
1018 void ListBox::SetSortColumn(int col_index)
1019 {
1020  if (col_index >= 0 && col_index <= columns.size())
1021  sort_column = col_index;
1022 }
1023 
1025 {
1026  return GetColumnSort(sort_column);
1027 }
1028 
1030 {
1031  SetColumnSort(sort_column, sort);
1032 }
1033 
1034 // +--------------------------------------------------------------------+
1035 
1037 {
1038  if (sort_column >=0 && sort_column <= columns.size())
1039  items.sort();
1040 }
1041 
1042 // +--------------------------------------------------------------------+
1043 
1044 int ListBox::IndexFromPoint(int x, int y) const
1045 {
1046  int sel_index = -1;
1047 
1048  if (show_headings)
1049  sel_index = top_index + (y - (line_height+HEADING_EXTRA)) / (line_height + leading);
1050 
1051  else
1052  sel_index = top_index + y / (line_height + leading);
1053 
1054  return sel_index;
1055 }
1056 
1057 // +--------------------------------------------------------------------+
1058 
1059 int ListBox::OnMouseMove(int x, int y)
1060 {
1061  bool dirty = false;
1062 
1063  if (captured) {
1064  ActiveWindow* test = GetCapture();
1065 
1066  if (test != this) {
1067  captured = false;
1068  dirty = true;
1069  }
1070 
1071  else {
1072  if (selecting && !dragging) {
1073  if (dragdrop && (x < rect.x ||
1074  x > rect.x+rect.w ||
1075  y < rect.y ||
1076  y > rect.y+rect.h)) {
1077 
1078  dragging = true;
1079  OnDragStart(x,y);
1080  }
1081  }
1082 
1083  if (scrolling == SCROLL_THUMB) {
1084  mouse_y = y - rect.y - TRACK_START;
1085 
1086  int dest = (int) ((double) mouse_y/track_length * (items.size()-1));
1087  ScrollTo(dest);
1088  dirty = true;
1089  }
1090  }
1091  }
1092 
1093  return ActiveWindow::OnMouseMove(x,y);
1094 }
1095 
1096 // +--------------------------------------------------------------------+
1097 
1098 static bool preselected = false;
1099 
1100 int ListBox::OnLButtonDown(int x, int y)
1101 {
1102  if (!captured)
1103  captured = SetCapture();
1104 
1105  mouse_x = x - rect.x;
1106  mouse_y = y - rect.y;
1107 
1108  int x_scroll_bar = rect.w;
1109 
1110  if (IsScrollVisible())
1111  x_scroll_bar -= SCROLL_WIDTH;
1112 
1113  if (mouse_x < x_scroll_bar) {
1115 
1117  int next_col_start = 0;
1118  int max_column = columns.size()-1;
1119  int column;
1120 
1121  for (column = 0; column < max_column; column++) {
1122  next_col_start += GetColumnWidth(column);
1123 
1124  if (mouse_x < next_col_start)
1125  break;
1126  }
1127 
1128  sort_column = column;
1129 
1130  int& sort_criteria = columns[sort_column]->sort;
1131 
1132  if (sort_criteria != LIST_SORT_NEVER) {
1133  if (!sort_criteria)
1134  sort_criteria = LIST_SORT_ALPHA_DESCENDING;
1135  else
1136  sort_criteria = -sort_criteria;
1137 
1138  SortItems();
1139  }
1140  }
1141 
1142  else {
1143  selecting = true;
1144  }
1145  }
1146 
1147  else {
1148  selecting = false;
1149 
1150  if (mouse_y < TRACK_START) {
1151  scrolling = SCROLL_UP;
1152  Scroll(scrolling, 1);
1154  }
1155 
1156  else if (mouse_y > rect.h-TRACK_START) {
1158  if (top_index < items.size()-1)
1159  top_index++;
1161  }
1162 
1163  else if (mouse_y < thumb_pos) {
1167  }
1168 
1169  else if (mouse_y > thumb_pos+THUMB_HEIGHT) {
1173  }
1174 
1175  else {
1177  }
1178  }
1179 
1180  if (selecting) {
1182  preselected = IsSelected(list_index);
1183  if (!multiselect || !Keyboard::KeyDown(VK_SHIFT))
1184  ClearSelection();
1188  }
1189 
1190  return ActiveWindow::OnLButtonDown(x,y);
1191 }
1192 
1193 // +--------------------------------------------------------------------+
1194 
1195 int ListBox::OnLButtonUp(int x, int y)
1196 {
1197  if (captured) {
1198  mouse_x = x-rect.x;
1199  mouse_y = y-rect.y;
1200 
1201  if (dragging) {
1202  if (mouse_x < 0 || mouse_x > rect.w || mouse_y < 0 || mouse_y > rect.h) {
1203  FormWindow* parent_form = (FormWindow*) form;
1204 
1205  if (parent_form) {
1206  ActiveWindow* drop_target = parent_form->FindControl(x,y);
1207 
1208  if (drop_target && drop_target->IsEnabled() && drop_target->IsShown())
1209  drop_target->OnDragDrop(x,y,this);
1210  }
1211  }
1212  }
1213  else if (preselected) {
1214  if (multiselect && Keyboard::KeyDown(VK_SHIFT)) {
1215  SetSelected(list_index, false);
1217  }
1218  }
1219 
1220  ReleaseCapture();
1221  captured = false;
1222 
1223  Mouse::SetCursor((Mouse::CURSOR) old_cursor);
1224  }
1225 
1226  dragging = false;
1227  selecting = false;
1228 
1229  return ActiveWindow::OnLButtonUp(x,y);
1230 }
1231 
1232 // +--------------------------------------------------------------------+
1233 
1235 {
1236  return ScrollWindow::OnMouseWheel(wheel);
1237 }
1238 
1239 // +--------------------------------------------------------------------+
1240 
1242 {
1243  int fire_select = !scrolling;
1244 
1245  if (scrolling == SCROLL_THUMB)
1247 
1248  if (fire_select)
1249  return ActiveWindow::OnSelect();
1250  else
1251  return ActiveWindow::OnClick();
1252 
1253  return 0;
1254 }
1255 
1256 // +--------------------------------------------------------------------+
1257 
1258 int ListBox::OnKeyDown(int vk, int flags)
1259 {
1260  if (selcount == 1 && list_index >= 0 && list_index < items.size()) {
1261  ListBoxItem* item = items[list_index];
1262 
1263  if (vk == VK_DOWN) {
1264  if (list_index < items.size() - 1) {
1265  item->selected = false;
1266  list_index++;
1267  item = items[list_index];
1268  item->selected = true;
1269  OnClick();
1270  return ActiveWindow::OnKeyDown(vk, flags);
1271  }
1272  }
1273 
1274  else if (vk == VK_UP) {
1275  if (list_index > 0) {
1276  item->selected = false;
1277  list_index--;
1278  item = items[list_index];
1279  item->selected = true;
1280  OnClick();
1281  return ActiveWindow::OnKeyDown(vk, flags);
1282  }
1283  }
1284  }
1285 
1286  return ScrollWindow::OnKeyDown(vk, flags);
1287 }
1288 
1289 // +--------------------------------------------------------------------+
1290 
1291 int ListBox::OnDragStart(int x, int y)
1292 {
1293  old_cursor = Mouse::SetCursor(Mouse::DRAG);
1294  return ActiveWindow::OnDragStart(x,y);
1295 }
1296 
1297 // +--------------------------------------------------------------------+
1298 
1299 int ListBox::OnDragDrop(int x, int y, ActiveWindow* source)
1300 {
1301  if (!dragdrop) return 0;
1302 
1303  ListBox* drag_source = (ListBox*) source;
1304 
1305  if (drag_source) {
1306  int max_col = NumColumns();
1307 
1308  if (max_col != drag_source->NumColumns())
1309  max_col = 0;
1310 
1311  for (int i = 0; i < drag_source->NumItems(); i++) {
1312  if (drag_source->IsSelected(i)) {
1313  AddItemWithData(drag_source->GetItemText(i),
1314  drag_source->GetItemData(i));
1315 
1316  for (int c = 1; c < max_col; c++) {
1317  SetItemText(list_index, c, drag_source->GetItemText(i,c));
1318  SetItemData(list_index, c, drag_source->GetItemData(i,c));
1319  }
1320 
1321  if (!multiselect)
1322  ClearSelection();
1323 
1324  items[list_index]->selected = true;
1325  selcount++;
1326  }
1327  }
1328 
1329  drag_source->RemoveSelectedItems();
1331  }
1332 
1333  return ActiveWindow::OnDragDrop(x,y,source);
1334 }