📄 panel_text.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)panel_text.c 1.1 92/07/30 Copyr 1984 Sun Micro";#endif#endif/***********************************************************************//* panel_text.c *//* Copyright (c) 1985 by Sun Microsystems, Inc. *//***********************************************************************/#include <suntool/panel_impl.h>#include <ctype.h>#include <sys/filio.h>#include <fcntl.h>#include <sunwindow/defaults.h>#include <sundev/kbd.h>#include <sunwindow/sv_malloc.h>static caddr_t panel_getcaret(), panel_setcaret();char *malloc();/***********************************************************************//* field-overflow pointer *//***********************************************************************/static short left_arrow_image[] = {#include <images/panel_left_arrow.pr>};static mpr_static(panel_left_arrow_pr, 8, 8, 1, left_arrow_image);static short right_arrow_image[] = {#include <images/panel_right_arrow.pr>};static mpr_static(panel_right_arrow_pr, 8, 8, 1, right_arrow_image);static int primary_ms_clicks = 0; /* # primary mouse left clicks */static int secondary_ms_clicks = 0; /* # secondary mouse left clicks */static int ms_clicks = 0;static u_char primary_pending_delete = FALSE;static u_char secondary_pending_delete = FALSE;static panel_handle primary_seln_panel, secondary_seln_panel;static Rect primary_seln_rect, secondary_seln_rect;static int primary_seln_first, primary_seln_last;static int secondary_seln_first, secondary_seln_last;typedef enum { HL_NONE, HL_GRAY, HL_INVERT} highlight_t;static highlight_t primary_seln_highlight = HL_NONE;static highlight_t secondary_seln_highlight = HL_NONE;#define PV_HIGHLIGHT TRUE#define PV_NO_HIGHLIGHT FALSE#define textdp(ip) ((text_data *)LINT_CAST((ip)->data))static begin_preview(), cancel_preview(), accept_preview(), accept_menu(), accept_key(), paint(), destroy(), set_attr();static caddr_t get_attr();static Panel_item remove();static Panel_item restore();static void text_caret_invert();static void text_caret_on();static void paint_value();extern void (*panel_caret_on_proc) (), (*panel_caret_invert_proc) ();static struct panel_ops ops = { panel_default_handle_event, /* handle_event() */ begin_preview, /* begin_preview() */ begin_preview, /* update_preview() */ cancel_preview, /* cancel_preview() */ accept_preview, /* accept_preview() */ accept_menu, /* accept_menu() */ accept_key, /* accept_key() */ paint, /* paint() */ destroy, /* destroy() */ get_attr, /* get_attr() */ set_attr, /* set_attr() */ remove, /* remove() */ restore, /* restore() */ panel_nullproc /* layout() */};/***********************************************************************//* data area *//***********************************************************************/typedef struct text_data { Panel_setting notify_level; /* NONE, SPECIFIED, NON_PRINTABLE, * ALL */ panel_item_handle orig_caret; /* original item with the caret */ int underline; /* TRUE, FALSE (not implemented) */ int flags; char *value; Pixfont *font; char mask; int caret_offset; /* caret's x offset from value rect */ int secondary_caret_offset; int value_offset; /* right margin of last displayed * char (x offset from value rect) */ int last_char; /* last displayed character */ int seln_first; /* index of first char selected */ int seln_last; /* index of last char selected */ int ext_first; /* first char of extended word */ int ext_last; /* last char of extended word */ int first_char; /* first displayed character */ char *terminators; int stored_length; int display_length; char edit_bk_char; char edit_bk_word; char edit_bk_line; panel_item_handle next;} text_data;#define SELECTING_ITEM 0x00000001#define HASCARET 0x00000002#define READ_ONLY 0x00000004#define UP_CURSOR_KEY (KEY_RIGHT(8))#define DOWN_CURSOR_KEY (KEY_RIGHT(14))#define RIGHT_CURSOR_KEY (KEY_RIGHT(12))#define LEFT_CURSOR_KEY (KEY_RIGHT(10))Panel_itempanel_text(ip, avlist) register panel_item_handle ip; Attr_avlist avlist;{ register text_data *dp; char *def_str; /* set the caret functions for panel_public.c and panel_select.c */ panel_caret_on_proc = text_caret_on; panel_caret_invert_proc = text_caret_invert; if (!ip->panel->seln_client) panel_seln_init(ip->panel); if (!(dp = (text_data *) LINT_CAST(calloc(1, sizeof(text_data))))) return (NULL); ip->ops = &ops; ip->data = (caddr_t) dp; ip->item_type = PANEL_TEXT_ITEM; if (ip->notify == panel_nullproc) ip->notify = (int (*) ()) panel_text_notify; dp->notify_level = PANEL_SPECIFIED; dp->font = ip->panel->font; dp->mask = '\0'; dp->terminators = panel_strsave("\n\r\t"); dp->stored_length = 80; dp->display_length = 80; /* * Keymapping has made the following edit character settings obsolete. * (see update_value() below) */ if (ip->panel->edit_bk_char == NULL) { def_str = defaults_get_string("/Text/Edit_back_char", "\177", (int *) NULL); ip->panel->edit_bk_char = def_str[0]; def_str = defaults_get_string("/Text/Edit_back_word", "\027", (int *) NULL); ip->panel->edit_bk_word = def_str[0]; def_str = defaults_get_string("/Text/Edit_back_line", "\025", (int *) NULL); ip->panel->edit_bk_line = def_str[0]; } dp->edit_bk_char = ip->panel->edit_bk_char; dp->edit_bk_word = ip->panel->edit_bk_word; dp->edit_bk_line = ip->panel->edit_bk_line; dp->value = (char *) calloc(1, (u_int) (dp->stored_length + 1)); if (!dp->value) return (NULL); /* * All other dp-> fields are initialized to zero by calloc(). */ ip->value_rect.r_width = panel_col_to_x(dp->font, dp->display_length); ip->value_rect.r_height = dp->font->pf_defaultsize.y; /* set the user specified attributes */ if (!set_attr(ip, avlist)) return NULL;; /* append to the panel list of items */ (void) panel_append(ip); /* only insert in caret list if not hidden already */ if (!hidden(ip)) insert(ip); return (Panel_item) ip;}static intset_attr(ip, avlist) register panel_item_handle ip; register Attr_avlist avlist;{ register text_data *dp = textdp(ip); register Panel_attribute attr; char *new_value = NULL; short value_changed = FALSE; extern char *strncpy(); while (attr = (Panel_attribute) * avlist++) { switch (attr) { case PANEL_VALUE: new_value = (char *) *avlist++; break; case PANEL_VALUE_FONT: dp->font = (Pixfont *) LINT_CAST(*avlist++); value_changed = TRUE; break; case PANEL_VALUE_UNDERLINED: dp->underline = (int) *avlist++; break; case PANEL_NOTIFY_LEVEL: dp->notify_level = (Panel_setting) * avlist++; break; case PANEL_NOTIFY_STRING: dp->terminators = panel_strsave((char *) *avlist++); break; case PANEL_VALUE_STORED_LENGTH: dp->stored_length = (int) *avlist++; dp->value = (char *) sv_realloc(dp->value, (u_int) (dp->stored_length + 1)); break; case PANEL_VALUE_DISPLAY_LENGTH: dp->display_length = (int) *avlist++; value_changed = TRUE; break; case PANEL_MASK_CHAR: dp->mask = (char) *avlist++; break; case PANEL_READ_ONLY: if (*avlist++) dp->flags |= READ_ONLY; else dp->flags &= ~READ_ONLY; break; default: avlist = attr_skip(attr, avlist); break; } } if (new_value) { char *old_value = dp->value; dp->value = (char *) sv_calloc(1, (u_int) (dp->stored_length + 1)); (void) strncpy(dp->value, new_value, dp->stored_length); free(old_value); /* Move the caret to the end of the text value */ dp->last_char = strlen(dp->value) - 1; if (dp->last_char >= dp->display_length) { /* Left-truncate displayed string, leaving room for left arrow */ dp->first_char = dp->last_char - dp->display_length + 2; dp->caret_offset = ip->value_rect.r_width; } else { dp->first_char = 0; dp->caret_offset = strlen(dp->value) * dp->font->pf_defaultsize.x; } /* PUT AFTER ASSIGNMENT OF dp->first_char, dp->last_char */ /* release any held selection */ cancel_preview(ip, (Event *) NULL); /* Must be here until panel_seln_dehilite fixed? */ paint_caret(ip, PIX_CLR); } /* * update the value & items rect if the width or height of the value has * changed. */ if (value_changed) { ip->value_rect.r_width = panel_col_to_x(dp->font, dp->display_length); ip->value_rect.r_height = dp->font->pf_defaultsize.y; ip->rect = panel_enclosing_rect(&ip->label_rect, &ip->value_rect); } return 1;}/***********************************************************************//* get_attr *//* returns the current value of an attribute for the text item. *//***********************************************************************/static caddr_tget_attr(ip, which_attr) panel_item_handle ip; register Panel_attribute which_attr;{ register text_data *dp = textdp(ip); switch (which_attr) { case PANEL_VALUE: return (caddr_t) dp->value; case PANEL_VALUE_FONT: return (caddr_t) dp->font; case PANEL_VALUE_STORED_LENGTH: return (caddr_t) dp->stored_length; case PANEL_VALUE_DISPLAY_LENGTH: return (caddr_t) dp->display_length; case PANEL_NOTIFY_LEVEL: return (caddr_t) dp->notify_level; case PANEL_NOTIFY_STRING: return (caddr_t) dp->terminators; case PANEL_READ_ONLY: if (dp->flags & READ_ONLY) return (caddr_t) TRUE; else return (caddr_t) FALSE; default: return panel_get_generic(ip, which_attr); }}/***********************************************************************//* remove *//***********************************************************************/static Panel_itemremove(ip) register panel_item_handle ip;{ register panel_handle panel = ip->panel; register panel_item_handle prev_item, next_item; short had_caret_seln = FALSE; /* READ_ONLY text can accept caret to allow scrolling */#ifdef OBSOLETE if (textdp(ip)->flags & READ_ONLY) return NULL;#endif next_item = textdp(ip)->next; /* if already removed then ignore remove() */ if (!next_item) return NULL; /* * cancel the selection if this item owns it. */ if (panel_seln(panel, SELN_PRIMARY)->ip == ip) panel_seln_cancel(panel, SELN_PRIMARY); if (panel_seln(panel, SELN_SECONDARY)->ip == ip) panel_seln_cancel(panel, SELN_SECONDARY); if (panel_seln(panel, SELN_CARET)->ip == ip) { had_caret_seln = TRUE; panel_seln_cancel(panel, SELN_CARET); } /* if ip is the only text item, then remove caret for panel */ if (next_item == ip) { textdp(ip)->next = NULL; textdp(ip)->flags &= ~HASCARET; panel->caret = NULL; return NULL; } /* find the next item */ for (prev_item = next_item; textdp(prev_item)->next != ip; prev_item = textdp(prev_item)->next ); /* unlink ip from the list */ textdp(prev_item)->next = next_item; textdp(ip)->next = NULL; /* reset the caret */ if (panel->caret == ip) { textdp(ip)->flags &= ~HASCARET; panel->caret = next_item; textdp(next_item)->flags |= HASCARET; if (had_caret_seln) panel_seln(panel, SELN_CARET)->ip = panel->caret; } return (Panel_item) ip;}/*************************************************************************//* restore *//* this code assumes that the caller has already set ip to be not hidden *//*************************************************************************/static Panel_itemrestore(ip) register panel_item_handle ip;{ register panel_item_handle prev_item, next_item; register text_data *dp, *prev_dp; /* READ_ONLY text can accept caret to allow scrolling */#ifdef OBSOLETE if (textdp(ip)->flags & READ_ONLY) return NULL;#endif /* if not removed then ignore restore() */ if (textdp(ip)->next) return NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -