00001 #include "bcdragwindow.h"
00002 #include "bclistbox.h"
00003 #include "bclistboxitem.h"
00004 #include "bcpixmap.h"
00005 #include "bcresources.h"
00006 #include "clip.h"
00007 #include "cursors.h"
00008 #include "fonts.h"
00009 #include "keys.h"
00010 #include "language.h"
00011 #include "bctimer.h"
00012 #include "vframe.h"
00013
00014 #include <string.h>
00015 #include <unistd.h>
00016
00017
00018
00019
00020 BC_ListBoxYScroll::BC_ListBoxYScroll(BC_ListBox *listbox,
00021 int total_height,
00022 int view_height,
00023 int position)
00024 : BC_ScrollBar(listbox->get_yscroll_x(),
00025 listbox->get_yscroll_y(),
00026 SCROLL_VERT,
00027 listbox->get_yscroll_height(),
00028 total_height,
00029 position,
00030 view_height)
00031 {
00032 this->listbox = listbox;
00033 }
00034
00035 BC_ListBoxYScroll::~BC_ListBoxYScroll()
00036 {
00037 }
00038
00039 int BC_ListBoxYScroll::handle_event()
00040 {
00041 listbox->set_yposition(get_value());
00042 return 1;
00043 }
00044
00045
00046
00047
00048
00049
00050
00051 BC_ListBoxXScroll::BC_ListBoxXScroll(BC_ListBox *listbox,
00052 int total_width,
00053 int view_width,
00054 int position)
00055 : BC_ScrollBar(listbox->get_xscroll_x(),
00056 listbox->get_xscroll_y(),
00057 SCROLL_HORIZ,
00058 listbox->get_xscroll_width(),
00059 total_width,
00060 position,
00061 view_width)
00062 {
00063 this->listbox = listbox;
00064 }
00065
00066 BC_ListBoxXScroll::~BC_ListBoxXScroll()
00067 {
00068 }
00069
00070 int BC_ListBoxXScroll::handle_event()
00071 {
00072 listbox->set_xposition(get_value());
00073 return 1;
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083 BC_ListBoxToggle::BC_ListBoxToggle(BC_ListBox *listbox,
00084 BC_ListBoxItem *item,
00085 int x,
00086 int y)
00087 {
00088 this->listbox = listbox;
00089 this->item = item;
00090 this->x = x;
00091 this->y = y;
00092 this->value = item->get_expand();
00093 if(this->value)
00094 state = BC_Toggle::TOGGLE_CHECKED;
00095 else
00096 state = BC_Toggle::TOGGLE_UP;
00097 }
00098
00099 void BC_ListBoxToggle::update(BC_ListBoxItem *item,
00100 int x,
00101 int y,
00102 int flash)
00103 {
00104 this->value = item->get_expand();
00105 this->item = item;
00106 this->x = x;
00107 this->y = y;
00108
00109
00110 switch(state)
00111 {
00112 case TOGGLE_UP:
00113 if(value)
00114 state = TOGGLE_CHECKED;
00115 break;
00116
00117 case TOGGLE_UPHI:
00118 if(value)
00119 state = TOGGLE_CHECKEDHI;
00120 break;
00121
00122 case TOGGLE_CHECKED:
00123 if(!value)
00124 state = TOGGLE_UP;
00125 break;
00126
00127 case TOGGLE_DOWN:
00128 break;
00129
00130 case TOGGLE_CHECKEDHI:
00131 if(!value)
00132 state = TOGGLE_UPHI;
00133 break;
00134
00135 case TOGGLE_DOWN_EXIT:
00136 break;
00137 }
00138
00139
00140 draw(flash);
00141 }
00142
00143 int BC_ListBoxToggle::cursor_motion_event(int *redraw_toggles)
00144 {
00145 int w = listbox->toggle_images[0]->get_w();
00146 int h = listbox->toggle_images[0]->get_h();
00147 int cursor_inside = listbox->get_cursor_x() >= x &&
00148 listbox->get_cursor_x() < x + w &&
00149 listbox->get_cursor_y() >= y &&
00150 listbox->get_cursor_y() < y + h;
00151 int result = 0;
00152
00153 switch(state)
00154 {
00155 case BC_ListBoxToggle::TOGGLE_UPHI:
00156 if(!cursor_inside)
00157 {
00158 state = BC_ListBoxToggle::TOGGLE_UP;
00159 *redraw_toggles = 1;
00160 }
00161 break;
00162
00163 case BC_ListBoxToggle::TOGGLE_CHECKEDHI:
00164 if(!cursor_inside)
00165 {
00166 state = BC_ListBoxToggle::TOGGLE_CHECKED;
00167 *redraw_toggles = 1;
00168 }
00169 break;
00170
00171 case BC_ListBoxToggle::TOGGLE_DOWN:
00172 if(!cursor_inside)
00173 {
00174 state = BC_ListBoxToggle::TOGGLE_DOWN_EXIT;
00175 *redraw_toggles = 1;
00176 }
00177 result = 1;
00178 break;
00179
00180 case BC_ListBoxToggle::TOGGLE_DOWN_EXIT:
00181 if(cursor_inside)
00182 {
00183 state = BC_ListBoxToggle::TOGGLE_DOWN;
00184 *redraw_toggles = 1;
00185 }
00186 result = 1;
00187 break;
00188
00189 default:
00190 if(cursor_inside)
00191 {
00192 if(value)
00193 state = BC_ListBoxToggle::TOGGLE_CHECKEDHI;
00194 else
00195 state = BC_ListBoxToggle::TOGGLE_UPHI;
00196 *redraw_toggles = 1;
00197 }
00198 break;
00199 }
00200 return result;
00201 }
00202
00203 int BC_ListBoxToggle::cursor_leave_event(int *redraw_toggles)
00204 {
00205 if(value)
00206 state = BC_ListBoxToggle::TOGGLE_CHECKED;
00207 else
00208 state = BC_ListBoxToggle::TOGGLE_UP;
00209 }
00210
00211 int BC_ListBoxToggle::button_press_event()
00212 {
00213 int w = listbox->toggle_images[0]->get_w();
00214 int h = listbox->toggle_images[0]->get_h();
00215
00216 if(listbox->gui->get_cursor_x() >= x &&
00217 listbox->gui->get_cursor_x() < x + w &&
00218 listbox->gui->get_cursor_y() >= y &&
00219 listbox->gui->get_cursor_y() < y + h)
00220 {
00221 state = BC_ListBoxToggle::TOGGLE_DOWN;
00222 return 1;
00223 }
00224 return 0;
00225 }
00226
00227 int BC_ListBoxToggle::button_release_event(int *redraw_toggles)
00228 {
00229 int result = 0;
00230 switch(state)
00231 {
00232 case BC_ListBoxToggle::TOGGLE_DOWN:
00233 value = !value;
00234 if(value)
00235 state = BC_ListBoxToggle::TOGGLE_CHECKEDHI;
00236 else
00237 state = BC_ListBoxToggle::TOGGLE_UPHI;
00238 listbox->expand_item(item, value);
00239 result = 1;
00240 break;
00241
00242 case BC_ListBoxToggle::TOGGLE_DOWN_EXIT:
00243 if(value)
00244 state = BC_ListBoxToggle::TOGGLE_CHECKED;
00245 else
00246 state = BC_ListBoxToggle::TOGGLE_UP;
00247 *redraw_toggles = 1;
00248 result = 1;
00249 break;
00250 }
00251 return result;
00252 }
00253
00254 void BC_ListBoxToggle::draw(int flash)
00255 {
00256 if(listbox->gui)
00257 {
00258 int image_number = 0;
00259 int w = listbox->toggle_images[0]->get_w();
00260 int h = listbox->toggle_images[0]->get_h();
00261
00262 switch(state)
00263 {
00264 case BC_ListBoxToggle::TOGGLE_UP: image_number = 0; break;
00265 case BC_ListBoxToggle::TOGGLE_UPHI: image_number = 1; break;
00266 case BC_ListBoxToggle::TOGGLE_CHECKED: image_number = 2; break;
00267 case BC_ListBoxToggle::TOGGLE_DOWN: image_number = 3; break;
00268 case BC_ListBoxToggle::TOGGLE_CHECKEDHI: image_number = 4; break;
00269 case BC_ListBoxToggle::TOGGLE_DOWN_EXIT:
00270 if(value)
00271 image_number = 2;
00272 else
00273 image_number = 0;
00274 break;
00275 }
00276
00277
00278 listbox->gui->draw_pixmap(listbox->toggle_images[image_number],
00279 x,
00280 y);
00281
00282
00283 if(flash)
00284 {
00285 listbox->gui->flash(x, y, w, h);
00286 listbox->gui->flush();
00287 }
00288 }
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 BC_ListBox::BC_ListBox(int x,
00307 int y,
00308 int w,
00309 int h,
00310 int display_format,
00311 ArrayList<BC_ListBoxItem*> *data,
00312 char **column_titles,
00313 int *column_width,
00314 int columns,
00315 int yposition,
00316 int is_popup,
00317 int selection_mode,
00318 int icon_position,
00319 int allow_drag)
00320 : BC_SubWindow(x, y, w, h, -1)
00321 {
00322 justify = LISTBOX_RIGHT;
00323 xposition = 0;
00324 highlighted_item = -1;
00325 highlighted_title = -1;
00326 highlighted_division = -1;
00327 highlighted_ptr = 0;
00328 xscrollbar = 0;
00329 yscrollbar = 0;
00330 current_cursor = ARROW_CURSOR;
00331 gui = 0;
00332 view_h = 0;
00333 view_w = 0;
00334 title_h = 0;
00335 active = 0;
00336 new_value = 0;
00337 need_xscroll = 0;
00338 need_yscroll = 0;
00339 bg_tile = 0;
00340 drag_popup = 0;
00341 selection_number1 = -1;
00342 selection_number2 = -1;
00343 bg_surface = 0;
00344 bg_pixmap = 0;
00345
00346 current_operation = NO_OPERATION;
00347 button_highlighted = 0;
00348
00349 disabled = 0;
00350
00351 list_highlighted = 0;
00352
00353 allow_drag_scroll = 1;
00354 process_drag = 1;
00355
00356 sort_column = -1;
00357 sort_order = 0;
00358
00359 allow_drag_column = 0;
00360 master_column = 0;
00361 search_column = 0;
00362
00363 popup_w = w;
00364 popup_h = h;
00365
00366 for(int i = 0; i < 3; i++)
00367 column_bg[i] = 0;
00368
00369 for(int i = 0; i < 4; i++)
00370 button_images[i] = 0;
00371
00372 for(int i = 0; i < 5; i++)
00373 toggle_images[i] = 0;
00374
00375 column_sort_up = 0;
00376 column_sort_dn = 0;
00377
00378
00379 this->data = data;
00380 this->columns = columns;
00381 this->yposition = yposition;
00382 this->is_popup = is_popup;
00383 this->display_format = display_format;
00384 this->selection_mode = selection_mode;
00385 this->icon_position = icon_position;
00386 this->allow_drag = allow_drag;
00387 this->column_titles = 0;
00388 this->column_width = 0;
00389
00390
00391 if((!column_titles && column_width) ||
00392 (column_titles && !column_width))
00393 {
00394 printf("BC_ListBox::BC_ListBox either column_titles or column_widths == NULL but not both.\n");
00395 }
00396
00397 set_columns(column_titles,
00398 column_width,
00399 columns);
00400
00401
00402
00403 drag_icon_vframe = 0;
00404 drag_column_icon_vframe = 0;
00405
00406
00407
00408
00409
00410 reset_query();
00411
00412 }
00413
00414 BC_ListBox::~BC_ListBox()
00415 {
00416 expanders.remove_all_objects();
00417 if(bg_surface) delete bg_surface;
00418 if(bg_pixmap) delete bg_pixmap;
00419 if(xscrollbar) delete xscrollbar;
00420 if(yscrollbar) delete yscrollbar;
00421 for(int i = 0; i < 3; i++)
00422 if(column_bg[i]) delete column_bg[i];
00423 for(int i = 0; i < 4; i++)
00424 if(button_images[i]) delete button_images[i];
00425 for(int i = 0; i < 5; i++)
00426 if(toggle_images[i]) delete toggle_images[i];
00427 if(column_sort_up) delete column_sort_up;
00428 if(column_sort_dn) delete column_sort_dn;
00429
00430 delete_columns();
00431 if(drag_popup) delete drag_popup;
00432 }
00433
00434 int BC_ListBox::enable()
00435 {
00436 disabled = 0;
00437 draw_button();
00438 return 1;
00439 }
00440
00441 int BC_ListBox::disable()
00442 {
00443 disabled = 1;
00444 draw_button();
00445 return 1;
00446 }
00447
00448 void BC_ListBox::reset_query()
00449 {
00450 query[0] = 0;
00451 }
00452
00453 int BC_ListBox::evaluate_query(int list_item, char *string)
00454 {
00455 return(strcmp(string, data[search_column].values[list_item]->text) <= 0 &&
00456 data[search_column].values[list_item]->searchable);
00457 }
00458
00459 int BC_ListBox::query_list()
00460 {
00461 if(query[0] == 0) return 0;
00462
00463 int done = 0;
00464 int result;
00465 int selection_changed = 0;
00466 int prev_selection = -1;
00467 for(int i = 0; !done && i < data[0].total; i++)
00468 {
00469 if(evaluate_query(i, query))
00470 {
00471 result = i;
00472 done = 1;
00473 }
00474 }
00475
00476 if(done)
00477 {
00478
00479 for(int i = 0; i < data[0].total; i++)
00480 {
00481 for(int j = 0; j < columns; j++)
00482 {
00483 if(data[j].values[i]->selected) prev_selection = i;
00484 data[j].values[i]->selected = 0;
00485 }
00486 }
00487
00488
00489 if(prev_selection != result)
00490 selection_changed = 1;
00491 for(int j = 0; j < columns; j++)
00492 {
00493 data[j].values[result]->selected = 1;
00494 }
00495 center_selection(result);
00496 }
00497
00498 return selection_changed;
00499 }
00500
00501 void BC_ListBox::init_column_width()
00502 {
00503 if(!column_width && data)
00504 {
00505 int widest = 5, w;
00506 for(int i = 0; i < data[0].total; i++)
00507 {
00508 w = get_text_width(MEDIUMFONT, data[0].values[i]->get_text()) + 2 * LISTBOX_MARGIN;
00509 if(w > widest) widest = w;
00510 }
00511 default_column_width[0] = widest;
00512 }
00513 }
00514
00515 int BC_ListBox::initialize()
00516 {
00517 if(is_popup)
00518 {
00519 for(int i = 0; i < 4; i++)
00520 {
00521 button_images[i] = new BC_Pixmap(parent_window,
00522 BC_WindowBase::get_resources()->listbox_button[i],
00523 PIXMAP_ALPHA);
00524 }
00525 w = button_images[0]->get_w();
00526 h = button_images[0]->get_h();
00527
00528 gui = 0;
00529 current_operation = NO_OPERATION;
00530 }
00531 else
00532 {
00533 gui = this;
00534 current_operation = NO_OPERATION;
00535 }
00536
00537 for(int i = 0; i < 3; i++)
00538 {
00539 column_bg[i] = new BC_Pixmap(parent_window,
00540 get_resources()->listbox_column[i],
00541 PIXMAP_ALPHA);
00542 }
00543 for(int i = 0; i < 5; i++)
00544 {
00545 toggle_images[i] = new BC_Pixmap(parent_window,
00546 get_resources()->listbox_expand[i],
00547 PIXMAP_ALPHA);
00548 }
00549
00550 column_sort_up = new BC_Pixmap(parent_window,
00551 BC_WindowBase::get_resources()->listbox_up,
00552 PIXMAP_ALPHA);
00553 column_sort_dn = new BC_Pixmap(parent_window,
00554 BC_WindowBase::get_resources()->listbox_dn,
00555 PIXMAP_ALPHA);
00556
00557
00558 drag_icon_vframe = get_resources()->type_to_icon[ICON_UNKNOWN];
00559 drag_column_icon_vframe = get_resources()->type_to_icon[ICON_COLUMN];
00560
00561
00562
00563
00564
00565
00566 BC_SubWindow::initialize();
00567
00568 init_column_width();
00569
00570 if(top_level->get_resources()->listbox_bg)
00571 bg_pixmap = new BC_Pixmap(this,
00572 get_resources()->listbox_bg,
00573 PIXMAP_OPAQUE);
00574
00575 draw_button();
00576 draw_items(1);
00577 return 0;
00578 }
00579
00580 void BC_ListBox::deactivate_selection()
00581 {
00582 current_operation = NO_OPERATION;
00583 }
00584
00585 int BC_ListBox::draw_button()
00586 {
00587
00588 if(is_popup)
00589 {
00590 int image_number = 0;
00591
00592 draw_top_background(parent_window, 0, 0, w, h);
00593
00594 if(button_highlighted)
00595 image_number = 1;
00596 if(current_operation == BUTTON_DN)
00597 image_number = 2;
00598 if(disabled)
00599 image_number = 3;
00600
00601
00602 button_images[image_number]->write_drawable(pixmap,
00603 0,
00604 0,
00605 w,
00606 h,
00607 0,
00608 0);
00609 flash();
00610 }
00611 return 0;
00612 }
00613
00614 int BC_ListBox::calculate_item_coords()
00615 {
00616 if(!data) return 0;
00617
00618 int icon_x = 0;
00619 int next_icon_x = 0;
00620 int next_icon_y = 0;
00621 int next_text_y = 0;
00622
00623
00624 int display_format_temp = display_format;
00625
00626
00627
00628
00629 calculate_last_coords_recursive(data,
00630 &icon_x,
00631 &next_icon_x,
00632 &next_icon_y,
00633 &next_text_y,
00634 1);
00635
00636
00637
00638 calculate_item_coords_recursive(data,
00639 &icon_x,
00640 &next_icon_x,
00641 &next_icon_y,
00642 &next_text_y,
00643 1);
00644
00645
00646
00647 display_format = display_format_temp;
00648
00649 return 0;
00650 }
00651
00652 void BC_ListBox::calculate_last_coords_recursive(
00653 ArrayList<BC_ListBoxItem*> *data,
00654 int *icon_x,
00655 int *next_icon_x,
00656 int *next_icon_y,
00657 int *next_text_y,
00658 int top_level)
00659 {
00660 for(int i = 0; i < data[0].total; i++)
00661 {
00662 int current_text_y = 0;
00663 int current_icon_x = 0;
00664 int current_icon_y = 0;
00665 BC_ListBoxItem *item = data[0].values[i];
00666
00667
00668 if(!item->autoplace_text)
00669 {
00670
00671 display_format = LISTBOX_TEXT;
00672 current_text_y = item->text_y +
00673 get_text_height(MEDIUMFONT);
00674 if(current_text_y > *next_text_y)
00675 *next_text_y = current_text_y;
00676
00677
00678 if(item->get_sublist() &&
00679 item->get_columns() &&
00680 item->get_expand())
00681 {
00682 calculate_last_coords_recursive(item->get_sublist(),
00683 icon_x,
00684 next_icon_x,
00685 next_icon_y,
00686 next_text_y,
00687 0);
00688 }
00689 }
00690
00691
00692 if(top_level)
00693 {
00694 BC_ListBoxItem *item = data[master_column].values[i];
00695 if(!item->autoplace_icon)
00696 {
00697 display_format = LISTBOX_ICONS;
00698
00699 current_icon_x = item->icon_x;
00700 if(current_icon_x > *icon_x) *icon_x = current_icon_x;
00701 if(current_icon_x + get_item_w(item) > *next_icon_x)
00702 *next_icon_x = current_icon_x + get_item_w(item);
00703
00704 current_icon_y = item->icon_y + get_item_h(item);
00705 if(current_icon_y > *next_icon_y)
00706 *next_icon_y = current_icon_y;
00707 }
00708 }
00709 }
00710 }
00711
00712
00713 void BC_ListBox::calculate_item_coords_recursive(
00714 ArrayList<BC_ListBoxItem*> *data,
00715 int *icon_x,
00716 int *next_icon_x,
00717 int *next_icon_y,
00718 int *next_text_y,
00719 int top_level)
00720 {
00721
00722
00723
00724
00725
00726 for(int i = 0; i < data[0].total; i++)
00727 {
00728
00729 int total_autoplaced_columns = 0;
00730
00731
00732 if(top_level)
00733 {
00734 BC_ListBoxItem *item = data[master_column].values[i];
00735 if(item->autoplace_icon)
00736 {
00737
00738 display_format = LISTBOX_ICONS;
00739
00740
00741 if(*next_icon_y + get_item_h(item) >= get_h() &&
00742 *next_icon_y > 0)
00743 {
00744 *icon_x = *next_icon_x;
00745 *next_icon_y = 0;
00746 }
00747
00748 if(*icon_x + get_item_w(item) > *next_icon_x)
00749 *next_icon_x = *icon_x + get_item_w(item);
00750
00751
00752 item->set_icon_x(*icon_x);
00753 item->set_icon_y(*next_icon_y);
00754
00755 *next_icon_y += get_item_h(item);
00756 }
00757 }
00758
00759
00760
00761
00762 int next_text_x = 0;
00763 for(int j = 0; j < columns; j++)
00764 {
00765 BC_ListBoxItem *item = data[j].values[i];
00766 if(item->autoplace_text)
00767 {
00768 display_format = LISTBOX_TEXT;
00769 item->set_text_x(next_text_x);
00770 item->set_text_y(*next_text_y);
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780 if(j < columns - 1)
00781 next_text_x += (column_width ?
00782 column_width[j] :
00783 default_column_width[j]);
00784 else
00785
00786 {
00787 int new_w = get_item_w(item);
00788
00789 int *previous_w = (column_width ?
00790 &column_width[j] :
00791 &default_column_width[j]);
00792 if(new_w > *previous_w)
00793 *previous_w = new_w;
00794
00795 }
00796 total_autoplaced_columns++;
00797 }
00798 }
00799
00800
00801 if(total_autoplaced_columns)
00802 {
00803 display_format = LISTBOX_TEXT;
00804 *next_text_y += get_text_height(MEDIUMFONT);
00805 }
00806
00807
00808 BC_ListBoxItem *item = data[master_column].values[i];
00809 if(item->get_sublist() &&
00810 item->get_columns() &&
00811 item->get_expand())
00812 {
00813 calculate_item_coords_recursive(
00814 item->get_sublist(),
00815 icon_x,
00816 next_icon_x,
00817 next_icon_y,
00818 next_text_y,
00819 0);
00820 }
00821 }
00822 }
00823
00824 void BC_ListBox::set_justify(int value)
00825 {
00826 this->justify = value;
00827 }
00828
00829 void BC_ListBox::set_allow_drag_column(int value)
00830 {
00831 this->allow_drag_column = value;
00832 }
00833
00834 void BC_ListBox::set_process_drag(int value)
00835 {
00836 this->process_drag = value;
00837 }
00838
00839 void BC_ListBox::set_master_column(int value, int redraw)
00840 {
00841 this->master_column = value;
00842 if(redraw)
00843 {
00844 draw_items(1);
00845 }
00846 }
00847
00848 void BC_ListBox::set_search_column(int value)
00849 {
00850 this->search_column = value;
00851 }
00852
00853 int BC_ListBox::get_sort_column()
00854 {
00855 return sort_column;
00856 }
00857
00858 void BC_ListBox::set_sort_column(int value, int redraw)
00859 {
00860 sort_column = value;
00861 if(redraw)
00862 {
00863 draw_titles(1);
00864 }
00865 }
00866
00867 int BC_ListBox::get_sort_order()
00868 {
00869 return sort_order;
00870 }
00871
00872 void BC_ListBox::set_sort_order(int value, int redraw)
00873 {
00874 sort_order = value;
00875 if(redraw)
00876 {
00877 draw_titles(1);
00878 }
00879 }
00880
00881
00882
00883
00884
00885 int BC_ListBox::get_display_mode()
00886 {
00887 return display_format;
00888 }
00889
00890 int BC_ListBox::get_yposition()
00891 {
00892 return yposition;
00893 }
00894
00895 int BC_ListBox::get_xposition()
00896 {
00897 return xposition;
00898 }
00899
00900 int BC_ListBox::get_highlighted_item()
00901 {
00902 return highlighted_item;
00903 }
00904
00905
00906 int BC_ListBox::get_item_x(BC_ListBoxItem *item)
00907 {
00908 if(display_format == LISTBOX_TEXT)
00909 return item->text_x - xposition + 2;
00910 else
00911 return item->icon_x - xposition + 2;
00912 }
00913
00914 int BC_ListBox::get_item_y(BC_ListBoxItem *item)
00915 {
00916 int result;
00917 if(display_format == LISTBOX_TEXT)
00918 result = item->text_y - yposition + title_h + 2;
00919 else
00920 result = item->icon_y - yposition + title_h + 2;
00921 return result;
00922 }
00923
00924 int BC_ListBox::get_item_w(BC_ListBoxItem *item)
00925 {
00926 if(display_format == LISTBOX_ICONS)
00927 {
00928 int x, y, w, h;
00929 get_icon_mask(item, x, y, w, h);
00930 int icon_w = w;
00931 get_text_mask(item, x, y, w, h);
00932 int text_w = w;
00933
00934 if(icon_position == ICON_LEFT)
00935 return icon_w + text_w;
00936 else
00937 return (icon_w > text_w) ? icon_w : text_w;
00938 }
00939 else
00940 {
00941 return get_text_width(MEDIUMFONT, item->text) + 2 * LISTBOX_MARGIN;
00942 }
00943 }
00944
00945 int BC_ListBox::get_item_h(BC_ListBoxItem *item)
00946 {
00947 if(display_format == LISTBOX_ICONS)
00948 {
00949 int x, y, w, h;
00950 get_icon_mask(item, x, y, w, h);
00951 int icon_h = h;
00952 get_text_mask(item, x, y, w, h);
00953 int text_h = h;
00954
00955 if(icon_position == ICON_LEFT)
00956 return (icon_h > text_h) ? icon_h : text_h;
00957 else
00958 return icon_h + text_h;
00959 }
00960 else
00961 {
00962 return get_text_height(MEDIUMFONT);
00963 }
00964 return 0;
00965 }
00966
00967
00968 int BC_ListBox::get_icon_w(BC_ListBoxItem *item)
00969 {
00970 BC_Pixmap *icon = item->icon;
00971 if(icon) return icon->get_w();
00972 return 0;
00973 }
00974
00975 int BC_ListBox::get_icon_h(BC_ListBoxItem *item)
00976 {
00977 BC_Pixmap *icon = item->icon;
00978 if(icon) return icon->get_h();
00979 return 0;
00980 }
00981
00982 int BC_ListBox::get_items_width()
00983 {
00984 int widest = 0;
00985
00986 if(display_format == LISTBOX_ICONS)
00987 {
00988 for(int i = 0; i < columns; i++)
00989 {
00990 for(int j = 0; j < data[i].total; j++)
00991 {
00992 int x1, x, y, w, h;
00993 BC_ListBoxItem *item = data[i].values[j];
00994 x1 = item->icon_x;
00995
00996 get_icon_mask(item, x, y, w, h);
00997 if(x1 + w > widest) widest = x1 + w;
00998
00999 if(display_format == LISTBOX_ICONS && icon_position == ICON_LEFT)
01000 x1 += w;
01001
01002 get_text_mask(item, x, y, w, h);
01003 if(x1 + w > widest) widest = x1 + w;
01004 }
01005 }
01006 }
01007 else
01008 if(display_format == LISTBOX_TEXT)
01009 {
01010 return get_column_offset(columns);
01011 }
01012 return widest;
01013 }
01014
01015 int BC_ListBox::get_items_height(ArrayList<BC_ListBoxItem*> *data,
01016 int columns,
01017 int *result)
01018 {
01019 int temp = 0;
01020 int top_level = 0;
01021 int highest = 0;
01022 if(!result)
01023 {
01024 result = &temp;
01025 top_level = 1;
01026 }
01027
01028
01029
01030
01031
01032 for(int j = 0; j < (data ? data[master_column].total : 0); j++)
01033 {
01034 int y1, x, y, w, h;
01035 BC_ListBoxItem *item = data[master_column].values[j];
01036
01037 if(display_format == LISTBOX_ICONS)
01038 {
01039 get_icon_mask(item, x, y, w, h);
01040 if(y + h + yposition > highest) highest = y + h + yposition;
01041
01042 get_text_mask(item, x, y, w, h);
01043 if(y + h + yposition > highest) highest = y + h + yposition;
01044 }
01045 else
01046 {
01047 get_text_mask(item, x, y, w, h);
01048 *result += h;
01049
01050
01051
01052 if(item->get_sublist() &&
01053 item->get_expand())
01054 {
01055 get_items_height(item->get_sublist(),
01056 item->get_columns(),
01057 result);
01058 }
01059 }
01060 }
01061 if(display_format == LISTBOX_TEXT && top_level)
01062 {
01063 highest = LISTBOX_MARGIN + *result;
01064 }
01065
01066
01067 return highest;
01068 }
01069
01070 int BC_ListBox::set_yposition(int position, int draw_items)
01071 {
01072 this->yposition = position;
01073 if(draw_items)
01074 {
01075 this->draw_items(1);
01076 }
01077 return 0;
01078 }
01079
01080 int BC_ListBox::set_xposition(int position)
01081 {
01082 this->xposition = position;
01083 draw_items(1);
01084 return 0;
01085 }
01086
01087 void BC_ListBox::expand_item(BC_ListBoxItem *item, int expand)
01088 {
01089 if(item)
01090 {
01091 item->expand = expand;
01092
01093
01094 if(item->get_sublist())
01095 collapse_recursive(item->get_sublist(), master_column);
01096
01097
01098
01099
01100 set_autoplacement(data, 0, 1);
01101
01102 draw_items(1);
01103 }
01104 }
01105
01106 void BC_ListBox::collapse_recursive(ArrayList<BC_ListBoxItem*> *data,
01107 int master_column)
01108 {
01109 for(int i = 0; i < data[master_column].total; i++)
01110 {
01111 BC_ListBoxItem *item = data[master_column].values[i];
01112 if(item->get_sublist() && item->expand)
01113 {
01114 item->expand = 0;
01115 collapse_recursive(item->get_sublist(), master_column);
01116 }
01117 }
01118 }
01119
01120 void BC_ListBox::set_autoplacement(ArrayList<BC_ListBoxItem*> *data,
01121 int do_icons,
01122 int do_text)
01123 {
01124 for(int i = 0; i < data[0].total; i++)
01125 {
01126 for(int j = 0; j < columns; j++)
01127 {
01128 if(do_icons) data[j].values[i]->autoplace_icon = 1;
01129 if(do_text) data[j].values[i]->autoplace_text = 1;
01130 }
01131
01132 BC_ListBoxItem *item = data[master_column].values[i];
01133 if(item->get_sublist())
01134 {
01135 set_autoplacement(item->get_sublist(), do_icons, do_text);
01136 }
01137 }
01138 }
01139
01140
01141
01142 int BC_ListBox::get_w()
01143 {
01144 if(is_popup)
01145 return BCPOPUPLISTBOX_W;
01146 else
01147 return popup_w;
01148 }
01149
01150 int BC_ListBox::get_h()
01151 {
01152 if(is_popup)
01153 return BCPOPUPLISTBOX_H;
01154 else
01155 return popup_h;
01156 }
01157
01158 int BC_ListBox::get_yscroll_x()
01159 {
01160 if(is_popup)
01161 return popup_w - get_resources()->vscroll_data[SCROLL_HANDLE_UP]->get_w();
01162 else
01163 return get_x() +
01164 popup_w -
01165 get_resources()->vscroll_data[SCROLL_HANDLE_UP]->get_w();
01166 }
01167
01168 int BC_ListBox::get_yscroll_y()
01169 {
01170 if(is_popup)
01171 return 0;
01172 else
01173 return get_y();
01174 }
01175
01176 int BC_ListBox::get_yscroll_height()
01177 {
01178 return popup_h - (need_xscroll ?
01179 get_resources()->hscroll_data[SCROLL_HANDLE_UP]->get_h() :
01180 0);
01181 }
01182
01183 int BC_ListBox::get_xscroll_x()
01184 {
01185 if(is_popup)
01186 return 0;
01187 else
01188 return get_x();
01189 }
01190
01191 int BC_ListBox::get_xscroll_y()
01192 {
01193 if(is_popup)
01194 return popup_h -
01195 get_resources()->hscroll_data[SCROLL_HANDLE_UP]->get_h();
01196 else
01197 return get_y() +
01198 popup_h -
01199 get_resources()->hscroll_data[SCROLL_HANDLE_UP]->get_h();
01200 }
01201
01202 int BC_ListBox::get_xscroll_width()
01203 {
01204 return popup_w - (need_yscroll ?
01205 get_resources()->vscroll_data[SCROLL_HANDLE_UP]->get_w() :
01206 0);
01207 }
01208
01209 int BC_ListBox::get_column_offset(int column)
01210 {
01211 int x = 0;
01212 while(column > 0)
01213 {
01214 x += column_width ?
01215 column_width[--column] :
01216 default_column_width[--column];
01217 }
01218 return x;
01219 }
01220
01221 void BC_ListBox::column_width_boundaries()
01222 {
01223 if(column_width)
01224 {
01225 for(int i = 0; i < columns; i++)
01226 {
01227 if(column_width[i] < MIN_COLUMN_WIDTH) column_width[i] = MIN_COLUMN_WIDTH;
01228 }
01229 }
01230 else
01231 {
01232 for(int i = 0; i < columns; i++)
01233 {
01234 if(default_column_width[i] < MIN_COLUMN_WIDTH) default_column_width[i] = MIN_COLUMN_WIDTH;
01235 }
01236 }
01237 }
01238
01239 int BC_ListBox::get_column_width(int column, int clamp_right)
01240 {
01241 if(column < columns - 1 || !clamp_right)
01242 return column_width ?
01243 column_width[column] :
01244 default_column_width[column];
01245 else
01246 return popup_w +
01247 xposition -
01248 get_column_offset(column);
01249 }
01250
01251 int BC_ListBox::get_icon_mask(BC_ListBoxItem *item,
01252 int &x,
01253 int &y,
01254 int &w,
01255 int &h)
01256 {
01257 if(display_format == LISTBOX_ICONS)
01258 {
01259 x = get_item_x(item);
01260 y = get_item_y(item);
01261 w = get_icon_w(item) + ICON_MARGIN * 2;
01262 h = get_icon_h(item) + ICON_MARGIN * 2;
01263 }
01264 else
01265 if(display_format == LISTBOX_TEXT)
01266 {
01267 x = y = w = h = 0;
01268 }
01269 return 0;
01270 }
01271
01272 int BC_ListBox::get_text_mask(BC_ListBoxItem *item,
01273 int &x,
01274 int &y,
01275 int &w,
01276 int &h)
01277 {
01278 x =