📄 bctextbox.c
字号:
#include "bctextbox.h"#include <ctype.h>BC_TextBox::BC_TextBox(int x, int y, int w, char *text, int has_border = 1) : BC_Tool(x, y, w, 25){ strcpy(this->text, text); this->has_border = has_border;}BC_TextBox::BC_TextBox(int x, int y, int w, int text, int has_border = 1) : BC_Tool(x, y, w, 25){ sprintf(this->text, "%d", text); this->has_border = has_border;}BC_TextBox::BC_TextBox(int x, int y, int w, float text, int has_border = 1) : BC_Tool(x, y, w, 25){ sprintf(this->text, "%f", text); this->has_border = has_border;}BC_TextBox::create_tool_objects(){ start = 0; if(has_border) { back_color = WHITE; high_color = LTYELLOW; h = get_text_height(top_level->largefont) + 8; } else { high_color = LTGREY; back_color = subwindow->color; h = get_text_height(top_level->largefont) + 2; } text_color = BLACK; text_ascent = get_text_ascent(top_level->largefont); selecttext = selectword = highlighted = 0; create_window(x, y, w, h, back_color); update(text);}BC_TextBox::resize_tool(int x, int y){ resize_window(x, y, w, h); update();}BC_TextBox::draw(){ update();}BC_TextBox::cursor_left_(){ if(top_level->active_tool != this && enabled) { if(cursor_x < 0 || cursor_x > w || cursor_y < 0 || cursor_y > h) { if(highlighted) { highlighted = 0; update(); return 0; } } }}BC_TextBox::button_press_(){ int result = 0; if(top_level->event_win != top_level->win) return 0; if(!enabled) return 0; if(cursor_x > 0 && cursor_y > 0 && cursor_x < w && cursor_y < h) {// cursor was inside boundaries if(top_level->double_click) { // double click selectword = 1; /* set center of selection */ center = x1 = x2 = charof(cursor_x + 2) + start; /* set word of selection */ while(isalnum(text[x1]) && x1 > 0) x1--; if(!isalnum(text[x1]) && x1 < center) x1++; while(isalnum(text[x2]) && x2 < strlen(text)) x2++; wordx1 = x1; wordx2 = x2; /* set original word selected */ } else { /* set center of selection */ center = x1 = x2 = start + charof(cursor_x + 2); selecttext = 1; /* select on */ } if(top_level->active_tool != this) { // deactivate active textbox activate(); result = 1; } else update(); } else { // cursor was outside boundary if(top_level->active_tool == this) { deactivate(); } } return result;}BC_TextBox::cursor_motion_(){ if(selecttext || selectword) { /* decide which side to extend */ x1_ = x1; x2_ = x2; if(cursor_x < 0 && start > 0) { center_ = --start; } else if(cursor_x > w && x2 < strlen(text)) { center_ = charof(w) + start; start++; } else { center_ = charof(cursor_x) + start; } if(center_ < center){ if(selectword){ while(center_ > 0 && isalnum(text[center_])) center_--; if(center_ < x2 && !isalnum(text[center_])) center_++; x1 = center_; x2 = wordx2; /* reset right side */ }else{ x1 = center_; /* extend left side */ x2 = center; /* reset right side */ } } else if(center_ >= center){ if(selectword){ /* extend right word */ static int len; len = strlen(text); while(center_ < len && isalnum(text[center_])) center_++; x2 = center_; x1 = wordx1; } else { x2 = center_; /* extend right side */ x1 = center; /* reset right side */ } } if(x1_ != x1 || x2_ != x2) update(); } else { if(top_level->event_win != top_level->win) return 0; if(!enabled) return 0; if(top_level->button_down) return 0; if(highlighted) { if(cursor_x < 0 || cursor_x > w || cursor_y < 0 || cursor_y > h) { if(top_level->active_tool != this) { highlighted = 0; update(); return 0; } } } else { if(cursor_x > 0 && cursor_x < w && cursor_y > 0 && cursor_y < h) { highlighted = 1; update(); return 0; } } }}BC_TextBox::button_release_(){ if(selecttext || selectword) { selecttext = 0; selectword = 0;// need to update everything in window top_level->button_just_released++; top_level->button_down = 0; }}BC_TextBox::keypress_event_(){ int result, i; if(top_level->active_tool != this) return 0; if(!enabled) return 0; switch(top_level->key_pressed) { case 13: deactivate(); result = 2; break; case ESC: deactivate(); break; case TAB: top_level->cycle_textboxes(); break; case LEFT: if(!top_level->shift_down() && x1 < x2) x2 = x1; if(top_level->shift_down()) { if(x1 == x2) { if(x1 > 0) x1--; center = 0; } else if(center) { if(x2 > x1) x2--; else if(x1 > 0){ x1--; center = 0; } } else if(x1 > 0) x1--; } else { if(x1 > 0){ x1--; x2--; } } if(x1 < start) start = x1; update(); break; case RIGHT: if(!top_level->shift_down() && x1 < x2) x1 = x2; if(top_level->shift_down()) { if(x1 == x2) { if(x2 < strlen(text)){ x2++; center = 1; } } else if(center) { if(x2 < strlen(text)) x2++; } else if(x1 < x2) x1++; else if(x2 < strlen(text)){ x2++; center = 1; } } else { if(x2 < strlen(text)){ x2++; x1++; } } while(XTextWidth(top_level->largefont, &text[start], x2 - start) + 2 > w - 2) start++; update(); break; case BACKSPACE: if(x1 == x2){ /* single character */ if(x1 > 0){ for(i = x1 - 1; i < strlen(text); i++){ text[i] = text[i+1]; } x1--; x2--; if(start) start--; /* scroll left if extended */ } }else{ /* multiple characters */ for(i = x1; x2 < strlen(text); i++, x2++){ text[i] = text[x2]; } text[i] = 0; x2 = x1; } if(x2 < start) start = x2; update(); result = 2; break; default: if(top_level->get_keypress() > 30 && top_level->get_keypress() < 127) { if(x1 == x2){ /* insert */ for(i = strlen(text) + 1; i > x1; i--){ text[i] = text[i - 1]; } }else{ /* replace */ for(i = x1+1; x2 <= strlen(text);) { text[i++] = text[x2++]; } x2 = x1; } text[x1] = top_level->get_keypress(); x1++; x2++; /* fit text into window */ while(XTextWidth(top_level->largefont, &text[start], x2 - start) + 2 > w - 8) start++; update(); result = 2; } break; } if(result == 2) handle_event(); top_level->key_pressed = 0; // trap key return result;}// return char position in string of pixel xBC_TextBox::charof(int x_){ int len = strlen(&text[start]); x_ -= 5; for(; len > 0 && XTextWidth(top_level->largefont, &text[start], len) > x_; len--) ; return len;}char* BC_TextBox::get_text(){ return text;}BC_TextBox::update(char *text_){ strcpy(text, text_); int len; // length of string to print start = 0; len = strlen(&text[start]); // cut length until it fits in box while(XTextWidth(top_level->largefont, &text[start], len) > w - 8) { len--; start++; } update(); deactivate();}BC_TextBox::update(int value){ sprintf(text, "%d", value); int len; // length of string to print start = 0; len = strlen(&text[start]); // cut length until it fits in box while(XTextWidth(top_level->largefont, &text[start], len) > w - 8) { len--; start++; } update(); deactivate();}BC_TextBox::update(){ static int column1, column2; // columns for highlight box static int len; // length of string to print static int distance_from_edge, distance_from_top; if(has_border) { distance_from_edge = 4; distance_from_top = h - 7; } else { distance_from_edge = 2; distance_from_top = text_ascent; } if(has_border) { if(highlighted) { draw_3d_big(0, 0, w, h, RED, WHITE, LTPINK); } else { draw_3d_big(0, 0, w, h, DKGREY, WHITE, LTGREY); } } else { if(highlighted) { set_color(high_color); draw_box(0, 0, w, h); } else { set_color(back_color); draw_box(0, 0, w, h); } } // draw text without cursor len = strlen(&text[start]); // cut length until it fits in box while(XTextWidth(top_level->largefont, &text[start], len) > w - distance_from_edge * 2){ len--; } subwindow->set_color(text_color); XDrawString(top_level->display, pixmap, top_level->gc, distance_from_edge, distance_from_top, &text[start], len); if(top_level->active_tool == this) {// draw selection if(start <= x1) { // x1 after start column1 = XTextWidth(top_level->largefont, &text[start], x1 - start) + distance_from_edge; } else { // x1 before view column1 = -1; } if(x2 >= start) { // x2 after start column2 = XTextWidth(top_level->largefont, &text[start], x2 - start) + distance_from_edge; } else { column2 = -1; // x2 before view } if(column1 < w - 2 && column2 >= 2) { // selection in view if(column1 < distance_from_edge) column1 = distance_from_edge; // x1 before view if(column2 >= w - distance_from_edge) column2 = w - distance_from_edge - 1; // x2 after view set_inverse(); set_color(back_color); // set inverse column2++; // add one for single cursor if(has_border) draw_box(column1, 3, column2 - column1, h - 6); else draw_box(column1, 1, column2 - column1, h - 2); set_opaque(); } set_opaque(); } flash();}BC_TextBox::activate_(){ if(x1 == -1) { //x1 = 0; //x2 = strlen(text); // set cursor selection for entire string //selecttext = 0; //selectword = 0; x2 = x1 = 0; } highlighted = 1; update();}BC_TextBox::deactivate(){ if(top_level->active_tool == this) { selecttext = 0; // draw a text box with no cursor selectword = 0; x1 = x2 = -1; top_level->active_tool = 0; highlighted = 0; update(); }}BC_TextBox::uses_text(){ // set to 1 if tool uses text input return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -