📄 panel_text.c
字号:
return;}staticupdate_value_offset(ip, val_change, val_shift) panel_item_handle ip; int val_change; int val_shift;{ register text_data *dp = textdp(ip); int clip_len, full_len; struct pr_size size; int max_caret; int caret_offset = dp->caret_offset; full_len = strlen(dp->value); /* clip at the left if needed */ /* account for the left arrow if clipped */ if (full_len <= dp->display_length) { size = pf_textwidth(full_len, dp->font, dp->value); dp->first_char = 0; dp->last_char = full_len - 1; dp->value_offset = size.x; } else { clip_len = dp->display_length - 1; size = pf_textwidth(clip_len, dp->font, dp->value); max_caret = (dp->display_length - 1) * dp->font->pf_defaultsize.x; if (dp->font->pf_defaultsize.x >= panel_left_arrow_pr.pr_width) caret_offset += dp->font->pf_defaultsize.x - panel_left_arrow_pr.pr_width; caret_offset = caret_offset / dp->font->pf_defaultsize.x; caret_offset = caret_offset * dp->font->pf_defaultsize.x; /* Add a character */ if (val_change > 0) { /* Inserted characters will always be visible and the */ /* caret is always positioned after the inserted character, */ /* unless the caret is already positioned after the last */ /* displayable character, in which case all the characters */ /* to the left of the inserted character are shifted to the */ /* left on the display. */ if (caret_offset >= max_caret) { if (dp->first_char) dp->first_char++; else dp->first_char = 2; /* clip at left */ } } /* Delete 1 or more characters */ else if (val_change < 0) { if (dp->first_char > 2) dp->first_char += val_change; else dp->first_char = 0; /* no more clip at left */ } /* Shift the display */ else { dp->first_char += val_shift; /* Check for clipping at left */ if ((dp->first_char == 1) && (val_shift > 0)) dp->first_char++; if ((dp->first_char == 1) && (val_shift < 0)) dp->first_char--; } dp->last_char = dp->first_char + clip_len - 1; /* Check again for left clip */ if (dp->first_char <= 1) { dp->first_char = 0; dp->last_char = clip_len; } /* Check for right clip */ if (dp->last_char < (full_len - 1)) dp->last_char -= 1; /* Compute value offset, and include arrows if clipping either side */ dp->value_offset = size.x; if (dp->first_char) dp->value_offset += panel_left_arrow_pr.pr_width; if (dp->last_char < (full_len - 1)) dp->value_offset += panel_right_arrow_pr.pr_width; }}intupdate_caret_offset(ip, caret_shift) panel_item_handle ip; int caret_shift;/* * update_caret_offset computes the caret x offset for ip. */{ register text_data *dp = textdp(ip); int clip_len, full_len; struct pr_size size; int caret_offset = dp->caret_offset; /* no offset if masked completely */ full_len = strlen(dp->value); /* * Get old caret offset, in multiples of the font width. */ if (dp->font->pf_defaultsize.x >= panel_left_arrow_pr.pr_width) caret_offset += dp->font->pf_defaultsize.x - panel_left_arrow_pr.pr_width; caret_offset = caret_offset / dp->font->pf_defaultsize.x; caret_offset = caret_offset * dp->font->pf_defaultsize.x; /* * Compute new caret offset. */ dp->caret_offset = caret_offset + (caret_shift * dp->font->pf_defaultsize.x); /* Caret cannot cross left boundary of text field. */ if (dp->caret_offset < 0) dp->caret_offset = 0; /* If clipping at left, caret cannot cross left arrow */ if ((dp->caret_offset == 0) && (dp->first_char)) dp->caret_offset += panel_left_arrow_pr.pr_width; else { if ((dp->caret_offset != 0) && (dp->first_char)) dp->caret_offset += panel_left_arrow_pr.pr_width - dp->font->pf_defaultsize.x; } /* * Now use the newly computed caret offset, and do the same thing for the * right boundary. */ caret_offset = dp->caret_offset; if (dp->font->pf_defaultsize.x >= panel_left_arrow_pr.pr_width) caret_offset += dp->font->pf_defaultsize.x - panel_left_arrow_pr.pr_width; caret_offset = caret_offset / dp->font->pf_defaultsize.x; caret_offset = caret_offset * dp->font->pf_defaultsize.x; /* Caret cannot cross right boundary of text field. */ if (caret_offset > dp->display_length * dp->font->pf_defaultsize.x) dp->caret_offset -= dp->font->pf_defaultsize.x; /* If clipping at right, caret cannot cross right arrow */ else if ((caret_offset == dp->display_length * dp->font->pf_defaultsize.x) && (dp->last_char < full_len - 1)) dp->caret_offset -= dp->font->pf_defaultsize.x; /* * Caret cannot exceed value offset. This should be a "catch-all" safety * net, like when stored length < displayed length. */ if (dp->caret_offset > dp->value_offset) dp->caret_offset = dp->value_offset;}staticblink_value(ip) panel_item_handle ip;/* * blink_value blinks the value rect of ip. */{ int i; /* counter */ /* invert the value rect */ (void) panel_invert(ip->panel, &ip->value_rect); /* wait a while */ for (i = 1; i < 5000; i++); /* un-invert the value rect */ (void) panel_invert(ip->panel, &ip->value_rect);}/***********************************************************************//* caret routines *//***********************************************************************/staticdeselect(panel) panel_handle panel;{ panel_item_handle old_item = (panel_item_handle) panel->caret; text_data *old_dp; if (old_item != NULL) { old_dp = textdp(old_item); old_dp->flags &= ~HASCARET; paint_caret(old_item, PIX_CLR); }}static caddr_tpanel_getcaret(panel) panel_handle panel;{ return (caddr_t) panel->caret;}static caddr_tpanel_setcaret(panel, ip) panel_handle panel; panel_item_handle ip;{ text_data *dp = textdp(ip); if (ip == NULL || hidden(ip)) return NULL; deselect(panel); panel->caret = ip; if (panel_seln(panel, SELN_CARET)->ip) panel_seln(panel, SELN_CARET)->ip = ip; dp->flags |= HASCARET; paint_caret(ip, PIX_SET); return (caddr_t) ip;}Panel_itempanel_advance_caret(client_panel) Panel_item client_panel;{ panel_handle panel = PANEL_CAST(client_panel); panel_item_handle old_item; text_data *old_dp; old_item = panel->caret; if (!old_item) return (NULL); old_dp = textdp(old_item); (void) panel_setcaret(panel, old_dp->next); return (Panel_item) panel->caret;}Panel_itempanel_backup_caret(client_panel) Panel_item client_panel;{ panel_handle panel = PANEL_CAST(client_panel); register panel_item_handle old_ip; register panel_item_handle new_ip, pre_ip; old_ip = panel->caret; if (!old_ip) return (NULL); /* find previous item by going forward in linked list of text items... */ pre_ip = old_ip; new_ip = textdp(old_ip)->next; while (new_ip != old_ip) { pre_ip = new_ip; new_ip = textdp(new_ip)->next; } (void) panel_setcaret(panel, pre_ip); return (Panel_item) panel->caret;}static voidtext_caret_invert(panel) register panel_handle panel;/* * text_caret_invert inverts the type-in caret. */{ if (!panel->caret) return; paint_caret(panel->caret, panel->caret_on ? PIX_CLR : PIX_SET);} /* text_caret_invert */static voidtext_caret_on(panel, on) panel_handle panel; int on;/* * text_caret_on paints the type-in caret if on is true; otherwise xor's it. */{ if (!panel->caret) return; paint_caret(panel->caret, on ? PIX_SET : PIX_CLR);} /* text_caret_on *//***********************************************************************//* panel_text_notify *//***********************************************************************//* ARGSUSED */Panel_settingpanel_text_notify(client_item, event) Panel_item client_item; register Event *event;{ register panel_item_handle ip = PANEL_ITEM_CAST(client_item); register text_data *dp = textdp(ip); register short code; switch (event_action(event)) { case '\n': case '\r': case '\t': return (event_shift_is_down(event)) ? PANEL_PREVIOUS : PANEL_NEXT; /* always insert action editting characters */ case ACTION_ERASE_CHAR_BACKWARD: case ACTION_ERASE_CHAR_FORWARD: case ACTION_ERASE_WORD_BACKWARD: case ACTION_ERASE_WORD_FORWARD: case ACTION_ERASE_LINE_BACKWARD: case ACTION_ERASE_LINE_END: return (PANEL_INSERT); default: /* always insert user-specified editting characters */ if ((event_action(event) == dp->edit_bk_char) || (event_action(event) == dp->edit_bk_word) || (event_action(event) == dp->edit_bk_line)) return (PANEL_INSERT); if (event_is_iso(event)) return ((event_id(event) >= ISO_FIRST + 0xA0) ? PANEL_INSERT : PANEL_NONE); code = event_id(event); /* XXX should be event_action? */ return (code >= 0 && code <= 0xFF && isprint(code)) ? PANEL_INSERT : PANEL_NONE; }}/* * Hilite selection according to its rank. */voidpanel_seln_hilite(selection) register panel_selection_handle selection;{ register panel_item_handle ip = selection->ip; int caret_offset = textdp(ip)->caret_offset; register text_data *dp = textdp(ip); Rect rect; int first_dsc; /* first displayed, selected char */ int last_dsc; /* last displayed, selected char */ if (selection->is_null) return; if (selection->rank == SELN_PRIMARY && primary_ms_clicks == 0) return; if (selection->rank == SELN_SECONDARY && secondary_ms_clicks == 0) return; rect = ip->value_rect; /* bug 1028852 -- limit selection to currently displayed characters */ /* * Highlight all characters that are currently selected and currently * being displayed */ switch (selection->rank) { case SELN_PRIMARY: first_dsc = primary_seln_first; if (dp->first_char > first_dsc) first_dsc = dp->first_char; last_dsc = primary_seln_last; if (dp->last_char < last_dsc) last_dsc = dp->last_char; break; case SELN_SECONDARY: first_dsc = secondary_seln_first; if (dp->first_char > first_dsc) first_dsc = dp->first_char; last_dsc = secondary_seln_last; if (dp->last_char < last_dsc) last_dsc = dp->last_char; break; } rect.r_left += (first_dsc - dp->first_char) * dp->font->pf_defaultsize.x; if (dp->first_char > 0) rect.r_left += panel_left_arrow_pr.pr_width; rect.r_width = (last_dsc - first_dsc + 1) * dp->font->pf_defaultsize.x; if (rect.r_width < 0) rect.r_width = 0;#ifdef DEBUG printf("first_dsc=%2d, last_dsc=%2d, left=%d, width=%d\n", first_dsc, last_dsc, rect.r_left, rect.r_width);#endif /* DEBUG */ switch (selection->rank) { case SELN_PRIMARY: primary_seln_panel = ip->panel; /* save panel */ primary_seln_rect = rect; /* save rectangle coordinates */ if (primary_pending_delete) { panel_gray(ip->panel, &rect); primary_seln_highlight = HL_GRAY; } else { panel_invert(ip->panel, &rect); primary_seln_highlight = HL_INVERT; } break; case SELN_SECONDARY: secondary_seln_panel = ip->panel; /* save panel */ secondary_seln_rect = rect; /* save rectangle coordinates */ if (secondary_pending_delete) { panel_gray(ip->panel, &secondary_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -