• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files

hvirtual/guicast/bclistbox.C

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