📄 panel_text.c
字号:
/* editting characters are always ok to insert */ ok_to_insert = (panel_printable_char(code) || (code == dp->edit_bk_char) || (code == dp->edit_bk_word) || (code == dp->edit_bk_line) || (code == ACTION_ERASE_CHAR_BACKWARD) || (code == ACTION_ERASE_CHAR_FORWARD) || (code == ACTION_ERASE_WORD_BACKWARD) || (code == ACTION_ERASE_WORD_FORWARD) || (code == ACTION_ERASE_LINE_BACKWARD) || (code == ACTION_ERASE_LINE_END)); } if (dp->flags & READ_ONLY) ok_to_insert = FALSE; /* Process cursor key */ if (event_is_key_right(event)) { code = event_id(event); switch (event_id(event)) { case (UP_CURSOR_KEY): notify_rtn_code = PANEL_PREVIOUS; notify_desired = TRUE; ok_to_insert = FALSE; break; case (DOWN_CURSOR_KEY): notify_rtn_code = PANEL_NEXT; notify_desired = TRUE; ok_to_insert = FALSE; break; case (RIGHT_CURSOR_KEY): case (LEFT_CURSOR_KEY): notify_desired = FALSE; ok_to_insert = FALSE; break; default: break; } } /* turn off the caret */ caret_was_on = 0; if (ip->panel->caret_on && ip == panel->caret) { caret_was_on = 1; paint_caret(ip, PIX_CLR); } /* do something with the character */ /* use 'event_action(event)' and not 'code' because client may have */ /* changed the event */ update_value(ip, event_action(event), ok_to_insert); if (caret_was_on) paint_caret(ip, PIX_SET); if (notify_desired && ip == panel->caret) switch (notify_rtn_code) { case PANEL_NEXT: (void) panel_advance_caret((Panel) panel); break; case PANEL_PREVIOUS: (void) panel_backup_caret((Panel) panel); break; default: break; }}staticint panel_printable_char(code) int code; /* event code */{ /* * return( (code >= ' ' && code <= '~') || (code >= ISO_FIRST+0xA0 && * code <= ISO_FIRST+0xFF) ); */ return ((code >= 0 && code <= 0xFF && isprint(code)) || (code >= ISO_FIRST + 0xA0 && code <= ISO_FIRST + 0xFF));}/* * IMPORTANT: dp->caret_offset always points to the pixel offset of the caret * relative to the left boundary. It includes the left arrow if it exists, * so its value MAY NOT BE a multiple of dp->font->pf_defaultsize.x. * * In some routines, the local variable, caret_offset, is used for computations * & comparisons involving string lengths in pixel units, such as computing * the insertion point and new caret position. It treats the left and right * arrows as characters, whose width is identical to the font width. So its * value should ALWAYS be a multiple of dp->font->pf_defaultsize.x. * * In summary, the displayed text field width, in pixels, including the arrows, * may not always be a multiple of the font width. The text displayed is * always placed immediately after the left arrow, whose pixel width is * independent of the font width. * * The hilite/dehilite routines must also account for this. */staticupdate_value(ip, code, ok_to_insert) panel_item_handle ip; register int code; int ok_to_insert;/* * update_value updates the value of ip according to code. If code is an * edit character, the appropriate edit action is taken. Otherwise, if * ok_to_insert is true, code is appended to ip->value. */{ register text_data *dp = textdp(ip); register char *sp; /* string value */ int orig_len, new_len; /* before & after lengths */ register int i; /* counter */ register int x; /* left of insert/del point */ int was_clipped;/* TRUE if value was clipped */ int orig_offset;/* before caret offset */ int caret_shift = 0; /* number of positions to move caret */ int insert_pos; /* position for character add/delete */ int j; int val_shift = 0; /* number of positions to shift value * display */ int val_change = 0; /* number of positions to move value */ int pix_display_length; /* dp->display_length, in pixel units */ int char_code; int caret_offset; int saved_caret_offset; caret_offset = dp->caret_offset; /* Get the character position in question, relative of left boundary. */ if (caret_offset < 0) insert_pos = 0; else { if (dp->first_char) caret_offset += dp->font->pf_defaultsize.x - panel_left_arrow_pr.pr_width; insert_pos = caret_offset / dp->font->pf_defaultsize.x; } /* Get actual positional character within the string */ if (dp->first_char) insert_pos += dp->first_char - 1; sp = dp->value; orig_len = strlen(sp); if ((code == dp->edit_bk_char) || (code == ACTION_ERASE_CHAR_BACKWARD)) { /* backspace */ /* Allow notify_proc to override editting characters. */ /* Supports read-only text fields. */ if (!ok_to_insert) { blink_value(ip); goto END_OF_UPDATE_VALUE; } /* Nothing to backspace if caret is at left boundary. */ if (caret_offset == 0) goto END_OF_UPDATE_VALUE; /* Can't show result of backspace if display length exceeded and */ /* caret is to the right of the panel left arrow. The moral here */ /* is that you can't delete what you can't see. */ if ((orig_len > dp->display_length) && (dp->first_char) && (caret_offset <= dp->font->pf_defaultsize.x)) goto END_OF_UPDATE_VALUE; if ((*sp) && (insert_pos > 0)) { for (i = insert_pos; i < orig_len; i++) sp[i - 1] = sp[i]; sp[orig_len - 1] = '\0'; insert_pos--; caret_shift = -1; val_change = -1; /* If clipped at left boundary, leave caret alone. */ /* Characters will shift in from the left. */ if (dp->first_char > 1) caret_shift = 0; } } else if (code == ACTION_ERASE_CHAR_FORWARD) { /* forespace */ /* Allow notify_proc to override editting characters. */ /* Supports read-only text fields. */ if (!ok_to_insert) { blink_value(ip); goto END_OF_UPDATE_VALUE; } /* Can't show result of forespace if display length exceeded and */ /* caret is to the left of the panel right arrow. The moral here */ /* is that you can't delete what you can't see. */ pix_display_length = dp->display_length * dp->font->pf_defaultsize.x; if (caret_offset >= pix_display_length) goto END_OF_UPDATE_VALUE; pix_display_length = (dp->last_char - dp->first_char + 1); if (dp->first_char) pix_display_length++; pix_display_length *= dp->font->pf_defaultsize.x; if (caret_offset >= pix_display_length) goto END_OF_UPDATE_VALUE; if ((*sp) && (insert_pos >= 0)) { for (i = insert_pos; i < orig_len; i++) sp[i] = sp[i + 1]; sp[orig_len - 1] = '\0'; caret_shift = 0; val_change = 0; if ((dp->last_char >= (strlen(sp) - 1)) && (dp->last_char > 1)) { val_change = -1; if (dp->first_char > 2) caret_shift = 1; } } } else if ((code == dp->edit_bk_word) || (code == ACTION_ERASE_WORD_BACKWARD)) { /* backword */ /* * for(i = orig_len - 1; i >= 0 && sp[i] == ' '; i--); for(; i >= 0 * && sp[i] != ' '; i--); sp[i + 1] = '\0'; */ /* Allow notify_proc to override editting characters. */ /* Supports read-only text fields. */ if (!ok_to_insert) { blink_value(ip); goto END_OF_UPDATE_VALUE; } /* skip back past blanks */ if (insert_pos > orig_len) insert_pos -= (dp->first_char - 1); for (i = insert_pos - 1; (i >= 0) && (sp[i] == ' '); i--); for (; (i >= 0) && (sp[i] != ' '); i--); if (i < 0) i = 0; if (i > 0) i++; caret_shift = i - insert_pos; val_change = i - insert_pos; for (j = insert_pos; j <= orig_len; j++, i++) sp[i] = sp[j]; insert_pos += caret_shift; } else if (code == ACTION_ERASE_WORD_FORWARD) { /* foreword */ /* Allow notify_proc to override editting characters. */ /* Supports read-only text fields. */ if (!ok_to_insert) { blink_value(ip); goto END_OF_UPDATE_VALUE; } /* skip back past blanks */ for (i = insert_pos; (i < orig_len) && (sp[i] == ' '); i++); for (; (i < orig_len) && (sp[i] != ' '); i++); if (i >= orig_len) i = orig_len - 1; if (i < (orig_len - 1)) i--; caret_shift = 0; val_change = 0; for (j = insert_pos; i < orig_len; j++, i++) sp[j] = sp[i + 1]; if ((dp->last_char >= (strlen(sp) - 1)) && (dp->first_char > 1)) { val_change = strlen(sp) - 1 - dp->last_char; if (dp->last_char < (orig_len - 1)) val_change--; caret_shift = -val_change; } } else if ((code == dp->edit_bk_line) || (code == ACTION_ERASE_LINE_BACKWARD)) { /* backline */ /* Allow notify_proc to override editting characters. */ /* Supports read-only text fields. */ if (!ok_to_insert) { blink_value(ip); goto END_OF_UPDATE_VALUE; } /* sp[0] = '\0'; */ caret_shift = -insert_pos; val_change = -insert_pos; for (i = 0, j = insert_pos; j <= orig_len; i++, j++) sp[i] = sp[j]; insert_pos = 0; } else if (code == ACTION_ERASE_LINE_END) { /* foreline */ /* Allow notify_proc to override editting characters. */ /* Supports read-only text fields. */ if (!ok_to_insert) { blink_value(ip); goto END_OF_UPDATE_VALUE; } caret_shift = 0; val_change = 0; sp[insert_pos] = '\0'; if (dp->first_char > 1) { val_change = strlen(sp) - 1 - dp->last_char; if (dp->last_char < (orig_len - 1)) val_change--; caret_shift = -val_change; } } else if (code == RIGHT_CURSOR_KEY) { caret_shift = 1; if ((dp->last_char < (orig_len - 1)) && (caret_offset >= (dp->display_length - 1) * dp->font->pf_defaultsize.x)) val_shift = 1; /* display will include next char to right */ } else if (code == LEFT_CURSOR_KEY) { caret_shift = -1; if ((dp->first_char) && (caret_offset <= dp->font->pf_defaultsize.x)) val_shift = -1; /* display will include next char to left */ } else if (code == UP_CURSOR_KEY) { } /* do nothing */ else if (code == DOWN_CURSOR_KEY) { } /* do nothing */ else if (code == '\n') { } /* do nothing */ else if (code == '\r') { } /* do nothing */ else if (code == '\t') { } /* do nothing */ else { if (ok_to_insert) { /* insert */ if (orig_len < dp->stored_length) { /* there is room */ if (ISO_FIRST <= code && code <= ISO_LAST) char_code = code - ISO_FIRST; else char_code = code; for (i = orig_len; i > insert_pos; i--) sp[i] = sp[i - 1]; sp[insert_pos] = (char) char_code; sp[orig_len + 1] = '\0'; caret_shift = 1; val_change = 1; /* Don't shift caret if display length exceeded or the caret */ /* is positioned just before the last displayable character. */ if ((strlen(sp) > dp->display_length) && (caret_offset >= (dp->display_length - 1) * dp->font->pf_defaultsize.x)) caret_shift = 0; } else /* no more room */ blink_value(ip); } else /* must be read-only */ blink_value(ip); } /* determine the new caret offset */ was_clipped = (dp->first_char != 0) || (dp->last_char < (orig_len - 1)); orig_offset = dp->value_offset; update_value_offset(ip, val_change, val_shift); update_caret_offset(ip, caret_shift); /* update the display if not masked */ if (dp->mask != ' ') { /* compute the position of the caret */ x = ip->value_rect.r_left + dp->caret_offset; new_len = strlen(sp); /* erase deleted characters that were displayed */ if (new_len < orig_len) { /* repaint the whole value if needed */ if (was_clipped || dp->first_char || (dp->last_char < (new_len - 1))) paint_value(ip, PV_HIGHLIGHT); else { /* clear the deleted characters and everything to the right */ (void) panel_pw_writebackground(ip->panel, x, ip->value_rect.r_top, orig_offset - dp->caret_offset, ip->value_rect.r_height, PIX_CLR); if (dp->mask == '\0') (void) panel_pw_text(ip->panel, x, ip->value_rect.r_top + panel_fonthome(dp->font), PIX_SRC | PIX_COLOR(ip->color_index), dp->font, &sp[insert_pos]); else { /* masked */ char *buff; buff = (char *) sv_malloc(strlen(sp) + 1); for (i = 0; i < strlen(sp); i++) buff[i] = dp->mask; buff[strlen(sp)] = '\0'; (void) panel_pw_text(ip->panel, x, ip->value_rect.r_top + panel_fonthome(dp->font), PIX_SRC | PIX_COLOR(ip->color_index), dp->font, &buff[insert_pos]); free(buff); } } } else if (new_len > orig_len) { /* repaint the whole value if it doesn't fit */ if (new_len > dp->display_length) paint_value(ip, PV_HIGHLIGHT); else /* write the new character to the left of the caret */ if (dp->mask == '\0') /* not masked */ (void) panel_pw_text(ip->panel, x - dp->font->pf_defaultsize.x, ip->value_rect.r_top + panel_fonthome(dp->font), PIX_SRC | PIX_COLOR(ip->color_index), dp->font, &sp[insert_pos]); else { /* masked */ char *buff; buff = (char *) sv_malloc(strlen(sp) + 1); for (i = 0; i < strlen(sp); i++) buff[i] = dp->mask; buff[strlen(sp)] = '\0'; (void) panel_pw_text(ip->panel, x - dp->font->pf_defaultsize.x, ip->value_rect.r_top + panel_fonthome(dp->font), PIX_SRC | PIX_COLOR(ip->color_index), dp->font, &buff[insert_pos]); free(buff); } } else /* Cursor key causes display shift */ if (val_shift) paint_value(ip, PV_HIGHLIGHT); }END_OF_UPDATE_VALUE:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -