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

📄 textwidget.c

📁 具有IDE功能的编辑器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* textwidget.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. */#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 "mad.h"extern struct look *look;int option_text_fg_normal = 0;int option_text_fg_bold = 1;int option_text_fg_italic = 18;int option_text_bg_normal = 26;int option_text_bg_marked = 25;int option_text_bg_highlighted = 12;void selection_clear (void);static long current;extern int calc_text_pos2 (CWidget * w, long b, long *q, int l);extern void convert_text2 (CWidget * w, long from, cache_type *line, int x, int x_max, int row);void edit_translate_xy (int xs, int ys, int *x, int *y);/* returns the position in the edit buffer of a window click */long text_get_click_pos (CWidget * w, int x, int y){    long click, c, q;    int width;    width = w->options & TEXTBOX_WRAP ? (w->width - TEXTBOX_BDR) / FONT_MEAN_WIDTH : 32000;    if (y > 1)	c = strmovelines (w->text, w->current, y - 1, width);    else	c = w->current;    if (y > 0)	click = strmovelines (w->text, c, 1, width);    else	click = w->current;    if (w->options & TEXTBOX_MARK_WHOLE_LINES) {	if (click == c && y > 0) {	    calc_text_pos2 (w, click, &q, 32000);	/* this is to get the last line */	    return q;	}	return click;    } else	calc_text_pos2 (w, click, &q, x);    return q;}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){    return text_get_click_pos (w, --x, --y);}/* 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;}int range (CWidget * w, long start, long end, int click){    return (start <= click && click < end);}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);    }}static char *get_block (CWidget * w, long start_mark, long end_mark, int *type, int *l){    char *t, *t2;    *l = abs (w->mark2 - w->mark1);    t = CMalloc (*l + 1);    memcpy (t, w->text + min (w->mark1, w->mark2), *l);    t[*l] = 0;    t2 = str_strip_nroff ((char *) t, l);    free (t);    t2[*l] = 0;    if (w->options & TEXTBOX_FILE_LIST) {#ifdef HAVE_DND	char *p;	int i;	p = CDndFileList (t2, l, &i);	if (!p) {	    free (t2);	    return 0;	}	free (t2);	t2 = p;	if (i == 1)	    *type = DndFile;	else#endif	    *type = DndFiles;    } else {	*type = DndText;    }    return t2;}static void move (CWidget * w, long click, int row){    int h;    current = click;    if (w->mark2 == -1)	w->mark1 = current;    h = (w->height - TEXTBOX_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 textbox_mouse_mark = {    0,    (void (*)(int, int, int *, int *)) xy,    (long (*)(void *, int, int)) cp,    (int (*)(void *, long *, long *)) marks,    (int (*)(void *, long, long, long)) range,    (void (*)(void *)) fin_mark,    (void (*)(void *)) move_mark,    (void (*)(void *, XEvent *)) release_mark,    (char *(*)(void *, long, long, int *, int *)) get_block,    (void (*)(void *, long, int)) move,    (void (*)(void *, long)) motion,    0,    0,    0,    0,    DndText};/*   If options & TEXTBOX_NO_STRDUP then text must be passed as an malloced string   which will be free'd automatically when the text box is destroyed.   If !options & TEXTBOX_NO_STRDUP then text will be strdup'ed (creating its own   internal copy of the text), like other widgets.   CRedrawTextbox will do the same as CDrawTextbox: it will not free old text   or make its own copy of new text. */CWidget *CDrawTextbox (const char *identifier, Window parent, int x, int y,		       int width, int height, int line, int column, const char *text, long options){    char *scroll;    int numlines;    CWidget *wdt;    int w, h;    CPushFont ("editor", 0);    if (width == AUTO_WIDTH || height == AUTO_HEIGHT)	CTextSize (&w, &h, text);    if (width == AUTO_WIDTH)	width = w + 6;    if (height == AUTO_HEIGHT)	height = h + 6;    wdt = CSetupWidget (identifier, parent, x, y,			width, height, C_TEXTBOX_WIDGET, INPUT_KEY,			color_palette (option_text_bg_normal), 1);    wdt->funcs = mouse_funcs_new (wdt, &textbox_mouse_mark);    xdnd_set_type_list (CDndClass, wdt->winid, xdnd_typelist_send[DndText]);    wdt->options = options | WIDGET_TAKES_SELECTION;    if (options & TEXTBOX_NO_STRDUP)	wdt->text = (char *) text;    else	wdt->text = (char *) strdup (text);    numlines = strcountlines (text, 0, 1000000000, options & TEXTBOX_WRAP ? (wdt->width - TEXTBOX_BDR) / FONT_MEAN_WIDTH : 32000) + 1;    wdt->firstline = 0;    wdt->firstcolumn = 0;    wdt->cursor = 0;    wdt->current = 0;    wdt->numlines = numlines;    wdt->textlength = strlen (wdt->text);    CSetTextboxPos (wdt, TEXT_SET_LINE, line);    CSetTextboxPos (wdt, TEXT_SET_COLUMN, column);    if (height > 80) {/* this will also set the hint position, set_hint_pos() */	wdt->vert_scrollbar = CDrawVerticalScrollbar (scroll = catstrs (identifier, ".vsc", 0), parent,		x + width + WIDGET_SPACING, y, height, AUTO_WIDTH, 0, 0);	CSetScrollbarCallback (wdt->vert_scrollbar->ident, wdt->ident, link_scrollbar_to_textbox);    } else {	set_hint_pos (x + width + WIDGET_SPACING, y + height + WIDGET_SPACING);    }    CPopFont ();    return wdt;}int CSetTextboxPos (CWidget * w, int which, long p);/* redraws the text box. If preserve is 0 then view position is reset to 0 */CWidget *CRedrawTextbox (const char *identifier, const char *text, int preserve){    CWidget *w = CIdent (identifier);    int numlines, firstline, firstcolumn, cursor;    if (!w)	return 0;    if (w->options & TEXTBOX_NO_STRDUP)	w->text = (char *) text;    else {	if (w->text)	    free (w->text);	w->text = (char *) strdup (text);    }    CPushFont ("editor", 0);    w->textlength = strlen (w->text);    numlines = strcountlines (text, 0, 1000000000, w->options & TEXTBOX_WRAP ? (w->width - TEXTBOX_BDR) / FONT_MEAN_WIDTH : 32000) + 1;    w->numlines = numlines;    firstline = w->firstline;    firstcolumn = w->firstcolumn;    cursor = w->cursor;    w->firstline = 0;    w->current = 0;    w->firstcolumn = 0;    w->cursor = 0;    w->mark1 = w->mark2 = -1;    if (preserve) {	CSetTextboxPos (w, TEXT_SET_LINE, firstline);	CSetTextboxPos (w, TEXT_SET_COLUMN, firstcolumn);	CSetTextboxPos (w, TEXT_SET_CURSOR_LINE, cursor);    }    CExpose (identifier);    CPopFont ();    return w;}/* result must not be free'd, and must be used immediately */char *CGetTextBoxLine (CWidget * w, int i){    int width;    char *r;    CPushFont ("editor", 0);    width = w->options & TEXTBOX_WRAP ? (w->width - TEXTBOX_BDR) / FONT_MEAN_WIDTH : 32000;    r = strline (w->text, strmovelines (w->text, w->current, i - w->firstline, width));    CPopFont ();    return r;}/* clears the text box */CWidget *CClearTextbox (const char *identifier){    CWidget *w;    w = CIdent (identifier);    if (w) {	if (!(w->options & TEXTBOX_NO_STRDUP))	    if (w->text)		free (w->text);	w->text = (char *) strdup ("");	w->textlength = w->numlines = 0;	w->firstline = w->firstcolumn = 0;	w->mark1 = w->mark2 = 0;	CExpose (identifier);    }    return w;}CWidget *CDrawManPage (const char *identifier, Window parent, int x, int y,	   int width, int height, int line, int column, const char *text){    CWidget *w;    w = CDrawTextbox (identifier, parent, x, y, width, height, line, column, text, TEXTBOX_MAN_PAGE);    return w;}/*   If which is TEXT_SET_POS the current offset of the top right   corner is set to p.   returns non-zero if anything actually changed. */int CSetTextboxPos (CWidget * wdt, int which, long p){    long q;    int width, i, j;    if (p < 0)	p = 0;    CPushFont ("editor", 0);    width = wdt->options & TEXTBOX_WRAP ? (wdt->width - TEXTBOX_BDR) / FONT_MEAN_WIDTH : 32000;    switch (which) {    case TEXT_SET_COLUMN:	i = wdt->firstcolumn;	wdt->firstcolumn = p;	CPopFont ();	return (i != wdt->firstcolumn);    case TEXT_SET_LINE:	i = wdt->firstline;	if (p >= wdt->numlines)	    p = wdt->numlines - 1;	if (p < 0)	    p = 0;	if (wdt->kind == C_FIELDED_TEXTBOX_WIDGET) {	    wdt->firstline = p;	} else {	    q = strmovelines (wdt->text, wdt->current, p - wdt->firstline, width);	    wdt->firstline += strcountlines (wdt->text, wdt->current, q - wdt->current, width);	    wdt->current = q;	}	CPopFont ();	return (i != wdt->firstline);    case TEXT_SET_POS:	i = wdt->firstline;	if (wdt->kind == C_FIELDED_TEXTBOX_WIDGET) {	    break;	} else {	    wdt->firstline += strcountlines (wdt->text, wdt->current, p - wdt->current, width);	    wdt->current = p;	}	CPopFont ();	return (i != wdt->firstline);

⌨️ 快捷键说明

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