📄 panel_text.c
字号:
/* find next non_hidden text item following ip in the circular list */ /* of caret items (could be ip itself ) */ next_item = ip; do { next_item = panel_successor(next_item); /* find next unhidden item */ if (!next_item) next_item = ip->panel->items; /* wrap to start of list */ } while ((next_item->item_type != PANEL_TEXT_ITEM) || hidden(next_item)); /* now find the previous text item of next_item in the caret list */ prev_item = next_item; prev_dp = textdp(prev_item); /* if next_item is different from ip, then find the previous item */ if (next_item != ip) while (prev_dp->next != next_item) { prev_item = prev_dp->next; prev_dp = textdp(prev_item); } /* prev_item now points to the (circular) */ /* predecessor of ip; if ip is sole text item, */ /* prev_item == next_item == ip. */ /* link ip into the caret list */ dp = textdp(ip); dp->next = next_item; prev_dp->next = ip; /* deselect the previous caret item */ deselect(ip->panel); /* give the caret to this item */ ip->panel->caret = ip; dp->flags |= HASCARET; /* if we have the caret selection, change the item */ if (panel_seln(ip->panel, SELN_CARET)->ip) panel_seln(ip->panel, SELN_CARET)->ip = ip; /* note that the caret will be drawn when the item is painted */ return (Panel_item) ip;}/***********************************************************************//* insert *//***********************************************************************/staticinsert(ip) register panel_item_handle ip;/* * insert inserts ip into the caret list for ip->panel. */{ register panel_item_handle head; register text_data *dp; /* READ_ONLY text can accept caret to allow scrolling */#ifdef OBSOLETE if (textdp(ip)->flags & READ_ONLY) return NULL;#endif head = ip->panel->caret; if (head == NULL) { ip->panel->caret = ip; dp = textdp(ip); dp->flags |= HASCARET; head = ip; } else { /* find the last caret item */ for (dp = textdp(head); dp->next != head; dp = textdp(dp->next)); /* link after the last */ dp->next = ip; } /* point back to the head of the list */ dp = textdp(ip); dp->next = head;}/***********************************************************************//* destroy *//***********************************************************************/staticdestroy(dp) register text_data *dp;{ free(dp->value); free(dp->terminators); free((char *) dp);}/***********************************************************************//* paint *//***********************************************************************/staticpaint(ip) register panel_item_handle ip;{ (void) panel_paint_image(ip->panel, &ip->label, &ip->label_rect, PIX_COLOR(ip->color_index)); paint_text(ip);}/***********************************************************************//* paint_text *//***********************************************************************/staticpaint_text(ip) panel_item_handle ip;{ register text_data *dp = textdp(ip); /* compute the caret position */ update_value_offset(ip, 0, 0); update_caret_offset(ip, 0); /* don't paint the text if masked */ if (dp->mask != ' ') paint_value(ip, PV_HIGHLIGHT);}static voidpaint_value(ip, highlight) register panel_item_handle ip; u_char highlight;/* * paint_value clears the value rect for ip and paints the string value * clipped to the left of the rect. */{ register text_data *dp = textdp(ip); register panel_handle panel = ip->panel; register int x = ip->value_rect.r_left; register int y = ip->value_rect.r_top; register Rect *r; int i, j, len; char *str; /* Get the actual characters which will be displayed */ len = dp->last_char - dp->first_char + 2; str = (char *) sv_malloc(len); for (j = 0, i = dp->first_char; i <= dp->last_char; i++, j++) str[j] = dp->value[i]; str[len - 1] = '\0'; /* * clear the value rect. Actually, clear an area slightly larger than the * value rect to prevent remnants of arrows being left on the screen */ r = &ip->value_rect; (void) panel_pw_writebackground(panel, r->r_left, r->r_top, r->r_width + (dp->font->pf_defaultsize.x / 2), r->r_height, PIX_CLR); /* draw the left clip arrow if needed */ if (dp->first_char) { /* center the arrow vertically in the value rect */ (void) panel_pw_write(panel, x, y + (ip->value_rect.r_height - panel_left_arrow_pr.pr_height) / 2, panel_left_arrow_pr.pr_width, panel_left_arrow_pr.pr_height, PIX_SRC | PIX_COLOR(ip->color_index), &panel_left_arrow_pr, 0, 0); x += panel_left_arrow_pr.pr_width; } /* draw the text */ if (dp->mask == '\0') /* not masked */ (void) panel_pw_text(panel, x, y + panel_fonthome(dp->font), PIX_SRC | PIX_COLOR(ip->color_index), dp->font, &str[0]); else { /* masked */ char *buf; int length, i; length = dp->last_char - dp->first_char + 2; buf = (char *) sv_malloc(length); for (j = 0, i = dp->first_char; i <= dp->last_char; i++, j++) buf[j] = dp->mask; buf[length - 1] = '\0'; (void) panel_pw_text(panel, x, y + panel_fonthome(dp->font), PIX_SRC | PIX_COLOR(ip->color_index), dp->font, buf); free(buf); } /* draw the right clip arrow if needed */ if (dp->last_char < (strlen(dp->value) - 1)) { x += (strlen(str) * dp->font->pf_defaultsize.x); x += panel_right_arrow_pr.pr_width / 2; /* center the arrow vertically in the value rect */ (void) panel_pw_write(panel, x, y + (ip->value_rect.r_height - panel_right_arrow_pr.pr_height) / 2, panel_right_arrow_pr.pr_width, panel_right_arrow_pr.pr_height, PIX_SRC | PIX_COLOR(ip->color_index), &panel_right_arrow_pr, 0, 0); } free(str); if (highlight) { /* re-hilite if this is a selection item */ if (ip == panel_seln(panel, SELN_PRIMARY)->ip && !panel_seln(panel, SELN_PRIMARY)->is_null) panel_seln_hilite(panel_seln(panel, SELN_PRIMARY)); if (ip == panel_seln(panel, SELN_SECONDARY)->ip && !panel_seln(panel, SELN_SECONDARY)->is_null) panel_seln_hilite(panel_seln(panel, SELN_SECONDARY)); }}/***********************************************************************//* paint_caret *//***********************************************************************/staticpaint_caret(ip, op) panel_item_handle ip; int op;{ register panel_handle panel = ip->panel; register text_data *dp = textdp(ip); register int x, max_x; int painted_caret_offset; if (((op == PIX_SET && panel->caret_on) || (op == PIX_CLR && !panel->caret_on))) return; panel->caret_on = panel->caret_on ? FALSE : TRUE; op = PIX_SRC ^ PIX_DST; /* paint the caret after the offset & above descender */ painted_caret_offset = (dp->mask == ' ') ? 0 : dp->caret_offset; x = ip->value_rect.r_left + painted_caret_offset - dp->font->pf_defaultsize.x / 2; max_x = view_width(panel) + panel->h_offset; (void) panel_pw_write(panel, (x > max_x - 7) ? (max_x - 3) : x, ip->value_rect.r_top + dp->font->pf_defaultsize.y - 4, 7, 7, op, panel->caret_pr, 0, 0);}/***********************************************************************//* ops vector routines *//***********************************************************************//* ARGSUSED */staticbegin_preview(ip, event) register panel_item_handle ip; Event *event;{ text_data *dp = textdp(ip); register panel_handle panel = ip->panel; Seln_holder holder; Panel_setting current_state; u_int is_null; int ptr_offset; /* mouse pointer offset */ int caret_offset; u_char adjust_right; u_char pending_delete; int first_offset; int last_offset; current_state = (Panel_setting) panel_get(ip, PANEL_MOUSE_STATE); /* * Ignore the middle mouse button when the mouse is dragged into an item * not containing the caret. */ if (panel->caret != ip && current_state == PANEL_MIDDLE_DOWN && event_id(event) == LOC_DRAG) return; holder = panel_seln_inquire(panel, SELN_UNSPECIFIED); if (holder.rank == SELN_PRIMARY) { if (ip != panel_seln(panel, SELN_PRIMARY)->ip) primary_ms_clicks = 0; ms_clicks = primary_ms_clicks; } else { /* secondary selection */ if (ip != panel_seln(panel, SELN_SECONDARY)->ip) secondary_ms_clicks = 0; ms_clicks = secondary_ms_clicks; } /* * If nothing is selected in this item, then allow the middle button * to pick (i.e., make it look like the left button was clicked). */ pending_delete = FALSE; if (event_id(event) == MS_MIDDLE && ms_clicks == 0) { event->ie_code = MS_LEFT; /* READ_ONLY text can never be deleted */ if (!(dp->flags & READ_ONLY)) { /* need to check this since this is actually a middle button */ pending_delete = adjust_is_pending_delete(panel) ? TRUE : FALSE; /* * bug 1028689 -- added support for control char toggling of * select vs pending delete */ if (event_ctrl_is_down(event)) pending_delete = !pending_delete; } } ptr_offset = event->ie_locx - ip->value_rect.r_left + 1; if (ptr_offset < 0) /* yes, this can happen */ ptr_offset = 0; if ((event_id(event) == MS_LEFT) || ((event_id(event) == LOC_DRAG) && (current_state == PANEL_LEFT_DOWN))) { /* * This is a mouse left click event. */ /* READ_ONLY text can never be deleted */ if (!(dp->flags & READ_ONLY)) { /* * bug 1028689 -- added support for control char toggling of * select vs pending delete */ if (event_ctrl_is_down(event)) pending_delete = !pending_delete; } /* * Set seln_first and seln_last to the character pointed to by the mouse. */ /* * bug 1028685 -- pointer anywhere on character now selects that * character */ dp->seln_first = ptr_offset / dp->font->pf_defaultsize.x; if (dp->last_char < (strlen(dp->value) - 1)) /* right arrow showing */ if (dp->seln_first >= dp->display_length-1) dp->seln_first = dp->display_length - 2; if (dp->first_char) { /* left arrow showing */ dp->seln_first += dp->first_char - 1; if (dp->seln_first < dp->first_char) dp->seln_first = dp->first_char; } if (dp->seln_first >= strlen(dp->value)) if ((dp->seln_first = strlen(dp->value) - 1) < 0) dp->seln_first = 0; dp->seln_last = dp->seln_first; if (event_id(event) == MS_LEFT) { /* * If this is a quick click then increment clicks * otherwise reset clicks to 1. */ if (panel_dclick_is(&event_time(event))) ms_clicks++; else ms_clicks = 1; } if (ms_clicks == 2) /* select word */ panel_find_word(dp, &dp->seln_first, &dp->seln_last); else if (ms_clicks >= 3) { /* select line */ dp->seln_first = 0; dp->seln_last = strlen(dp->value) - 1; } } else if (ms_clicks > 0 && ((event_id(event) == MS_MIDDLE) || ((event_id(event) == LOC_DRAG) && (current_state == PANEL_MIDDLE_DOWN)))) { /* READ_ONLY text can never be deleted */ if (!(dp->flags & READ_ONLY)) { pending_delete = adjust_is_pending_delete(panel) ? TRUE : FALSE; /* * bug 1028689 -- added support for control char toggling of * select vs pending delete */ if (event_ctrl_is_down(event)) pending_delete = !pending_delete; } /* * bug 1028685 -- pointer anywhere on character now selects that * character */ dp->ext_first = ptr_offset / dp->font->pf_defaultsize.x; if (dp->last_char < strlen(dp->value) - 1) /* right arrow showing */ if (dp->ext_first >= dp->display_length-1) dp->ext_first = dp->display_length - 2; if (dp->first_char) { /* left arrow showing */ dp->ext_first += dp->first_char - 1; if (dp->ext_first < dp->first_char) dp->ext_first = dp->first_char; } if (dp->ext_first >= strlen(dp->value)) if ((dp->ext_first = strlen(dp->value) - 1) < 0) dp->ext_first = 0; dp->ext_last = dp->ext_first; if (ms_clicks >= 3) { dp->seln_first = 0; dp->seln_last = strlen(dp->value) - 1; } else { if (ms_clicks == 2) /* word adjust */ panel_find_word(dp, &dp->ext_first, &dp->ext_last); /* Adjust first or last character selected */ if (dp->ext_last > dp->seln_last) adjust_right = TRUE; else if (dp->ext_first < dp->seln_first) adjust_right = FALSE; /* adjust left */ else if ((dp->ext_first - dp->seln_first) < (dp->seln_last - dp->ext_first)) adjust_right = FALSE; /* adjust left */ else adjust_right = TRUE; if (adjust_right) dp->seln_last = dp->ext_last; else /* adjust left */ dp->seln_first = dp->ext_first; } } /* * Calculate caret offset * If setting or adjusting the primary selection: * Make sure either seln_first or seln_last is showing
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -