/* * Copyright (C) Volition, Inc. 1999. All rights reserved. * * All source code herein is the property of Volition, Inc. You may not sell * or otherwise commercially exploit the source or things you created based on the * source. * */ #include "ui/uidefs.h" #include "ui/ui.h" #include "io/timer.h" #include "io/key.h" #include "globalincs/alphacolors.h" #define KEY_BUFFER_TIMEOUT 1000 // time to clear buffer in milliseconds #define DEFAULT_LISTBOX_ITEM_LENGTH 128 // -------------------------------------------------------------------- // UI_LISTBOX::link_hotspot // // void UI_LISTBOX::link_hotspot(int up_button_num, int down_button_num) { scrollbar.link_hotspot(up_button_num,down_button_num); } // -------------------------------------------------------------------- // UI_LISTBOX::set_bmaps // // Call the UI_SCROLLBAR::set_bmaps() function for the scroll bar gadget. // // returns: -1 ==> error // 0 ==> success // int UI_LISTBOX::set_bmaps(char *lbox_fname, char *b_up_fname, char *b_down_fname, char *sb_fname) { if (has_scrollbar) { scrollbar.set_bmaps(b_up_fname, b_down_fname, sb_fname); } // set the bitmaps for the list box rectangle UI_GADGET::set_bmaps(lbox_fname); uses_bmaps = 1; return 0; } void UI_LISTBOX::create(UI_WINDOW *wnd, int _x, int _y, int _w, int _h, int _numitems, char **_list, char *_check_list, int _max_items) { int tw, th, nrows; int real_h; gr_set_font(wnd->f_id); gr_get_string_size(&tw, &th, "*"); nrows = _h / th; real_h = nrows * th; base_create( wnd, UI_KIND_LISTBOX, _x, _y, _w, real_h ); max_items = _max_items; list = _list; num_items = _numitems; check_list = _check_list; num_items_displayed = nrows; first_item = 0; current_item = -1; toggled_item = -1; last_scrolled = 0; textheight = th; dragging = 0; selected_item = -1; key_buffer_count = 0; last_typed = timer_get_milliseconds(); if (_numitems > nrows) { scrollbar.create( wnd, _x+_w+3, _y, real_h, 0, _numitems-nrows, 0, nrows ); scrollbar.set_parent(this); has_scrollbar = 1; } else { has_scrollbar = 0; } // kazan draw_frame = 1; } void UI_LISTBOX::set_drawframe(int mode) { draw_frame = mode; } void UI_LISTBOX::draw() { int i, x1, y1, stop; int w1, h1; UI_GADGET::draw(); gr_set_font(my_wnd->f_id); if (uses_bmaps) { if (disabled_flag) { if ( bmap_ids[LBOX_DISABLED] >= 0 ) { gr_set_bitmap(bmap_ids[LBOX_DISABLED]); gr_bitmap(x, y, GR_RESIZE_MENU); } } else { if ( bmap_ids[LBOX_NORMAL] >= 0 ) { gr_set_bitmap(bmap_ids[LBOX_NORMAL]); gr_bitmap(x, y, GR_RESIZE_MENU); } } } else { gr_set_color_fast(&CBLACK); gr_set_clip( x, y, w, h, GR_RESIZE_MENU ); ui_rect( 0, 0, w-1, h-1 ); gr_reset_clip(); if (draw_frame) { if (has_scrollbar) { ui_draw_sunken_border( x-2, y-2, x+w+scrollbar.w+4, y+h+1 ); } else { ui_draw_sunken_border( x-2, y-2, x+w+4, y+h+1 ); } } } stop = first_item+num_items_displayed; if (stop>num_items) stop = num_items; x1 = y1 = 0; gr_set_clip( x, y, w, h, GR_RESIZE_MENU ); for ( i=first_item; iselected_gadget == this ) && (i == first_item) ) { if ( !uses_bmaps ) { gr_set_color_fast( &CBLACK ); gr_rect( x1, y1, w1+2, h1, GR_RESIZE_MENU_NO_OFFSET ); } current_item = first_item; gr_set_color_fast( &CBRIGHT_GREEN ); } else { if ( !uses_bmaps ) { gr_set_color_fast( &CBLACK ); gr_rect( x1, y1, w1+2, h1, GR_RESIZE_MENU_NO_OFFSET ); } gr_set_color_fast( &CWHITE ); } */ if (!uses_bmaps) { gr_set_color_fast( &CBLACK ); gr_rect( x1, y1, w1+2, h1, GR_RESIZE_MENU_NO_OFFSET ); } gr_set_color_fast(&CWHITE); } else { if (my_wnd->selected_gadget == this) { gr_set_color_fast( &CGRAY ); gr_rect( x1, y1, w1+2, h1, GR_RESIZE_MENU_NO_OFFSET ); gr_set_color_fast( &CBRIGHT_GREEN ); } else { gr_set_color_fast( &CGRAY ); gr_rect( x1, y1, w1+2, h1, GR_RESIZE_MENU_NO_OFFSET ); gr_set_color_fast( &CBLACK ); } } if ( check_list ) { if ( check_list[i] ) { gr_string( x1+2, y1, "X", GR_RESIZE_MENU ); } gr_string( x1+16, y1, list[i], GR_RESIZE_MENU ); } else gr_string( x1+2, y1, list[i], GR_RESIZE_MENU ); if (i==current_item) gr_set_color_fast( &CGRAY ); else gr_set_color_fast( &CBLACK ); if ( !uses_bmaps ) { ui_rect( x1+w1+2, y1, w-1, y1+h1-1 ); ui_rect( x1, y1, x1+1, y1+h1-1 ); } y1 += h1; } if (stop < num_items_displayed-1 && !uses_bmaps) { gr_set_color_fast(&CBLACK); ui_rect( x1, y1, w-1, h-1 ); } } void UI_LISTBOX::process(int focus) { int OnMe, mitem, kf = 0; int i, j; selected_item = -1; toggled_item = -1; if (disabled_flag) return; if (my_wnd->selected_gadget == this) focus = 1; if (has_scrollbar) { scrollbar.process(0); if (my_wnd->selected_gadget == &scrollbar) { set_focus(); focus = 1; } } if (num_items < 1) { current_item = -1; first_item = 0; old_current_item = current_item; old_first_item = first_item; // if (my_wnd->selected_gadget == this) { // my_wnd->selected_gadget == get_next(); // } return; } old_current_item = current_item; old_first_item = first_item; OnMe = is_mouse_on(); if (has_scrollbar) { if (scrollbar.moved) { first_item = scrollbar.position; Assert(first_item >= 0); if (current_item first_item + num_items_displayed - 1) current_item = first_item + num_items_displayed - 1; } } if (!B1_PRESSED) dragging = 0; if (B1_PRESSED && OnMe) { set_focus(); dragging = 1; } if ( key_buffer_count && (timer_get_milliseconds() > last_typed + KEY_BUFFER_TIMEOUT) ) key_buffer_count = 0; if (focus) { if (my_wnd->keypress) { kf = 0; switch (my_wnd->keypress) { case KEY_ENTER: selected_item = current_item; break; case KEY_SPACEBAR: toggled_item = current_item; break; case KEY_UP: current_item--; kf = 1; break; case KEY_DOWN: current_item++; kf = 1; break; case KEY_HOME: current_item = 0; kf = 1; break; case KEY_END: current_item=num_items - 1; kf = 1; break; case KEY_PAGEUP: current_item -= num_items_displayed; kf = 1; break; case KEY_PAGEDOWN: current_item += num_items_displayed; kf = 1; break; default: // enter the key in the key buffer if (my_wnd->keypress == KEY_BACKSP) { key_buffer_count = 0; } else if (key_buffer_count < MAX_KEY_BUFFER) { key_buffer[key_buffer_count++] = (char) my_wnd->keypress; last_typed = timer_get_milliseconds(); } if (!key_buffer_count) break; for (i=0; i= num_items) current_item = num_items - 1; if (current_item < first_item) first_item = current_item; if (current_item >= first_item + num_items_displayed) first_item = current_item - num_items_displayed + 1; if (num_items <= num_items_displayed ) { first_item = 0; } else { if (has_scrollbar) { scrollbar.position = first_item; scrollbar.bar_position = scrollbar.position - scrollbar.start; scrollbar.bar_position *= scrollbar.h - scrollbar.bar_size; scrollbar.bar_position /= scrollbar.stop - scrollbar.start; if (scrollbar.bar_position < 0) { scrollbar.bar_position = 0; } if (scrollbar.bar_position > scrollbar.h - scrollbar.bar_size) { scrollbar.bar_position = scrollbar.h - scrollbar.bar_size; } } } } } if (focus) { if (B1_PRESSED && dragging) { if (ui_mouse.y < y ) mitem = -1; else mitem = (ui_mouse.y - y)/textheight; if ( (mitem < 0) && (timer_get_milliseconds() > last_scrolled + 1000 / 18) ) { current_item--; last_scrolled = timer_get_milliseconds(); } if ( (mitem >= num_items_displayed) && (timer_get_milliseconds() > last_scrolled + 1000 / 18) ) { current_item++; last_scrolled = timer_get_milliseconds(); } if ((mitem >= 0) && (mitem= num_items) current_item = num_items - 1; if (current_item < first_item) first_item = current_item; if (current_item >= first_item + num_items_displayed) first_item = current_item - num_items_displayed + 1; if (num_items <= num_items_displayed) { first_item = 0; } else if (has_scrollbar) { scrollbar.position = first_item; scrollbar.bar_position = scrollbar.position - scrollbar.start; scrollbar.bar_position *= scrollbar.h - scrollbar.bar_size; scrollbar.bar_position /= scrollbar.stop - scrollbar.start; if (scrollbar.bar_position < 0) { scrollbar.bar_position = 0; } if (scrollbar.bar_position > scrollbar.h - scrollbar.bar_size) { scrollbar.bar_position = scrollbar.h - scrollbar.bar_size; } } } if (check_list) { if (B1_JUST_RELEASED) toggled_item = current_item; } if (B1_DOUBLE_CLICKED) { selected_item = current_item; } } } int UI_LISTBOX::toggled() { if (check_list) { return toggled_item; } else { return -1; } } int UI_LISTBOX::selected() { if (check_list) { return -1; } else { return selected_item; } } int UI_LISTBOX::current() { return current_item; } void UI_LISTBOX::set_current(int _index) { current_item = _index; } void UI_LISTBOX::set_first_item(int _index) { if (_index < 0) _index = 0; else if (_index > num_items) _index = num_items; first_item = _index; } char *UI_LISTBOX::get_string(int _index) { return list[_index]; } void UI_LISTBOX::clear_all_items() { int idx; for ( idx=0; idx num_items_displayed) first_item = num_items - num_items_displayed + 1; } void UI_LISTBOX::RemoveFirstItem() { for (int i = 0; i < num_items-1; i++) list[i] = list[i+1]; num_items--; } int UI_LISTBOX::MaxSize() { return max_items; } int UI_LISTBOX::CurSize() { return num_items; } int UI_LISTBOX::add_string(char *str) { if (max_items < 0) // only if we created an "empty" listbox can we add items return 0; else { if ( (num_items == max_items - 1) || (strlen(str) > DEFAULT_LISTBOX_ITEM_LENGTH) ) return 0; // we've reached our limit else { list[num_items] = vm_strdup(str); num_items++; return 1; } } } int UI_LISTBOX::sel_changed() { return old_current_item == current_item ? 0 : 1; }