⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inputwidget.c

📁 具有IDE功能的编辑器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* textinput.c - draw an editable text widget   Copyright (C) 1996-2000 Paul Sheer   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA   02111-1307, USA. */#include <config.h>#include <stdio.h>#include <my_string.h>#include <stdlib.h>#include <stdarg.h>#include <X11/Intrinsic.h>#include <X11/Xatom.h>#include "lkeysym.h"#include "stringtools.h"#include "app_glob.c"#include "coolwidget.h"#include "coollocal.h"#include "edit.h"#include "editcmddef.h"#include "mousemark.h"#include "mad.h"int eh_textinput (CWidget * w, XEvent * xevent, CEvent * cwevent);void input_mouse_mark (CWidget * w, XEvent * event, CEvent * ce);extern struct look *look;/* {{{  history stuff: draws a history of inputs a widget of the same ident */#define MAX_HIST_LEN 64#define MAX_HIST_WIDGETS 128struct textinput_history {    char ident[32];    int text_len;	/* length of a newline separate list of all 'input' strings */    int last;    char *input[MAX_HIST_LEN];};static struct textinput_history *history_widgets[MAX_HIST_WIDGETS] ={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};static int last = 0;static void add_to_history (struct textinput_history *h, const char *text, int allow_blank_lines){    int i, j;    char *t, *p;    if (!text)	return;    if (!*text && !allow_blank_lines)	return;    t = (char *) strdup (text);    if ((p = strchr (t, '\n')))	*p = '\0';		/* no newlines allowed in the history */    if (h->last)	for (i = h->last - 1; i >= 0; i--)	    if (!strcmp (h->input[i], text)) {	/* avoid adding duplicates */		text = h->input[i];		if (i < h->last - 1)		    for (j = i; j < h->last - 1; j++)	/* shift all entries up one place */			h->input[j] = h->input[j + 1];		h->input[h->last - 1] = (char *) text;	/* move new entry to top */		free (t);		return;	    }    h->input[h->last++] = t;    if (h->last == MAX_HIST_LEN) {	h->text_len -= strlen (h->input[0]) + 1;	free (h->input[0]);	memmove (h->input, h->input + 1, (MAX_HIST_LEN - 1) * sizeof (char *));		/* shift up to make space */	h->last--;    }    h->text_len += strlen (text) + 1;	/* maintain total list length */}static void add_to_widget_history (const char *ident, const char *text){    int i;    int allow_blank_lines = 0;    allow_blank_lines = (strchr (ident, '+') != 0);    for (i = 0; i < MAX_HIST_WIDGETS; i++) {	if (!history_widgets[i])	    break;	if (!strcmp (history_widgets[i]->ident, ident)) {	    add_to_history (history_widgets[i], text, allow_blank_lines);	    return;	}    }/* create a new history */    history_widgets[last] = CMalloc (sizeof (struct textinput_history));    memset (history_widgets[last], 0, sizeof (struct textinput_history));    strcpy (history_widgets[last]->ident, ident);    add_to_history (history_widgets[last], text, allow_blank_lines);    last++;    if (last == MAX_HIST_WIDGETS) {	/* shift up one */	for (i=0;i<history_widgets[0]->last;i++) {	    if (!history_widgets[0]->input[i])		break;	    free (history_widgets[0]->input[i]);	}	free (history_widgets[0]);	memmove (history_widgets, history_widgets + 1, (MAX_HIST_WIDGETS - 1) * sizeof (struct textinput_history *));	last--;    }}void CAddToTextInputHistory (const char *ident, const char *text){    add_to_widget_history (ident, text);}/*   Returns a newline separate list of all 'input' in the history.   Result must be free'd . */static char *get_history_list (const char *ident, int reverse, int *num_lines){    char *s, *r;    int i, j;    for (i = 0; i < MAX_HIST_WIDGETS; i++) {	if (!history_widgets[i])	    break;	if (!strcmp (history_widgets[i]->ident, ident)) {	    r = s = CMalloc (history_widgets[i]->text_len);	    if (!(*num_lines = history_widgets[i]->last))		break;	    if (reverse) {		for (j = 0; j < history_widgets[i]->last; j++) {		    strcpy (s, history_widgets[i]->input[j]);		    s += strlen (s);		    *s++ = '\n';		}	    } else {		for (j = history_widgets[i]->last - 1; j >= 0; j--) {	/* most recent at top */		    strcpy (s, history_widgets[i]->input[j]);		    s += strlen (s);		    *s++ = '\n';		}	    }	    *(--s) = 0;	    return r;	}    }    *num_lines = 1;    return (char *) strdup ("");}/* result must not be free'd *//* returns the last text inputted in the input widget named ident */char *CLastInput (const char *ident){    int i;    for (i = 0; i < MAX_HIST_WIDGETS; i++) {	if (!history_widgets[i])	    break;	if (!strcmp (history_widgets[i]->ident, ident)) {	    if (!history_widgets[i]->last)		return "";	    return history_widgets[i]->input[history_widgets[i]->last - 1];	}    }    return "";}#define HISTORY_LINES 10static int clip_lines (int lines, int num_lines){    if (lines > num_lines)	lines = num_lines;    if (lines > HISTORY_LINES)	lines = HISTORY_LINES;    if (lines < 1)	lines = 1;    return lines;}/* gets a list of all input histories and all widget for use in saving   to an options file (if you want to save the state of an application,    for example. result must be free'd */char *get_all_lists (void){    char *s, *r;    int i, j;    int tot_len;    tot_len = 0;/* calc length to alloc */    for (i = 0; i < MAX_HIST_WIDGETS; i++) {	if (!history_widgets[i])	    break;	tot_len += strlen (history_widgets[i]->ident) + 1;	tot_len += history_widgets[i]->text_len + history_widgets[i]->last;    }    r = s = CMalloc (tot_len + 1);    for (i = 0; i < MAX_HIST_WIDGETS; i++) {	if (!history_widgets[i])	    break;	strcpy (s, history_widgets[i]->ident);	s += strlen (s);	*s++ = '\n';	for (j = 0; j < history_widgets[i]->last; j++) {	    *s++ = '\t';	    strcpy (s, history_widgets[i]->input[j]);	    s += strlen (s);	    *s++ = '\n';	}    }    *s = 0;    return r;}void free_all_lists (void){    int i, j;    for (i = 0; i < MAX_HIST_WIDGETS; i++) {	if (!history_widgets[i])	    break;	for (j = 0; j < history_widgets[i]->last; j++) {	    if (!history_widgets[i]->input[j])		break;	    free (history_widgets[i]->input[j]);	    history_widgets[i]->input[j] = 0;	}	free (history_widgets[i]);	history_widgets[i] = 0;    }}void put_all_lists (char *list){    char *p;    char ident[33];    char input[1024];    ident[32] = 0;    input[1023] = 0;    if (!list)	return;    while (*list) {	p = strchr (list, '\n');	if (!p)	    return;	*p++ = 0;	strncpy (ident, list, 32);	list = p;	while (*list == '\t') {	    list++;	    p = strchr (list, '\n');	    if (!p)		return;	    *p++ = 0;	    strncpy (input, list, 1023);	    list = p;	    add_to_widget_history (ident, input);	}    }}    static char *draw_text_input_history (CWidget * text_input){    char *p, *r;    int num_lines;    CWidget *w;    int x, y;    int columns, lines;    if (text_input->options & TEXTINPUT_PASSWORD)	/* password lines, not allowed a history! */	return 0;    x = text_input->x;    CPushFont ("editor", 0);    columns = (text_input->width - WIDGET_SPACING * 3 - 4 - 6 - 20) / FONT_MEAN_WIDTH;    w = CWidgetOfWindow (text_input->parentid);    if (!w) {    	CPopFont ();	return 0;    }    if (text_input->y > w->height / 2) {	p = get_history_list (text_input->ident, 1, &num_lines);	lines = (text_input->y - 2 - WIDGET_SPACING * 2 - 4 - 6) / FONT_PIX_PER_LINE;	lines = clip_lines (lines, num_lines);	y = text_input->y - lines * FONT_PIX_PER_LINE - WIDGET_SPACING * 2 - 4 - 6;	r = CTrivialSelectionDialog (w->winid, x, y, columns, lines, p, max (0, num_lines - lines), num_lines - 1);    } else {	p = get_history_list (text_input->ident, 0, &num_lines);	lines = (w->height - text_input->height - text_input->y - 2 - WIDGET_SPACING * 2 - 4 - 6) / FONT_PIX_PER_LINE;	lines = clip_lines (lines, num_lines);	y = text_input->y + text_input->height;	r = CTrivialSelectionDialog (w->winid, x, y, columns, lines, p, 0, 0);    }    free (p);    CPopFont ();    return r;}#if 0wchar_t *mbstowcs_dup (unsigned char *s);int wchar_t_strlen (wchar_t * s);int wchar_t_columns (char *t, int x){    wchar_t *s;    t = (char *) strdup ((char *) t);    t[x] = '\0';    s = mbstowcs_dup ((unsigned char *) t);    x = wchar_t_strlen (s);    free (t);    free (s);    return x;}#endifvoid render_passwordinput (CWidget * wdt){    int wc, k, l, w = wdt->width, h = wdt->height;    Window win;    char *password;    CPushFont ("editor", 0);    win = wdt->winid;    CSetBackgroundColor (COLOR_WHITE);    CSetColor (COLOR_BLACK);    password = (char *) strdup (wdt->text);    memset (password, '*', strlen (wdt->text));    CImageString (win, FONT_OFFSET_X + 3 + TEXTINPUT_RELIEF,		      FONT_OFFSET_Y + 3 + TEXTINPUT_RELIEF,		      password);    CSetColor (COLOR_WHITE);    l = CImageStringWidth (password);    k = min (l, w - 6);    memset (password, 0, strlen (password));    free (password);    CRectangle (win, 3, 3, k, option_text_line_spacing + 1);    CLine (win, 3, 4, 3, h - 5);    CLine (win, 3, h - 4, k + 3, h - 4);    CRectangle (win, k + 3, 3, w - 6 - k, h - 6);    (*look->render_passwordinput_tidbits) (wdt, win == CGetFocus ());    wc = 3 + TEXTINPUT_RELIEF + 1 + CImageTextWidth (password, wdt->cursor);    set_cursor_position (win, wc, 5, 0, h - 5, CURSOR_TYPE_TEXTINPUT, 0, 0, 0, 0);    CPopFont ();    return;}void render_textinput (CWidget * wdt){    int wc, isfocussed = 0;    int f, k, l;    int x, m1, m2;    int w = wdt->width, h = wdt->height;    Window win;    char *s;    if (wdt->options & TEXTINPUT_PASSWORD) {	render_passwordinput (wdt);	return;    }        CPushFont ("editor", 0);    win = wdt->winid;    isfocussed = (win == CGetFocus ());/*This is a little untidy, but it will account for uneven font widths   without having to think to hard */    do {	f = 0;/*wc is the position of the cursor from the left of the input window */	wc = 3 + TEXTINPUT_RELIEF + 1 +	    CImageTextWidth (wdt->text + wdt->firstcolumn, wdt->cursor - wdt->firstcolumn);	/*now lets make sure the cursor is well within the view *//*except for when the cursor is at the end of the line */	if (wdt->cursor == strlen (wdt->text)) {	    if (wc > w - 3 - h) {		wdt->firstcolumn++;		f = 1;	    }	} else if (wc > max (w - FONT_MEAN_WIDTH - h, w * 3 / 4 - h)) {	    wdt->firstcolumn++;	    f = 1;	}	if (wc < min (FONT_MEAN_WIDTH, w / 4)) {	    wdt->firstcolumn--;	    f = 1;	    /*Unless of course we are at the beginning of the string */	    if (wdt->firstcolumn <= 0) {		wdt->firstcolumn = 0;		f = 0;	    }	}    } while (f);		/*recalculate if firstcolumn has changed */    s = wdt->text + wdt->firstcolumn;    l = strlen (s);    CSetColor (COLOR_WHITE);    k = min (CImageTextWidth (s, l), w - h - 6);    CRectangle (win, 3, 3, k, option_text_line_spacing + 1);    CLine (win, 3, 4, 3, h - 5);    CLine (win, 3, h - 4, k + 3, h - 4);    CRectangle (win, k + 3, 3, w - h - 6 - k, h - 6);/* now draw the visible part of the string */    wdt->mark1 = min (wdt->mark1, l + wdt->firstcolumn);    wdt->mark2 = min (wdt->mark2, l + wdt->firstcolumn);    m1 = min (wdt->mark1, wdt->mark2);    m2 = max (wdt->mark1, wdt->mark2);    x = 0;    if (m1 > wdt->firstcolumn) {	CSetBackgroundColor (COLOR_WHITE);	CSetColor (COLOR_BLACK);	CImageText (win,			  FONT_OFFSET_X + 3 + TEXTINPUT_RELIEF,			  FONT_OFFSET_Y + 3 + TEXTINPUT_RELIEF,			  s, m1 - wdt->firstcolumn);	x += CImageTextWidth (s, m1 - wdt->firstcolumn);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -