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

📄 fieldedtextbox.c

📁 具有IDE功能的编辑器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* fieldedtextbox.c - for drawing a scrollable text window 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. *//* *    format: * *    the printed fields can have the following: * *    '\t': can only occur at the begining and end, or at the beginning. *              At the beginning signals right justification. At the beginning *              and the end signals centering. eg "\tcentred\t" or "\tleft" *    "\v%d": insert pixmap %d at the point. Pixmaps are a special variety *              defined by the create_text_pixmap() function. The value passed *              to this function must appear after the \v and must be less *              than 128. *    "\f%d": advance forward %d pixels. %d must be less than 128. *    "\r%c": puts %c in 'italic' color, default: green. *    "\b%c": puts %c in 'bold' color, default: blue. */#define BDR 8#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 "edit.h"#include "editcmddef.h"#include "coolwidget.h"#include "coollocal.h"#include "mousemark.h"#include "pool.h"#include "mad.h"extern struct look *look;extern int option_text_fg_normal;extern int option_text_fg_bold;extern int option_text_fg_italic;extern int option_text_bg_normal;extern int option_text_bg_marked;extern int option_text_bg_highlighted;/* for this widget   ->column holds the pixel width of the longest line *//* char ** (*get_line) (void *data, int line_number, int *num_fields, int *tagged); */#define pixmap_width(x) 0int eh_fielded_textbox (CWidget * w, XEvent * xevent, CEvent * cwevent);static int calc_text_pos_fielded_textbox (CWidget * w, long b, long *q, int l);/* these are not printable in this module */#define this_is_printable(c) (!strchr ("\r\b\t", c))static int this_text_width (char *s){    int l = 0;    char *p;    for (p = s; *p; p++) {	if (*p == '\v')	    l += pixmap_width (++p);	else if (*p == '\f')	    l += *(++p);	else if (this_is_printable (*p))	    l += FONT_PER_CHAR((unsigned char) *p);    }    return l;}#define INTER_FIELD_SPACING	6#define LINE_OFFSET		0/* result must be free'd */static int *get_field_sizes (void *data, int *num_lines, int *max_width,			     char **(*get_line) (void *, int, int *, int *)){    char **fields;    int tagged, i, tab[256], *result, num_fields, max_num_fields = 0, line_number;    memset (tab, 0, sizeof (tab));    *num_lines = 0;    for (line_number = 0;; line_number++) {	fields = (*get_line) (data, line_number, &num_fields, &tagged);	if (!fields)	    break;	(*num_lines)++;	if (max_num_fields < num_fields)	    max_num_fields = num_fields;	for (i = 0; i < num_fields; i++) {	    int l;	    if (!fields[i])		break;	    l = this_text_width (fields[i]);	    if (tab[i] < l)		tab[i] = l;	}    }    *max_width = 0;    for (i = 0; i < max_num_fields; i++)	tab[i] += INTER_FIELD_SPACING;    for (i = 0; i < max_num_fields; i++)	*max_width += tab[i];    result = CMalloc (max_num_fields * sizeof (int));    memcpy (result, tab, max_num_fields * sizeof (int));    tab[max_num_fields] = 0;    return result;}static void compose_line (void *data, int line_number, unsigned char *line, int *tab,		     char **(*get_line) (void *, int, int *, int *), int *tagged){    char **fields;    int i, num_fields;    *line = 0;    *tagged = 0;    if (!data)	return;    fields = (*get_line) (data, line_number, &num_fields, tagged);    if (!fields)	return;    for (i = 0; i < num_fields; i++) {	int l = 0, t, centred = 0;	char *p;	p = fields[i];	t = tab[i] - this_text_width (p) - INTER_FIELD_SPACING;	if (t < 0)	    t = 0;	if (p[0] == '\t') {	    p++;	    if (p[strlen (p) - 1] == '\t') {		l = t - (t / 2);		t /= 2;		centred = 1;	    } else {		l = t;		t = 0;	    }	}	for (;;) {	    l -= 127;	    if (l >= 0) {		*line++ = '\f';		*line++ = (unsigned char) 127;	    } else {		l += 127;		if (l) {		    *line++ = '\f';		    *line++ = (unsigned char) l;		}		break;	    }	}	strcpy ((char *) line, p);	line += strlen (p) - centred;	if (!fields[i + 1])	    break;	t += INTER_FIELD_SPACING;	for (;;) {	    t -= 127;	    if (t >= 0) {		*line++ = '\f';		*line++ = (unsigned char) 127;	    } else {		t += 127;		if (t) {		    *line++ = '\f';		    *line++ = (unsigned char) t;		}		break;	    }	}    }    *line = 0;}static unsigned char *compose_line_cached (void *data, int l, int *tab, char **(*get_line) (void *, int, int *, int *), int *tagged){    static unsigned char line[4096];    static int c_tagged, c_l = -1;    if (c_l == l) {	*tagged = c_tagged;	return line;    }    compose_line (data, l, line, tab, get_line, tagged);    c_l = l;    c_tagged = *tagged;    return line;}static long count_fielded_textbox_lines (CWidget * wdt);void render_fielded_textbox (CWidget * w, int redrawall);void link_scrollbar_to_fielded_textbox (CWidget * scrollbar, CWidget * textbox, XEvent * xevent, CEvent * cwevent, int whichscrbutton){    int redrawtext = 0, count, c;    static int r = 0;    if ((xevent->type == ButtonRelease || xevent->type == MotionNotify) && whichscrbutton == 3) {	redrawtext = CSetTextboxPos (textbox, TEXT_SET_LINE, (double) scrollbar->firstline * textbox->numlines / 65535.0);    } else if (xevent->type == ButtonPress && (cwevent->button == Button1 || cwevent->button == Button2)) {	switch (whichscrbutton) {	case 1:	    redrawtext = CSetTextboxPos (textbox, TEXT_SET_LINE, textbox->firstline - (textbox->height / FONT_PIX_PER_LINE - 2));	    break;	case 2:	    redrawtext = CSetTextboxPos (textbox, TEXT_SET_LINE, textbox->firstline - 1);	    break;	case 5:	    redrawtext = CSetTextboxPos (textbox, TEXT_SET_LINE, textbox->firstline + 1);	    break;	case 4:	    redrawtext = CSetTextboxPos (textbox, TEXT_SET_LINE, textbox->firstline + (textbox->height / FONT_PIX_PER_LINE - 2));	    break;	}    }    if (xevent->type == ButtonRelease)	render_fielded_textbox (textbox, 0);    else {	c = CCheckWindowEvent (xevent->xany.window, ButtonReleaseMask | ButtonMotionMask, 0);	if (redrawtext) {	    if (!c) {		render_fielded_textbox (textbox, 0);		r = 0;	    } else {		r = 1;	    }	} else if (c && r) {	    render_fielded_textbox (textbox, 0);	    r = 0;	}    }    count = count_fielded_textbox_lines (textbox);    if (!count)	count = 1;    scrollbar->firstline = (double) 65535.0 *textbox->firstline / (textbox->numlines ? textbox->numlines : 1);    scrollbar->numlines = (double) 65535.0 *count / (textbox->numlines ? textbox->numlines : 1);}void link_h_scrollbar_to_fielded_textbox (CWidget * scrollbar, CWidget * textbox, XEvent * xevent, CEvent * cwevent, int whichscrbutton){    int redrawtext = 0, c;    static int r = 0;    if ((xevent->type == ButtonRelease || xevent->type == MotionNotify) && whichscrbutton == 3) {	redrawtext = CSetTextboxPos (textbox, TEXT_SET_COLUMN, (double) scrollbar->firstline * (textbox->column / FONT_MEAN_WIDTH) / 65535.0);    } else if (xevent->type == ButtonPress && (cwevent->button == Button1 || cwevent->button == Button2)) {	switch (whichscrbutton) {	case 1:	    redrawtext = CSetTextboxPos (textbox, TEXT_SET_COLUMN, textbox->firstcolumn - (textbox->width / FONT_MEAN_WIDTH - 2));	    break;	case 2:	    redrawtext = CSetTextboxPos (textbox, TEXT_SET_COLUMN, textbox->firstcolumn - 1);	    break;	case 5:	    redrawtext = CSetTextboxPos (textbox, TEXT_SET_COLUMN, textbox->firstcolumn + 1);	    break;	case 4:	    redrawtext = CSetTextboxPos (textbox, TEXT_SET_COLUMN, textbox->firstcolumn + (textbox->width / FONT_MEAN_WIDTH - 2));	    break;	}    }    if (xevent->type == ButtonRelease)	render_fielded_textbox (textbox, 0);    else {	c = CCheckWindowEvent (xevent->xany.window, ButtonReleaseMask | ButtonMotionMask, 0);	if (redrawtext) {	    if (!c) {		render_fielded_textbox (textbox, 0);		r = 0;	    } else {		r = 1;	    }	} else if (c && r) {	    render_fielded_textbox (textbox, 0);	    r = 0;	}    }    scrollbar->firstline = (double) 65535.0 *(textbox->firstcolumn * FONT_MEAN_WIDTH) / textbox->column;    scrollbar->numlines = (double) 65535.0 *(textbox->width - 6) / textbox->column;}void edit_translate_xy (int xs, int ys, int *x, int *y);void selection_clear (void);static long current;static void xy (int x, int y, int *x_return, int *y_return){    edit_translate_xy (x, y, x_return, y_return);}static long cp (CWidget * w, int x, int y){    long q;    y = (y + w->firstline - 1) << 16;    if (y < 0)	x = y = 0;    if (w->options & TEXTBOX_MARK_WHOLE_LINES)	x = 0;    calc_text_pos_fielded_textbox (w, y, &q, --x);    return q;}/* return 1 if not marked */static int marks (CWidget * w, long *start, long *end){    if (w->mark1 == w->mark2)	return 1;    *start = min (w->mark1, w->mark2);    *end = max (w->mark1, w->mark2);    return 0;}extern int range (CWidget * w, long start, long end, int click);static void move_mark (CWidget * w){    w->mark2 = w->mark1 = current;}static void fin_mark (CWidget * w){    w->mark2 = w->mark1 = -1;}static void release_mark (CWidget * w, XEvent * event){    w->mark2 = current;    if (w->mark2 != w->mark1 && event) {	selection_clear ();	XSetSelectionOwner (CDisplay, XA_PRIMARY, w->winid, event->xbutton.time);    }}/* result must be free'd */static char *get_block (CWidget * w, long start_mark, long end_mark, int *type, int *l){    POOL *p;    int tagged, i;    unsigned char c, *t;    long x, y, a, b;    void *data;    CPushFont ("editor", 0);    a = min (w->mark2, w->mark1);    b = max (w->mark2, w->mark1);    x = a & 0xFFFFL;    y = a >> 16;    p = pool_init ();    for (;; y++) {	unsigned char *text;	if (y < w->numlines)	    data = w->hook;	else	    data = 0;	text = compose_line_cached (data, y, w->tab, w->get_line, &tagged);	for (;; x++) {	    if (y == (b >> 16))		if (x >= (b & 0xFFFFL))		    goto done;	    c = text[x];	    if (!c) {		c = '\n';		pool_write (p, (unsigned char *) &c, 1);		break;	    }	    if (c == '\f') {		int j;#ifdef HAVE_DND		if (w->options & TEXTBOX_FILE_LIST) {	/* this is a filelist, so only get the first field: i.e. the file name */#else		if (*type == DndFiles || *type == DndFile) {	/* this is a filelist, so only get the first field: i.e. the file name */#endif		    c = '\n';		    pool_write (p, (unsigned char *) "\n", 1);		    break;		}    		j = text[++x];		while ((j -= FONT_PER_CHAR(' ')) > 0)		    pool_write (p, (unsigned char *) " ", 1);		pool_write (p, (unsigned char *) " ", 1);		continue;	    }	    if (c == '\v') {		int j;    		j = pixmap_width (text[++x]);		while ((j -= FONT_PER_CHAR(' ')) > 0)		    pool_write (p, (unsigned char *) " ", 1);		continue;	    }	    if (this_is_printable (c))		pool_write (p, (unsigned char *) &c, 1);	}	x = 0;    }  done:    CPopFont ();#ifdef HAVE_DND    *type = DndText;#endif    *l = pool_length (p);    pool_null (p);#ifdef HAVE_DND    if (!(w->options & TEXTBOX_FILE_LIST))#else    if (!(*type == DndFiles || *type == DndFile))#endif	return (char *) pool_break (p);    t = (unsigned char *) CDndFileList ((char *) pool_start (p), l, &i);    pool_free (p);    if (i == 1)	*type = DndFile;    else	*type = DndFiles;    return (char *) t;}static void move (CWidget * w, long click, int row){    int h;    current = click;    if (w->mark2 == -1)	w->mark1 = current;    h = (w->height - BDR) / FONT_PIX_PER_LINE;    if (row > h && w->firstline < w->numlines - h - 2)	CSetTextboxPos (w, TEXT_SET_LINE, w->firstline + row - h);    if (row < 1)	CSetTextboxPos (w, TEXT_SET_LINE, w->firstline + row - 1);    w->mark2 = click;}static void motion (CWidget * w, long click){    w->mark2 = click;}struct mouse_funcs fielded_mouse_funcs = {    0,    (void (*)(int, int, int *, int *)) xy,

⌨️ 快捷键说明

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