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

📄 editwidget.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* editor initialisation and callback handler.

   Copyright (C) 1996, 1997 the Free Software Foundation

   Authors: 1996, 1997 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */


#include <config.h>
#include "edit.h"

#ifndef MIDNIGHT
#include <X11/Xmd.h>		/* CARD32 */
#include <X11/Xatom.h>
#include "app_glob.c"
#include "coollocal.h"
#include "editcmddef.h"
#include "mousemark.h"
#endif


#ifndef MIDNIGHT

extern int EditExposeRedraw;
CWidget *wedit = 0;

void edit_destroy_callback (CWidget * w)
{
    if (w) {
	edit_clean (w->editor);
	if (w->editor)
	    free (w->editor);
	w->editor = NULL;
    } else
/* NLS ? */
	CError ("Trying to destroy non-existing editor widget.\n");
}

void link_hscrollbar_to_editor (CWidget * scrollbar, CWidget * editor, XEvent * xevent, CEvent * cwevent, int whichscrbutton);

extern int option_editor_bg_normal;
void edit_tri_cursor (Window win);
/* starting_directory is for the filebrowser */
CWidget *CDrawEditor (const char *identifier, Window parent, int x, int y,
	   int width, int height, const char *text, const char *filename,
		const char *starting_directory, unsigned int options, unsigned long text_size)
{
    static made_directory = 0;
    int extra_space_for_hscroll = 0;
    CWidget *w;
    WEdit *e;

    if (options & EDITOR_HORIZ_SCROLL)
	extra_space_for_hscroll = 8;

    wedit = w = CSetupWidget (identifier, parent, x, y,
			      width + 7, height + 6, C_EDITOR_WIDGET,
		   ExposureMask | ButtonPressMask | ButtonReleaseMask | \
		     KeyPressMask | KeyReleaseMask | ButtonMotionMask | \
			      PropertyChangeMask | StructureNotifyMask | \
			      EnterWindowMask | LeaveWindowMask, color_palette (option_editor_bg_normal), 1);
    edit_tri_cursor (w->winid);
    w->options = options | WIDGET_TAKES_SELECTION;

    w->destroy = edit_destroy_callback;
    if (filename)
	w->label = strdup (filename);
    else
	w->label = strdup ("");

    if (!made_directory) {
	mkdir (catstrs (home_dir, EDIT_DIR, 0), 0700);
	made_directory = 1;
    }
    e = w->editor = CMalloc (sizeof (WEdit));
    if (!w->editor) {
/* Not essential to translate */
	CError (_ ("Error initialising editor.\n"));
	return 0;
    }
    w->editor->widget = w;
    e = w->editor = edit_init (e, height / FONT_PIX_PER_LINE, width / FONT_MEAN_WIDTH, filename, text, starting_directory, text_size);
    if (!e) {
	CDestroyWidget (w->ident);
	return 0;
    }
    e->macro_i = -1;
    e->widget = w;

    set_hint_pos (x + width + 7 + WIDGET_SPACING, y + height + 6 + WIDGET_SPACING + extra_space_for_hscroll);
    if (extra_space_for_hscroll) {
	w->hori_scrollbar = CDrawHorizontalScrollbar (catstrs (identifier, ".hsc", 0), parent,
		x, y + height + 6, width + 6, 12, 0, 0);
	CSetScrollbarCallback (w->hori_scrollbar->ident, w->ident, link_hscrollbar_to_editor);
    }
    if (!(options & EDITOR_NO_TEXT))
	CDrawText (catstrs (identifier, ".text", 0), parent, x, y + height + 6 + WIDGET_SPACING + extra_space_for_hscroll, "%s", e->filename);
    if (!(options & EDITOR_NO_SCROLL)) {
	w->vert_scrollbar = CDrawVerticalScrollbar (catstrs (identifier, ".vsc", 0), parent,
		x + width + 7 + WIDGET_SPACING, y, height + 6, 20, 0, 0);
	CSetScrollbarCallback (w->vert_scrollbar->ident, w->ident, link_scrollbar_to_editor);
    }
    return w;
}

void update_scroll_bars (WEdit * e)
{
    int i, x1, x2;
    CWidget *scroll;
    scroll = e->widget->vert_scrollbar;
    if (scroll) {
	i = e->total_lines - e->start_line + 1;
	if (i > e->num_widget_lines)
	    i = e->num_widget_lines;
	if (e->total_lines) {
	    x1 = (double) 65535.0 *e->start_line / (e->total_lines + 1);
	    x2 = (double) 65535.0 *i / (e->total_lines + 1);
	} else {
	    x1 = 0;
	    x2 = 65535;
	}
	if (x1 != scroll->firstline || x2 != scroll->numlines) {
	    scroll->firstline = x1;
	    scroll->numlines = x2;
	    EditExposeRedraw = 1;
	    render_scrollbar (scroll);
	    EditExposeRedraw = 0;
	}
    }
    scroll = e->widget->hori_scrollbar;
    if (scroll) {
	i = e->max_column - (-e->start_col) + 1;
	if (i > e->num_widget_columns * FONT_MEAN_WIDTH)
	    i = e->num_widget_columns * FONT_MEAN_WIDTH;
	x1 = (double) 65535.0 *(-e->start_col) / (e->max_column + 1);
	x2 = (double) 65535.0 *i / (e->max_column + 1);
	if (x1 != scroll->firstline || x2 != scroll->numlines) {
	    scroll->firstline = x1;
	    scroll->numlines = x2;
	    EditExposeRedraw = 1;
	    render_scrollbar (scroll);
	    EditExposeRedraw = 0;
	}
    }
}

/* returns the position in the edit buffer of a window click */
long edit_get_click_pos (WEdit * edit, int x, int y)
{
    long click;
/* (1) goto to left margin */
    click = edit_bol (edit, edit->curs1);

/* (1) move up or down */
    if (y > (edit->curs_row + 1))
	click = edit_move_forward (edit, click, y - (edit->curs_row + 1), 0);
    if (y < (edit->curs_row + 1))
	click = edit_move_backward (edit, click, (edit->curs_row + 1) - y);

/* (3) move right to x pos */
    click = edit_move_forward3 (edit, click, x - edit->start_col - 1, 0);
    return click;
}

void edit_translate_xy (int xs, int ys, int *x, int *y)
{
    *x = xs - EDIT_TEXT_HORIZONTAL_OFFSET;
    *y = (ys - EDIT_TEXT_VERTICAL_OFFSET - option_text_line_spacing / 2 - 1) / FONT_PIX_PER_LINE + 1;
}

extern int just_dropped_something;

static void mouse_redraw (WEdit * edit, long click)
{
    edit->force |= REDRAW_PAGE | REDRAW_LINE;
    edit_update_curs_row (edit);
    edit_update_curs_col (edit);
    edit->prev_col = edit_get_col (edit);
    edit_update_screen (edit);
    edit->search_start = click;
}

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 (WEdit *edit, int x, int y)
{
    return edit_get_click_pos (edit, x, y);
}

/* return 1 if not marked */
static int marks (WEdit * edit, long *start, long *end)
{
    return eval_marks (edit, start, end);
}

int column_highlighting = 0;

static int erange (WEdit * edit, long start, long end, int click)
{
    if (column_highlighting) {
	int x;
	x = edit_move_forward3 (edit, edit_bol (edit, click), 0, click);
	if ((x >= edit->column1 && x < edit->column2)
	    || (x > edit->column2 && x <= edit->column1))
	    return (start <= click && click < end);
	else
	    return 0;
    }
    return (start <= click && click < end);
}

static void fin_mark (WEdit *edit)
{
    if (edit->mark2 < 0)
	edit_mark_cmd (edit, 0);
}

static void move_mark (WEdit *edit)
{
    edit_mark_cmd (edit, 1);
    edit_mark_cmd (edit, 0);
}

static void release_mark (WEdit *edit, XEvent *event)
{
    if (edit->mark2 < 0)
	edit_mark_cmd (edit, 0);
    else
	edit_mark_cmd (edit, 1);
    if (edit->mark1 != edit->mark2) {
	edit_get_selection (edit);
	XSetSelectionOwner (CDisplay, XA_PRIMARY, edit->widget->winid, event->xbutton.time);
    }
}

static char *get_block (WEdit * edit, long start_mark, long end_mark, int *type, int *l)
{
    char *t;
    t = (char *) edit_get_block (edit, start_mark, end_mark, l);
    if (strlen (t) < *l)
	*type = DndRawData;	/* if there are nulls in the data, send as raw */
    else
	*type = DndText;	/* else send as text */
    return t;
}

static void move (WEdit *edit, long click, int y)
{
    edit_cursor_move (edit, click - edit->curs1);
}

static void dclick (WEdit *edit, XEvent *event)
{
    edit_mark_cmd (edit, 1);
    edit_right_word_move (edit);
    edit_mark_cmd (edit, 0);
    edit_left_word_move (edit);
    release_mark (edit, event);
}

static void redraw (WEdit *edit, long click)
{
    mouse_redraw (edit, click);
}

static void edit_mouse_mark (WEdit * edit, XEvent * event, CEvent * ce)
{
    edit_update_curs_row (edit);
    edit_update_curs_col (edit);
    if (event->type != MotionNotify) {
	edit_push_action (edit, KEY_PRESS + edit->start_display);
	if (edit->mark2 == -1)
	    edit_push_action (edit, MARK_1 + edit->mark1);	/* mark1 must be following the cursor */
    }
    if (event->type == ButtonPress) {
	edit->highlight = 0;
	edit->found_len = 0;
    }
    mouse_mark (
	(void  *) edit,
	event,
	ce,
	(void (*) (int, int, int *, int *)) xy,
	(long (*) (void *, int, int)) cp,
	(int (*) (void *, long *, long *)) marks,
	(int (*) (void *, long, long, long)) erange,
	(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,
	0,
	(void (*) (void *, XEvent *)) dclick,
	(void (*) (void *, long)) redraw
    );
}

void link_scrollbar_to_editor (CWidget * scrollbar, CWidget * editor, XEvent * xevent, CEvent * cwevent, int whichscrbutton)
{
    int i, start_line;
    WEdit *e;
    e = editor->editor;
    if (!e)
	return;
    if (!e->widget->vert_scrollbar)
	return;
    start_line = e->start_line;
    if ((xevent->type == ButtonRelease || xevent->type == MotionNotify) && whichscrbutton == 3) {
	edit_move_display (e, (double) scrollbar->firstline * e->total_lines / 65535.0 + 1);
    } else if (xevent->type == ButtonPress && (cwevent->button == Button1 || cwevent->button == Button2)) {
	switch (whichscrbutton) {
	case 1:
	    edit_move_display (e, e->start_line - e->num_widget_lines + 1);
	    break;
	case 2:
	    edit_move_display (e, e->start_line - 1);
	    break;
	case 5:
	    edit_move_display (e, e->start_line + 1);
	    break;
	case 4:
	    edit_move_display (e, e->start_line + e->num_widget_lines - 1);
	    break;
	}
    }
    if (e->total_lines)
	scrollbar->firstline = (double) 65535.0 *e->start_line / (e->total_lines + 1);
    else
	scrollbar->firstline = 0;
    i = e->total_lines - e->start_line + 1;
    if (i > e->num_widget_lines)
	i = e->num_widget_lines;
    if (e->total_lines)
	scrollbar->numlines = (double) 65535.0 *i / (e->total_lines + 1);
    else
	scrollbar->numlines = 65535;
    if (start_line != e->start_line) {
	e->force |= REDRAW_PAGE | REDRAW_LINE;
	set_cursor_position (0, 0, 0, 0, 0, 0, 0, 0, 0);
	if (CCheckWindowEvent (xevent->xany.window, ButtonReleaseMask | ButtonMotionMask, 0))
	    return;
    }
    if (e->force) {
	edit_render_keypress (e);
	edit_status (e);

⌨️ 快捷键说明

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