📄 bclistbox.c
字号:
#include "bclistbox.h"// ======================================= scrollbarsBC_ListBoxYScroll::BC_ListBoxYScroll(BC_ListBox *listbox, int totallines, int position) : BC_YScrollBar(listbox->x + listbox->w, listbox->y, 17, listbox->h, totallines, position, listbox->h / listbox->itemheight){ this->listbox = listbox;}BC_ListBoxYScroll::handle_event(){ if(listbox->yposition != get_position()) { listbox->yposition = get_position(); // get new position listbox->draw(); // redraw }}BC_ListBoxXScroll::BC_ListBoxXScroll(BC_ListBox *listbox, int totalcolumns, int position) : BC_XScrollBar(listbox->x, listbox->y + listbox->h, listbox->w, 17, totalcolumns, position, listbox->w){ this->listbox = listbox;}BC_ListBoxXScroll::handle_event(){ if(listbox->xposition != get_position()) { listbox->xposition = get_position(); // get new position listbox->draw(); // redraw }}// ====================================================== boxBC_ListBox::BC_ListBox(int x, int y, int w, int h, char **data, int totallines, int yposition, int currentitem) : BC_Tool(x, y, w-17, h){ this->data = data; this->totallines = totallines; this->yposition = yposition; this->currentitem = currentitem; xposition = 0; buttondown = 0; highlighted = -1; reset_query(); // reset the search engine deactivates_highlight = 1;}BC_ListBox::~BC_ListBox(){//printf("BC_ListBox::~BC_ListBox 1\n"); delete xscrollbar; delete yscrollbar;//printf("BC_ListBox::~BC_ListBox 2\n");}BC_ListBox::create_tool_objects(){ itemheight = get_text_height(LARGEFONT); text_descent = get_text_descent(LARGEFONT); create_window(x, y, w, h, WHITE); // create the list display// create the scrollbars subwindow->add_tool(yscrollbar = new BC_ListBoxYScroll(this, totallines, yposition)); subwindow->add_tool(xscrollbar = new BC_ListBoxXScroll(this, get_total_columns(), xposition));// draw the initial list draw();}BC_ListBox::resize(int w, int h){// just redraw draw();}BC_ListBox::get_total_columns(){ int test_w = 0, total_w = 0; for(int i = 0; i < totallines; i++) { if((test_w = get_text_width(LARGEFONT, data[i])) > total_w) total_w = test_w; } return total_w + 20;}BC_ListBox::draw(){ int item, item_y, item_x; // clear background draw_3d_big(0, 0, w, h, DKGREY, WHITE, LTGREY); item_x = 5 - xposition; // draw items set_color(BLACK); for(item = yposition, item_y = itemheight + text_descent - 1; item < totallines && item < yposition + yscrollbar->handlelength; item++, item_y += itemheight) { // highlight selected item if(item == currentitem) { set_inverse(); set_color(WHITE); // clip bottom item to window if(item_y > h - 2) draw_box(2, item_y - itemheight - 2, w - 4, itemheight-2); else draw_box(2, item_y - itemheight, w - 4, itemheight); if(item < totallines) draw_text(item_x, item_y - text_descent, data[item]); set_opaque(); set_color(BLACK); } else // highlight item cursor is over if(item == highlighted) { set_color(LTGREY); // clip bottom item to window if(item_y > h - 2) draw_box(2, item_y - itemheight - 2, w - 2, itemheight-2); else draw_box(2, item_y - itemheight, w - 2, itemheight); set_color(BLACK); if(item < totallines) draw_text(item_x, item_y - text_descent, data[item]); } else { if(item < totallines) draw_text(item_x, item_y - text_descent, data[item]); } }// flash just the box flash();}BC_ListBox::set_size(int x, int y, int w, int h){ resize_window(x, y, w, h); xscrollbar->set_size(x + w, y, 17, h); yscrollbar->set_size(x, y + h, w, 17); draw();}BC_ListBox::set_contents(char **data, // new data pointer int totallines, // total data items int yposition = 0, // top line in window int currentitem = -1) // current selected item{ this->data = data; this->totallines = totallines; this->yposition = yposition; this->currentitem = currentitem;// rescale scrollbars yscrollbar->set_position(totallines, yposition, h / itemheight); xscrollbar->set_position(get_total_columns(), xposition, w); draw();}BC_ListBox::stay_highlighted(){ deactivates_highlight = 0;}BC_ListBox::deactivate(){ top_level->active_tool = 0; if(deactivates_highlight) set_selection(-1);}BC_ListBox::resize(int x, int y, int w, int h, char **data, int totallines, int position, int currentitem){ resize_window(x, y, w, h); this->data = data; this->totallines = totallines; this->yposition = yposition; this->currentitem = currentitem; yscrollbar->resize(x + w, y, 17, h, totallines, yposition, h / itemheight); xscrollbar->resize(x, y + h, w, 17, get_total_columns(), xposition, w); draw();}BC_ListBox::set_selection(int selection){ currentitem = selection; draw();}BC_ListBox::set_current_item(int currentitem){ this->currentitem = currentitem; // make sure current is in the visible selection if(currentitem > yposition + h / itemheight - 1) { yposition = currentitem - h / itemheight + 5; } if(currentitem < yposition) { yposition = currentitem; } yscrollbar->set_position(totallines, yposition, h / itemheight); draw();}BC_ListBox::get_selection(char *string){ if(currentitem != -1 && currentitem < totallines && totallines > 0) { strcpy(string, data[currentitem]); } else { sprintf(string, ""); }}char* BC_ListBox::get_selection(){ if(currentitem != -1) return data[currentitem]; else return "";}BC_ListBox::get_selection_number(){ return currentitem;}BC_ListBox::query_list(){ query_list(query);}BC_ListBox::query_list(char *regexp){ if(query[0] == 0) currentitem = 0; for(int i = 0; i < totallines; i++) { if(strcmp(regexp, data[i]) > 0) { currentitem = i + 1; } } if(currentitem > totallines - 1) currentitem = totallines - 1;// don't set to item 0 if(currentitem > 0) set_current_item(currentitem);}BC_ListBox::reset_query(){ query[0] = 0; // reset query query_x = 0; // don't redraw list here}BC_ListBox::set_query(char *new_query){ strcpy(query, new_query); query_list(query);}BC_ListBox::motion_update(){ set_current_item(currentitem); reset_query();}BC_ListBox::cursor_left_(){ if(highlighted != -1) { highlighted = -1; draw(); }}BC_ListBox::keypress_event_(){ if(top_level->active_tool != this) return 0; result = 0; redraw = 0; switch(top_level->get_keypress()) { case UP: if(currentitem > 0 && currentitem < totallines) currentitem--; else currentitem = 0; motion_update(); result = 1; // new item break; case DOWN: if(currentitem < totallines - 1 && currentitem >= 0) currentitem++; else currentitem = totallines - 1; motion_update(); result = 1; // new item break; case PGUP: currentitem -= h / itemheight; if(currentitem > totallines - 1) currentitem = totallines - 1; if(currentitem < 0) currentitem = 0; motion_update(); result = 1; // new item break; case PGDN: currentitem += h / itemheight; if(currentitem > totallines - 1) currentitem = totallines - 1; if(currentitem < 0) currentitem = 0; motion_update(); result = 1; // new item break; case 13: reset_query(); result = 2; break; case ESC: result = 2; break; default: // perform query if(top_level->get_keypress() > 30 && top_level->get_keypress() < 127) { query[query_x++] = top_level->get_keypress(); query[query_x] = 0; query_list(); } else if(top_level->get_keypress() == BACKSPACE) { if(query_x > 0) query[--query_x] = 0; query_list(); } redraw = 1; result = 1; // new item break; } top_level->key_pressed = 0; // trap key if(redraw) draw(); if(result == 2) handle_event(); // item selected if(result == 1) selection_changed(); // new item selected return 0;}BC_ListBox::button_press_(){ if(top_level->event_win != top_level->win) return 0; if(cursor_x > 0 && cursor_x < w && cursor_y > 0 && cursor_y < h) { // click inside box selects item result = 0; redraw = 0; int item, item_y, olditem; activate(); olditem = currentitem; for(item = yposition, item_y = itemheight + 2; item < yposition + yscrollbar->handlelength; item++, item_y += itemheight) { if(cursor_x > 2 && cursor_x < w && cursor_y > item_y - itemheight && cursor_y < item_y) { currentitem = item; item = yposition + yscrollbar->handlelength; } } if(currentitem > totallines-1) currentitem = totallines-1; if(olditem != currentitem) { result = redraw = 1; }// double click on an item if(top_level->double_click && olditem == currentitem) { reset_query(); result = 2; } // set the button down status buttondown = 1; if(redraw) draw(); if(result == 2) { handle_event(); // item selected } if(result == 1) selection_changed(); // new item selected return 0; } else if(top_level->active_tool == this) { deactivate(); }}BC_ListBox::button_release_(){ buttondown = 0;}BC_ListBox::cursor_motion_(){ result = 0; redraw = 0;//printf("%x %x\n", top_level->event_win, win); //if(top_level->event_win != win) return 0; if(!buttondown && cursor_x > 0 && cursor_x < w && cursor_y > 0 && cursor_y < h) { // cursor inside box and button is up int item, item_y, oldhighlight; oldhighlight = highlighted; highlighted = -1; for(item = yposition, item_y = itemheight + 2; item < yposition + yscrollbar->handlelength; item++, item_y += itemheight) {// get item cursor is over if(cursor_x > 2 && cursor_x < w - 16 && cursor_y > item_y - itemheight && cursor_y < item_y) { highlighted = item; item = yposition + yscrollbar->handlelength; } }// cursor is beyond end of list if(highlighted >= totallines) highlighted = -1;// cursor moved over new item if(oldhighlight != highlighted) { redraw = 1; } } else // cursor moved outside box when an item was still highlighted if(highlighted != -1) { if(buttondown || cursor_x < 0 || cursor_x > w || cursor_y < 0 || cursor_y > h) { highlighted = -1; redraw = 1; } } if(buttondown) {// button is down and cursor is in listbox if(cursor_x > 0 && cursor_x < w && cursor_y > 0 && cursor_y < h) { // click inside box int item, item_y, olditem; olditem = currentitem; for(item = yposition, item_y = itemheight + 2; item < yposition + yscrollbar->handlelength; item++, item_y += itemheight) {// get new item selected if(cursor_x > 2 && cursor_x < w - 16 && cursor_y > item_y - itemheight && cursor_y < item_y) { currentitem = item; item = yposition + yscrollbar->handlelength; } }// current selection is beyond end of list if(currentitem >= totallines) currentitem = totallines-1; if(olditem != currentitem) { redraw = 1; result = 1; // new item } } else {// cursor outside box so test boundaries for scrolling if(cursor_y < 0) { int olditem = currentitem, oldposition = yposition;// scroll window if(yposition > 0) { yposition--; } // change item selected if(currentitem > 0) { currentitem--; } if(yposition != oldposition || olditem != currentitem) { yscrollbar->set_position(totallines, yposition, h / itemheight); redraw = 1; result = 1; // new item } } else if(cursor_y > h) {// scroll down int olditem = currentitem, oldposition = yposition;// scroll window if(yposition < totallines - yscrollbar->handlelength) { yposition++; }// change item selected if(currentitem < totallines-1) { currentitem++; } if(yposition != oldposition || olditem != currentitem) { yscrollbar->set_position(totallines, yposition, h / itemheight); redraw = 1; result = 1; // new item } } int total_w = get_total_columns(); int oldxposition = xposition; if(cursor_x < 0 && xposition > 0) { if(xposition < -cursor_x) xposition -= xposition; else xposition -= -cursor_x; if(xposition != oldxposition) { xscrollbar->set_position(get_total_columns(), xposition, w); redraw = 1; } } else if(cursor_x > w && xposition < total_w - w) { if(xposition + cursor_x - w > total_w - w) xposition = total_w - w; else xposition += cursor_x - w; if(xposition != oldxposition) { xscrollbar->set_position(get_total_columns(), xposition, w); redraw = 1; } } } } if(redraw) draw(); if(result == 2) handle_event(); // item selected if(result == 1) selection_changed(); // new item selected return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -